Activity Diagrams
Branching, merging, swim-lanes. When the state machine isn't a single object's lifecycle but a multi-actor workflow.
Summary#
An activity diagram is the workflow picture: when does control branch, where do paths merge, what runs in parallel, and which actor owns which step. It is the right tool when the control flow itself is the story — when the interesting question is not “what message goes to whom” (a sequence diagram) but “what happens after this decision, and what happens after that one.” It is also the standard notation for the lifecycle of a stateful entity: an order, a ticket, a session, a subscription.
The notation reduces to a small set of shapes:
- Initial node — a filled black circle. The diagram starts here. Exactly one per diagram.
- Action — a rounded rectangle, labelled with a verb phrase. The unit of work.
- Decision node — a diamond with one incoming edge and two-or-more outgoing edges, each labelled with a guard in square brackets. Branching.
- Merge node — a diamond with multiple incoming edges and one outgoing edge. Where branches rejoin.
- Fork node — a thick horizontal or vertical bar splitting one flow into multiple parallel flows.
- Join node — the same bar, used to synchronise parallel flows back into one.
- Final node — a filled circle inside an outer circle (a bullseye). The flow terminates here. Multiple finals are allowed.
- Swim-lane — a vertical or horizontal partition labelled with an actor or system; each action inside a lane is performed by that actor.
That is enough to express any workflow you will be asked to draw in an LLD interview.
Why it matters#
Two situations in an LLD round demand an activity diagram, and a sequence diagram cannot replace it cleanly in either.
The first is a stateful entity with a non-trivial lifecycle. A Ticket moves through Issued → Paid → Closed, with a Lost side-branch. An Order moves through Cart → Submitted → Paid → Shipped → Delivered, with Cancelled reachable from several states. A Reservation moves through Held → Activated → Completed, with Expired as an alternative terminal. Each of these is a small state machine; the activity diagram is the conventional way to draw it. Putting state transitions on a class diagram is wrong (the class diagram is structural, not behavioural); trying to put them on a sequence diagram is awkward (sequence is for one flow, not for the entity’s whole life).
The second is a multi-actor workflow with branches. A loan application travels through a customer, an officer, an underwriter, and a notification service. A medical visit moves between the patient, the front desk, the nurse, the doctor, and the pharmacy. Each step happens in one lane, and the work crosses lanes at well-defined hand-offs. The swim-lane variant of the activity diagram is purpose-built for exactly this picture — the same picture is unreadable as a sequence diagram once it has more than two branches.
A third use, less common in interviews but worth naming: diagrams of an algorithm with concurrency. Fork/join with explicit synchronisation makes data parallelism visible. Rare in a 45-minute LLD round; common when the interviewer pushes into multithreading.
The diagram is also a useful bug-finder during the round. Drawing the activity diagram for a ticket lifecycle surfaces transitions you forgot to handle (what if a ticket is lost after it was paid?), terminal states that are not actually terminal (does a closed ticket allow re-entry?), and branches whose guards do not cover the input space. The interviewer often does not need to ask — your hand falters drawing the next arrow, and you have found the gap yourself.
How it works#
A canonical mini activity diagram for the parking lot ticket lifecycle:
+-------+ | start | <-- initial node (filled black circle) +---+---+ | v +-----------+ | Issued | +-----+-----+ | | driver returns to exit v +---------+ | ? | <-- decision: lost or not? +----+----+ | +------------+------------+ | [not lost] | [lost] v v +---------+ +---------+ | compute | | flag | | fare | | lost | +----+----+ +----+----+ | | v v +---------+ +-----------+ | Paid |<------------ | pay lost | +----+----+ | + fare | | +-----------+ v +-----------+ | release | | spot | +-----+-----+ | v +---------+ | Closed | +----+----+ | v (( )) <-- final node (bullseye)Reading the diagram:
- One initial node, one final node, three named states (
Issued,Paid,Closed) plus one side-state (Lost). - The decision diamond after
Issuedhas two guarded edges:[not lost]and[lost]. Every guard the diagram needs is explicit. - The
Lostbranch rejoins the main flow atPaid— once the lost-ticket fee is settled, the ticket is paid and continues normally. Closedis the only state that flows into the final node; re-entry produces a new ticket, not a re-opening of this one.
Swim-lanes#
When the workflow spans actors, vertical partitions clarify who owns each action. A canonical mini-diagram for a loan application:
+---------------+----------------+----------------+----------------+ | Customer | Officer | Underwriter | Notifications | +---------------+----------------+----------------+----------------+ | | | | | | (start) | | | | | | | | | | | v | | | | | submit app | | | | | | | | | | | +-------> | review app | | | | | | | | | | | v | | | | | decision | | | | | | | | | | | [accept] | | | | | +--------> | underwrite | | | | | | | | | | | v | | | | | decision | | | | | | | | | | | [approved] | | | | | +--------> | send approval | | | | | | | | | [reject] | | | | | +------------------------------------>send rejection | | | | | | | | | | v | | | | | (end) | +---------------+----------------+----------------+----------------+Each step happens in exactly one lane. The lane the arrow leaves and the lane it enters are a hand-off between actors. Swim-lanes make ownership unambiguous, which is the whole point.
Fork and join#
When parallel work is the story, the fork bar splits one flow into two; the join bar synchronises them back. The classic interview use: order fulfilment.
| v +-----------------+ | order submitted | +--------+--------+ | ===========+=========== <-- fork (thick bar) | | v v +----------+ +----------+ | charge | | reserve | | payment | | stock | +-----+----+ +-----+----+ | | ===============+====== <-- join (thick bar) | v +---------------+ | ship the box | +-------+-------+ | v (( ))The join waits for both parallel branches to complete before the shipment proceeds. If either branch fails, the failure surfaces at the join (in the simplest model, throw an error and roll back; in a richer model, compensate).
Object flow#
Activity diagrams also support object nodes — small rectangles attached to an edge, naming the artefact passed from one action to the next. Useful when the flow is fundamentally about data moving (a draft becoming a published document, a request becoming a response). In interviews, object flow is usually overkill; verbal narration suffices.
Variants and trade-offs#
A few recurring choices when drawing one of these in the room.
Activity diagram vs sequence diagram. A useful test: count the diamonds you would need to draw in a sequence diagram (alt fragments). One is fine. Two is borderline. Three or more is a sign the activity diagram is the right artefact and you are forcing it into the wrong notation.
Sequence diagram. Best when the flow is mostly linear, message-passing between specific objects, and there is one happy path with maybe one alternative. The story is who talks to whom.
Activity diagram. Best when the flow has multiple branches, parallel paths, or a multi-actor handoff. The story is what happens next, conditionally. Use swim-lanes when the actor split matters; skip them when it does not.
Activity diagram vs state machine diagram. UML has a separate state machine notation (rectangles with rounded corners, transitions labelled with trigger [guard] / effect, internal regions, history pseudostates). For a 45-minute interview, the activity-diagram subset is almost always sufficient; reach for the dedicated state machine only if the interviewer names it explicitly or the problem demands hierarchical states. The state-machine notation is more precise; the activity-diagram subset is more familiar.
How many actions before splitting the diagram. A readable activity diagram has 6–12 actions and 1–3 decision diamonds. Beyond that, factor the workflow into sub-activities (drawn as named rectangles with a fork-style indicator in the corner) and a higher-level diagram that composes them.
Whether to label transitions. Always label decision-outgoing edges with their guard ([condition]). Labelling unconditional transitions is usually unnecessary unless the action itself is too terse to convey what is happening. Self-explanatory action names beat verbose transition labels.
When this is asked in interviews#
The activity diagram is the least-commonly demanded of the four canonical diagrams in a 45-minute round — most problems can complete without one. The two clear cases where it pays.
Stateful lifecycle questions. “Walk me through the states a ticket goes through.” That sentence is a direct request for an activity (or state machine) diagram. Drawing the lifecycle explicitly, with every legal transition and at least one illegal one called out, signals you have thought about the entity as a state machine and not just as a class with a few mutators. The Parking Lot ticket — Issued → (Lost?) → Paid → Closed — is the textbook example.
Multi-actor workflows. “Design the loan-application flow” or “design the doctor-visit flow” are problems where the swim-lane variant earns its keep. Each hand-off between actors is a coordination point; each decision diamond is a place where the system can fail or branch. Putting them on the diagram makes the discussion concrete.
Three patterns interviewers reward.
Name every state, even the unhappy ones. A ticket lifecycle that names only Issued → Paid → Closed is missing Lost; a reservation lifecycle that names only Held → Activated → Completed is missing Expired. Drawing the unhappy states alongside the happy ones shows you have considered failure modes.
Mark the terminal states. Each terminal state ends in a final-node bullseye. If the diagram has two terminals (Closed and Cancelled for an order), draw both. Interviewers often probe “what happens after Closed?” — the answer is “nothing; it is terminal,” and the diagram should say so.
Resist drawing too many parallel branches. Fork/join is powerful and overused. If you draw a fork, the join must be there too, and the interviewer will ask what happens when one branch fails before the other completes. Have an answer ready (compensate, roll back, mark the whole flow failed) before drawing the fork.
Common follow-ups the diagram makes easy to answer: “What if the customer cancels mid-flow?” (Add an edge from the relevant state to Cancelled.) “What if both branches of the fork succeed but at different times?” (The join waits for the slower.) “What if an action throws?” (Add an exception edge to a recovery action or to a terminal failure state.)
Related concepts#
- OOAD and UML — Overview — the four-diagram canon.
- Class Diagrams — where the stateful entity lives whose lifecycle this diagram is drawing.
- Sequence Diagrams — the message-passing counterpart, for a single flow.
- Use Case Diagrams — the scope artefact whose use cases sometimes need an activity diagram each.
- Parking Lot — a real activity diagram for the ticket lifecycle in this codebase.
- Approaching the OOD Interview — when in the round to reach for this diagram.