State machine diagram
What stable configurations can this object be in, and what triggers moves between them? Rounded boxes are states, arrows are transitions labeled with the event that causes them. Unlike the activity diagram, there is no implied "and then it's done" - a state machine can sit in one state indefinitely until an event arrives, which is exactly what makes it the right notation for objects whose legal next moves depend on where they currently are.
States, transitions, and the initial pseudostate
A state is a stable condition the object can sit in - drawn as a rounded rectangle. A transition is an arrow from one state to another, labeled with the event that triggers it. The initial pseudostate - a solid filled circle with an arrow into the first real state - marks where a new object of this type starts out; it is not itself a state an object can remain in.
Click a state below to see exactly which transitions lead out of it - this is the same login flow from every other page in this module, now drawn as its states instead of its classes or its message order.
Guards and actions: the full transition syntax
A transition label can carry up to three parts, always in this order:
event- what triggers the transition.submit,timeout,logout.[guard]- an optional boolean condition. The transition only fires if the event occurs and the guard holds; if the guard is false, the event is effectively ignored from this state./ action- an optional side effect that runs as part of the transition itself, after the guard passes and before the object lands in its new state.
login alone (no guard, no action) is a perfectly valid transition label - the fuller
syntax exists for the moments it earns its keep, not as a requirement on every arrow.
Entry and exit actions
A state box can list actions that run automatically on the way in or the way out, regardless of which transition caused the move:
An entry action fires exactly once every time the machine enters the state, no matter which transition led there. An exit action fires exactly once on the way out, no matter which transition is leaving. This is the state-machine equivalent of a constructor and a destructor scoped to "however long the object spends in this one state" - useful for setup/teardown work that has nothing to do with which specific event triggered the move.
Self-transitions
A self-transition is an arrow that loops from a state back to itself. The object never leaves the state - but the transition's action still runs, and so do the state's exit and entry actions, since a self-transition is still, formally, an exit followed by a re-entry.
This is the right tool for "handle this event, run some side effect, but do not actually change which state the object reports" - a heartbeat ping that resets an idle timer without ending the session.
Final pseudostate
A final pseudostate - a solid circle inside a ring, the same mark used on activity
diagrams - marks a state from which no further transitions are possible; the object's
life cycle, as far as this diagram is concerned, is over. Not every state machine needs
one: plenty of objects (a TrafficLight, an AuthSession) cycle indefinitely with no
terminal state at all.
Composite (nested) states
A composite state contains its own inner state machine - useful when one logical state actually has sub-phases worth naming, without exploding the outer diagram with every combination. An event the inner states do not handle can still be caught by a transition declared on the composite state itself, which acts as a fallback for the whole group.
The login flow, and a second example: OrderStatus
The three-state login example at the top of this page is deliberately small. A second,
unrelated example is worth seeing to confirm the notation generalizes: the OrderStatus
enum from Enums is a state machine that was hiding in plain sight -
five named values, but only some of the moves between them are actually legal.
The enum told you the five values that exist. The state machine tells you the rule the
enum alone could never enforce: you cannot go from SHIPPED back to PENDING, and once
you hit DELIVERED or CANCELLED, that order is done changing - both are terminal, with
no outgoing transitions at all.
This is the diagram the State pattern implements directly - one class per bubble,
one transition() per arrow. If you catch yourself drawing a state machine for a class,
that class is a strong State-pattern candidate.
When to reach for it: the moment an object's legal transitions matter more than any single path through them - an order, a traffic light, a TCP connection. When not to bother: an object with no real states, or one where every transition is legal from everywhere - a state machine with one bubble and an arrow back to itself is not modelling anything.
Common mistakes
- Confusing this with an activity diagram. An activity diagram answers "what happens, in order, including branches" and implies a process that finishes. A state machine answers "what stable configuration is the object in, and what triggers a move out of it" and can sit in one state indefinitely with no implied ending.
- Drawing a transition with no triggering event.
Submitting -> Authenticatedwith no label reads as "this just happens," which is rarely true - name the event, even if it is something plain likesuccess. - Skipping guards and letting one event fan out to multiple states with no way to
tell which one fires. If
submitcan lead to eitherAuthenticatedorLocked, something distinguishes those two outcomes - write it as the guard, don't leave it implicit. - Modelling a field that isn't really a state machine. A boolean flag that can flip freely in either direction at any time, with no meaningful sequence of transitions, is just a field - forcing it into states and transitions adds ceremony without adding information.
Try it yourself: sketch a state machine for a TrafficLight with RED, YELLOW and
GREEN. Which transitions are self-transitions, if any? Does it need a final
pseudostate, or does it cycle forever? Where would an entry action (startTimer()) earn
its place?
Check yourself
A transition is labeled `login [attempts < 3] / resetTimer()`. What do the three parts mean, in order?