When you model real software behavior, not everything follows a straight line. Users log in or they don't. Payments succeed or they fail. A server responds or times out. If your sequence diagrams only show the happy path, they're incomplete. PlantUML sequence diagram code examples with conditional logic let you capture branching behavior the "if this, then that" decisions so your diagrams actually reflect how a system works. This is especially useful for documenting APIs, user flows, error handling, and microservice interactions where outcomes vary based on runtime conditions.
What does conditional logic mean in a PlantUML sequence diagram?
Conditional logic in a sequence diagram refers to blocks that show different interactions depending on a condition. PlantUML supports this through combined fragments, which come from the UML specification. The most common ones are:
- alt Alternative paths (like if/else). Exactly one branch executes.
- opt Optional path. The block runs only if a condition is true.
- break Breaks out of the interaction if a condition is met.
- loop Repeats a set of interactions while or until a condition holds.
These combined fragments use rectangular boxes with a label in the top-left corner. Each branch inside an alt block is separated by a dashed line. You can learn more about UML notation in our guide on UML state machine diagram notation and symbols, which covers how different UML diagrams handle state transitions and decisions.
How do you write an alt/else condition in PlantUML?
The alt keyword creates an if/else branch. Here's a basic example showing a login flow where authentication either succeeds or fails:
@startuml
actor User
participant "Auth Service" as Auth
participant Database
User -> Auth: Login request
alt credentials are valid
Auth -> Database: Query user
Database --> Auth: User found
Auth --> User: 200 OK + token
else credentials are invalid
Auth --> User: 401 Unauthorized
end
@enduml
The syntax is straightforward: write alt [condition label], describe the messages in that branch, then use else [another label] for the alternative path. Close it with end. You can have more than two branches just add more else blocks.
How do you show optional behavior with the opt keyword?
Sometimes a step only happens under certain conditions. There's no "else" it either happens or it doesn't. That's what opt is for:
@startuml
actor User
participant "API Gateway" as GW
participant "Cache" as Cache
participant "Product Service" as PS
User -> GW: GET /products/42
opt cache hit
GW -> Cache: Check for product 42
Cache --> GW: Return cached data
GW --> User: 200 OK (cached)
end
alt cache miss
GW -> PS: Fetch product 42
PS --> GW: Product data
GW --> User: 200 OK (fresh)
end
@enduml
This shows that the cache lookup only happens when there's a cache hit. If there's a miss, the flow falls through to the alt block. Combining opt and alt gives you fine-grained control over conditional paths.
Can you nest conditions inside other conditions?
Yes, and it's more common than you'd think in real systems. Consider an e-commerce checkout where payment processing has its own branching logic inside a larger order flow:
@startuml
actor Customer
participant "Order Service" as Order
participant "Payment Gateway" as Pay
participant "Inventory" as Inv
Customer -> Order: Place order
alt order is valid
Order -> Inv: Check stock
alt items in stock
Inv --> Order: Stock confirmed
Order -> Pay: Charge payment
alt payment succeeds
Pay --> Order: Payment confirmed
Order --> Customer: Order placed (ID #1234)
else payment fails
Pay --> Order: Payment error
Order --> Customer: 402 Payment failed
end
else out of stock
Inv --> Order: Insufficient stock
Order --> Customer: 409 Out of stock
end
else order is invalid
Order --> Customer: 400 Bad request
end
@enduml
Nested alt blocks let you model complex decision trees. Just be careful deeply nested fragments can become hard to read. If your diagram goes beyond three levels of nesting, it might be time to split it into separate diagrams or consider using a UML activity diagram for microservices architecture instead, since activity diagrams handle complex branching more naturally.
How do you loop through conditions in a sequence diagram?
The loop fragment repeats a set of messages while or until a condition is true. This is useful for retry logic, polling, or batch processing:
@startuml
participant "Client" as C
participant "Payment Service" as PS
C -> PS: Submit payment
loop retry up to 3 times
PS -> PS: Process payment
alt payment processed
PS --> C: 200 OK
else transient error
PS --> C: 503 Retry
C -> PS: Retry payment
end
end
@enduml
You can also combine loop with a break condition. If the payment succeeds on the first try, the loop ends early:
@startuml
participant "Client" as C
participant "Payment Service" as PS
C -> PS: Submit payment
loop retry up to 3 times
PS -> PS: Attempt processing
break success
PS --> C: 200 OK
end
end
@enduml
What's the difference between alt, opt, break, and loop?
These four combined fragments serve distinct purposes. Here's a quick comparison:
| Fragment | Behavior | UML Equivalent |
|---|---|---|
| alt | Multiple branches, one executes | if / else if / else |
| opt | Single optional block | if (no else) |
| break | Exits the enclosing interaction fragment | break statement |
| loop | Repeats while/until a condition | while / for loop |
There's also critical for regions that must complete without interruption, and par for parallel execution. But in most sequence diagrams, alt, opt, and loop cover the majority of conditional scenarios.
What mistakes do people make with conditional PlantUML code?
Here are the most common issues we've seen:
- Forgetting the
endkeyword. Every alt, opt, loop, and break block must close withend. Missing it causes parse errors or garbled output. - Using alt when opt is more appropriate. If there's no "else" path, use
optinstead. It makes the diagram cleaner and easier to understand. - Overcomplicating with too much nesting. Three or more levels of nested conditions become hard to follow. Consider splitting the diagram or using separate diagrams for different scenarios.
- Vague condition labels. Writing just
alt successvs.alt user has sufficient balancemakes a big difference for readers. Be specific. - Mixing sequence diagram logic with state transitions. If your conditions represent state changes rather than message-based decisions, a state machine diagram might be a better fit. Check our reference on state machine diagram notation and symbols to decide when to use which.
Any tips for writing cleaner conditional sequence diagrams?
- Name your conditions like acceptance criteria. Instead of
alt OK, writealt user is authenticated and has admin role. - Use grouping notes to add context. PlantUML supports
noteblocks inside combined fragments to explain why a condition exists. - Keep message arrows aligned. Only the messages relevant to a branch should appear inside the fragment. Don't put unrelated interactions in there.
- Use participant aliases. Long service names clutter the diagram. Alias them at the top:
participant "Authentication Service" as Auth. - Color-code blocks for readability. PlantUML supports
#coloron combined fragments:alt #LightGreen successandelse #LightCoral failure. - Test with small examples first. Build your conditional logic incrementally. Add one alt block, verify the output, then add the next layer.
When should you use a different UML diagram instead?
Sequence diagrams with conditional logic work well for showing how components communicate under different conditions. But they're not always the best choice:
- If you're modeling object states and transitions, use a state machine diagram.
- If you're modeling a business process with many branches and parallel paths, use an activity diagram.
- If you're documenting data structures, use a class diagram.
The key question is: are you showing who talks to whom and when, or are you showing how a process flows? For the former, sequence diagrams with conditional fragments are the right tool. For the latter, activity diagrams handle complexity better, particularly in distributed systems and microservices where parallel and conditional paths intertwine.
Practical checklist before you share your conditional sequence diagram
- Every
alt,opt,loop, andbreakblock has a matchingend - Condition labels are specific and readable by non-developers
- Nesting depth does not exceed three levels
- The diagram covers at least the main success path and the most common error path
- Participant aliases keep the diagram readable
- You've verified the rendered output matches your intent (PlantUML's online server is useful for quick checks at plantuml.com)
- You've considered whether the conditional logic might be better expressed in a different UML diagram type
Uml Class Diagram Syntax Reference Guide for Software Engineers
Uml State Machine Diagram Notation and Symbols Explained
Mermaid Uml Component Diagram Syntax Guide
Uml Activity Diagram Syntax for Microservices Architecture
How to Write Flowchart Code From Scratch: a Complete Beginner's Tutorial
Mermaid Flowchart Syntax Examples for Github Repositories