Common patterns

Parallel work

Run steps at the same time with a parallel split and join, or take only the paths that apply.

Run steps in parallel

A parallel gateway (and) starts every path at once, and a second one waits for all of them. Its arrows need no labels. Write each branch as its own block: one branch declares the join and carries on from it, and the others point to it.

Flowmark
process New hire onboarding
lanes HR | IT

lane HR
start Offer accepted
user Prepare contract
and #split
  -> Set up laptop
  -> Create accounts
  -> Plan first week

lane IT
manual Set up laptop
and #ready
lane HR
user Welcome new hire
end New hire started

lane IT
service Create accounts
  -> #ready

lane HR
user Plan first week
  -> #ready

Join parallel paths with and, never xor. The checks warn when an exclusive gateway merges parallel paths, and report a deadlock when a parallel gateway joins the paths of an exclusive decision, because it would wait for paths that were never taken. They also warn when the branches of a parallel split never meet again.

A decision inside parallel work

A decision on one parallel path, such as a fraud screening beside the vehicle inspection, merges its own branches with an xor first. Only that one flow goes to the and join, because the join waits for every flow into it and only one of the decision's branches is ever taken.

Flowmark
process Motor claim
lanes Claims handler | Adjuster

lane Claims handler
start Claim received
and #fork
  -> Inspect vehicle
  -> Screen for fraud

lane Adjuster
manual Inspect vehicle
and #join
lane Claims handler
user Decide on claim
end Claim decided

lane Claims handler
service Screen for fraud
xor Fraud suspected?
  yes -> Investigate claim
  no (default) -> #screened

user Investigate claim
xor #screened
  -> #join

If a branch has to stop all the work, such as a claim closed as fraudulent while the inspection still runs, end it with end:terminate instead of leading it to the join.

Take one or more paths

An inclusive gateway (or) takes every path whose condition holds. Give each flow a condition, add a (default) for when none hold, and join with another or:

Flowmark
process Insurance claim

start Claim received
user Assess claim
or Which checks are needed?
  fraud risk [fraudScore > 70] -> Run fraud check
  vehicle damage [type == "vehicle"] -> Inspect vehicle
  standard (default) -> Verify policy

service Run fraud check
or #checked
user Decide on claim
end Claim decided

manual Inspect vehicle
  -> #checked

service Verify policy
  -> #checked

What to notice

  • The split and the join use the same kind of gateway: and with and, or with or.
  • The join has only an id, and every branch but one points to it.
  • A decision inside a branch is merged before the join, so each branch brings exactly one flow to it.
  • A rework loop that starts after the join comes back to a merge after it. Looping back into one branch would leave the join waiting for the others.
  • Each branch is its own block, separated by a blank line.

On this page