The elements · 04 · 9 min
Gateways
Diamonds route tokens. They never perform work, never consume time, and never make a decision themselves.
If the gateway is not asking the question, something upstream must have answered it. The three types differ in what they do with that answer.
| Gateway | Split behaviour | Join behaviour |
|---|---|---|
| Exclusive (XOR) | Takes exactly one outgoing flow: the first whose condition is true. | Does not wait. |
| Parallel (AND) | Takes all outgoing flows. One token in, N tokens out. | Waits for all incoming flows. |
| Inclusive (OR) | Takes every flow whose condition is true, one, several, or all. | Waits for every token that can still arrive. The hardest to reason about. |
| Event-based | Does not evaluate data. Routes to whichever event happens first. | Rarely used as a join. |
| Complex | Custom conditions ("any 3 of 5 approvals"). Rare, usually a sign the model should be restructured. | , |
The default flow covers the else case
An exclusive gateway whose conditions are all false has nowhere to send the token. A default flow, marked with a backslash, is taken when nothing else matches.
After "Check invoice", the gateway "Invoice correct?" routes yes to "Schedule payment"; the default flow ("otherwise") catches every other case.
Event-based gateway: the race
This is the one people under-use. It models “whichever comes first”: a reply, or a timeout. The token waits at the gateway; whichever event fires first wins and the other path is discarded.
After "Send invoice", an event-based gateway waits: "Payment received" leads to "Close case", "14 days" to "Send reminder". Whichever comes first wins.
This is how you model “escalate after 14 days” without inventing a polling loop.
After this module you can
- Choose between exclusive, parallel, inclusive and event-based gateways
- Explain why a parallel join waits and an exclusive join does not
- Use a default flow to cover the else case