Activity diagram
What happens, step by step, including every branch? A flowchart, formalized: rounded start and end markers, rectangles for actions, diamonds for decisions, and (once the process needs it) bars for genuine parallelism. No participants, no lifelines, no messages between objects - just the process itself, told as a sequence of steps.
Initial and final nodes
Every activity diagram starts at exactly one initial node - a small filled circle - and ends at one or more activity final nodes - a circle with a ring around it. Between them sit the actions and decisions that make up the process.
Actions, decisions, and merges
An action is a rounded rectangle - one step of work, named as a verb phrase. A
decision node is a diamond with one path in and several paths out, each labeled with
a [guard]; exactly one guard is true on any given run, so exactly one outgoing path
fires. A merge node is a decision node's mirror image: several paths in, one path
out, reuniting branches that a decision node split earlier.
Nothing in the notation distinguishes a decision diamond from a merge diamond visually - the difference is entirely in how many arrows go in versus out.
Fork and join bars
A fork is a thick black bar with one incoming path and several outgoing ones that all start concurrently - unlike a decision node, there is no guard choosing between them, every branch fires. A join is the mirror bar: several concurrent paths in, and the flow does not continue past it until all of them have finished.
Guards on transitions
A guard is a bracketed boolean condition written next to an arrow, restricting when
that arrow may be followed - [amount > 100], [credentials valid]. Guards are what
make a decision node's branches mutually exclusive rather than ambiguous: every path out
of a decision node needs its own guard, and the set of guards should cover every case the
diamond can actually produce.
Swimlanes (partitions)
A swimlane (or partition) divides the diagram into vertical or horizontal bands, one per actor or component, and places every action inside whichever lane is responsible for it. The flow logic - decisions, forks, guards - works exactly the same; a swimlane only adds "who does this step" on top of "what happens next."
The login flow, built up in stages
Stage 1 - the straight path with one decision. Enter credentials, check them, branch.
Stage 2 - merge the branches, add fork/join for the side-effects. A successful login fires two independent, concurrent actions - send a "new login" notification and write an audit log entry - and both must finish before the response goes back.
When to reach for it: a business process or workflow with real branching - an
approval chain, an order pipeline with a refund path, anything with more than one
decision diamond worth drawing. When not to bother: a single method's control flow.
if (x) return a; else return b; is not worth a flowchart - that is what the code itself
is for.
Common mistakes
- Using a fork where a decision was meant. A fork runs every outgoing branch; a decision runs exactly one. Drawing a fork for "either do A or do B" describes both happening at once, which is very rarely what was intended.
- Missing guards on a decision's branches, or guards that overlap. Every path out of
a diamond needs its own
[condition], and the conditions should be mutually exclusive and exhaustive - otherwise the diagram is silent (or ambiguous) about what happens in the gap. - Forgetting the join. A fork with no matching join implies the concurrent branches never need to be waited on, which is rarely true - if the flow continues past both, draw the join bar to say so explicitly.
- Cramming everything into one swimlane. If every action lives in the same lane, the swimlanes are not adding information - only introduce them once responsibility for steps genuinely crosses actor or component boundaries.
Try it yourself: sketch an activity diagram for placing a food-delivery order with
two swimlanes, Customer and Restaurant. Where does a decision diamond belong (is the
restaurant currently accepting orders)? Where would a fork/join pair make sense (charging
the card and reserving inventory at the same time)?
Check yourself
A flowchart has a filled black circle at the top and a ringed (bullseye) circle at the bottom. What do these mark?