Process and Ops Diagrams
0. What these have in common
The diagrams in notebooks 02 to 05 describe a system. These three describe work and time: when things happen, who owns them, and how long they take.
| Diagram | Time scale | The question it owns |
|---|---|---|
| Gantt / dependency chart | Weeks to months | “What blocks what, and when does this land?” |
| Swimlane | Hours to days | “Whose job is this step, and where does it get stuck?” |
| Timing diagram | Microseconds to seconds | “What is the signal actually doing, and does it meet timing?” |
Still the same running example: MeterHub, a service that ingests smart-meter readings over MQTT and bills customers monthly.
1. Gantt and dependency charts
What it is: tasks as horizontal bars on a calendar, with dependencies between them and milestones as points.
When it earns its keep: when the interesting fact is a dependency, not a date. “Meter commissioning cannot start until the certificate authority exists” is worth a chart. A list of tasks with dates is a spreadsheet, and Gantt charts drawn as decorated spreadsheets are why the format has the reputation it has.
What makes it honest: the critical path is visible, milestones are events rather than tasks, and dates that are guesses are marked as guesses.
gantt
title MeterHub release 1
dateFormat YYYY-MM-DD
axisFormat %d %b
excludes weekends
section Platform
Provision LXC and network :done, inf1, 2026-08-03, 4d
Certificate authority for meters :done, inf2, after inf1, 3d
TimescaleDB and retention policy :active, inf3, after inf1, 6d
section Ingest
MQTT broker with client certs :active, ing1, after inf2, 5d
Validation and dedupe : ing2, after ing1, 8d
Load test to 10k per second :crit, ing3, after ing2, 4d
section Billing
Tariff engine, flat rate : bil1, after inf3, 6d
Tariff engine, time of use : bil2, after bil1, 7d
Invoice PDF and email : bil3, after bil2, 5d
section Customer facing
Usage charts : web1, after inf3, 8d
Payment flow with gateway :crit, web2, after bil3, 9d
section Gates
Meters in the field :milestone, m1, after ing3, 0d
First live bill issued :milestone, m2, after web2, 0d
Read the chart for its shape rather than its dates. Everything downstream of inf3 (the database) is blocked by one task, so slipping it slips billing and the customer app together. And the two crit tasks, load testing and the payment flow, are the ones with external dependencies (a load rig, a gateway’s sandbox), which is exactly where estimates fail.
Task syntax
Task name :tag, id, start, duration where the tags are done, active, crit, milestone, and the start can be a date or after <id>. excludes weekends keeps the arithmetic believable, and section groups rows.
When the dependency matters more than the calendar
Drop the dates and draw the network. This is a PERT-style dependency chart, and the numbers on the nodes are durations:
flowchart LR
A["Provision infra<br/>4d"] --> B["Cert authority<br/>3d"]
A --> C["TimescaleDB<br/>6d"]
B --> D["Broker + certs<br/>5d"]
D --> E["Validate + dedupe<br/>8d"]
E --> F["Load test<br/>4d"]
C --> G["Tariff flat<br/>6d"]
G --> H["Tariff ToU<br/>7d"]
H --> I["Invoice PDF<br/>5d"]
I --> J["Payment flow<br/>9d"]
C --> K["Usage charts<br/>8d"]
F --> M1(["Meters in field"])
J --> M2(["First live bill"])
linkStyle 1,5,6,7,8,11 stroke:#e53e3e,stroke-width:3px
The red edges are the critical path: infra, database, flat tariff, time of use, PDF, payment, at 37 days. Nothing on the ingest branch can delay the launch until it exceeds that, which tells you where a second pair of hands is worth having and where it is not.
A Gantt chart is a plan, and plans are wrong. Regenerate it from the tracker rather than maintaining it by hand, or accept that it is a snapshot with a date on it. The failure mode is a beautiful chart that nobody has updated in six weeks and everybody still quotes.
2. Swimlane diagram
What it is: a flowchart split into lanes, one per role, team or system. The steps are the same as any activity diagram. The lanes add the one fact that matters most in a cross-team process: who owns this step.
When it earns its keep: any process where the handoffs are the problem, which is most of them. Incident response, onboarding, procurement, refunds, deployment approvals. The lanes make queueing visible, and queueing between teams is where days disappear.
What to look for once it is drawn: every arrow that crosses a lane boundary is a handoff, and every handoff is a wait state. Count them. A process with nine lane crossings is not slow because people are slow.
flowchart TB
subgraph CUST["Customer"]
C1["Reports a suspicious bill"]
C2["Confirms the correction"]
end
subgraph SUP["Support"]
S1["Triage ticket,<br/>check usage chart"]
S2{"Explainable<br/>from the data?"}
S3["Reply with explanation"]
S4["Escalate to metering,<br/>attach NMI and period"]
S5["Notify customer of outcome"]
end
subgraph MET["Metering ops"]
M1["Pull raw interval data"]
M2{"Gap, estimate<br/>or genuine spike?"}
M3["Request field visit"]
M4["Issue correction:<br/>new rows, reason code"]
end
subgraph FIELD["Field technician"]
F1["Site visit,<br/>verify meter and wiring"]
F2["Replace or recommission"]
end
subgraph SYS["MeterHub"]
Y1["Reprice the period"]
Y2["Issue adjustment invoice"]
end
C1 --> S1
S1 --> S2
S2 -->|yes| S3
S3 --> C2
S2 -->|no| S4
S4 --> M1
M1 --> M2
M2 -->|"genuine spike"| S3
M2 -->|"gap or estimate"| M4
M2 -->|"hardware suspect"| M3
M3 --> F1
F1 --> F2
F2 --> M4
M4 --> Y1
Y1 --> Y2
Y2 --> S5
S5 --> C2
classDef wait fill:#744210,stroke:#f6e05e,color:#fff
class S4,M3,F1 wait
Six lane crossings on the unhappy path, and the three highlighted steps are the queues: escalation to metering, requesting a field visit, and the visit itself. The field visit is measured in days while everything else is measured in minutes, so the only optimisation that matters is not needing the visit, which means better remote diagnostics on the meter. Reading that off the diagram takes ten seconds. Arguing about it without a diagram takes a meeting.
Mermaid has no true swimlane primitive. Subgraphs plus flowchart TB get you horizontal lanes, and flowchart LR gets you vertical ones, but the layout engine will not keep lanes tidy in complicated processes. For a large process, BPMN (drawn in bpmn.io or Camunda Modeler) is the notation designed for exactly this, with real pools, lanes, gateways and events.
3. Timing diagram
What it is: signal or state values plotted against time, with the transitions and the intervals between them marked. The hardware side of the house, and the one diagram in this folder where the units are microseconds.
When it earns its keep: bus protocols (SPI, I2C, UART), interrupt latency, sleep and wake budgets on battery devices, and any datasheet requirement of the form “CS must be low at least 20 ns before the first clock edge”. Also useful one level up for anything with a strict deadline: an audio buffer, a control loop, a watchdog.
Mermaid does not do timing diagrams. Two tools do it properly.
WaveDrom, for signal level
WaveDrom takes JSON and renders the classic waveform picture. This is one SPI transaction from the meter’s MCU to its energy-measurement chip:
{ "signal": [
{ "name": "CS", "wave": "10.........1" },
{ "name": "SCLK", "wave": "0.p........0" },
{ "name": "MOSI", "wave": "x.2222x.....", "data": ["A7", "A6", "A5", "A4"] },
{ "name": "MISO", "wave": "x......3333x", "data": ["D7", "D6", "D5", "D4"] },
{ "name": "IRQ", "wave": "1.........0." }
],
"config": { "hscale": 1 }
}wave characters: 0 and 1 are levels, . extends the previous value, p and n are clocks, x is don’t-care, and digits are data buses whose labels come from data. The whole notation is learnable in about ten minutes and it is what most datasheets and RFCs use.
PlantUML, for state level
When the interesting thing is which state something is in rather than the voltage on a pin, PlantUML’s timing syntax is easier to read:
@startuml
robust "Meter MCU" as MCU
concise "MQTT session" as NET
scale 1 as 60 pixels
@0
MCU is DeepSleep
NET is Disconnected
@300
MCU is Sampling
NET is Disconnected
@360
MCU is Connecting
NET is Handshake
@900
MCU is Publishing
NET is Connected
@1000
MCU is DeepSleep
NET is Disconnected
@300 <-> @900 : 600 ms of radio, the entire power budget
@enduml
The annotation at the bottom is the point of the diagram. Sampling costs almost nothing, and the TLS handshake plus publish dominates the wake window, so a battery meter should batch readings and publish once an hour rather than reconnect every five minutes. That conclusion is a power measurement made visible, and it changes the firmware design.
For anything with a deadline, put the budget on the diagram next to the measurement. “600 ms” is data. “600 ms of a 900 ms wake budget” is a decision.
4. Three more Mermaid diagrams worth knowing
Not in the original taxonomy, cheap to draw, and they come up constantly in ops work.
gitGraph, for branching strategy
Explaining a branching model in prose never works. Six lines of gitGraph does:
gitGraph
commit id: "v1.2.0"
branch release/1.3
checkout main
commit id: "feat: tou tariffs"
commit id: "fix: dedupe ttl"
checkout release/1.3
cherry-pick id: "fix: dedupe ttl"
commit id: "v1.3.0" tag: "v1.3.0"
checkout main
merge release/1.3
commit id: "feat: adjustment invoices"
timeline, for retrospectives and incident reviews
timeline
title Incident 2026-07-14, billing run produced zero invoices
02.00 : Nightly billing timer fires
: Advisory lock acquired
02.01 : Query returns zero sites due
: Run exits 0, no alert fires
08.40 : Support notices no bills sent
09.15 : Timezone bug found
: period_end compared in UTC, not Brisbane
10.30 : Fix deployed, run replayed
11.00 : Alert added on invoices issued equals zero
The lesson is legible in the gaps: the failure happened at 02.01 and was noticed at 08.40, so the finding is not the timezone bug. It is that a successful-looking run with zero output raised nothing. (Times are written with a dot because timeline uses the colon as its field separator: a row written 02:01 : Query returns zero sites due is a parse error, not a clock time.)
quadrantChart, for prioritisation
quadrantChart
title Diagram effort against payoff
x-axis Cheap to keep current --> Expensive to keep current
y-axis Low payoff --> High payoff
quadrant-1 Worth the upkeep
quadrant-2 Draw these first
quadrant-3 Generate it or skip it
quadrant-4 Usually not worth it
ER diagram: [0.2, 0.85]
Sequence with failure paths: [0.25, 0.9]
C4 container: [0.3, 0.8]
Deployment: [0.4, 0.75]
State machine: [0.3, 0.7]
Network topology: [0.5, 0.65]
Gantt: [0.8, 0.4]
Class diagram: [0.7, 0.2]
Use case: [0.6, 0.15]
Communication: [0.6, 0.1]
5. Wrapping up the folder
Across all five notebooks, the same three rules decide whether a diagram was worth drawing.
- One question per diagram. Structure, behaviour, scope, architecture and process are different questions. A picture that answers two of them answers neither.
- Text source, in the repository, next to the thing it describes. Every diagram in this folder is Mermaid, WaveDrom or PlantUML source, so it diffs in a pull request and can be regenerated. A PNG in a wiki is a screenshot of something that used to be true.
- Generate what can be generated, hand-draw only intent. ER diagrams, dependency graphs, class diagrams and git graphs come out of tools. Deployment, C4, DFDs and swimlanes encode decisions no tool can recover, and those are the ones worth your time.
If you keep only three diagram types, the ones from the overview still hold up: sequence for how an interaction works, ER for the data shape, and C4 container for the moving pieces. Add a deployment diagram the first time you get paged at 2am and cannot remember which container holds Redis.
The folder
| Notebook | Covers |
|---|---|
| 01 Overview | The full taxonomy and the short list |
| 02 Structural | Class, ER, component, deployment, package |
| 03 Behavioural | Sequence, state machine, activity |
| 04 Requirements and scope | Use case, user flow, journey, requirement traceability |
| 05 Architectural | C4, data flow and STRIDE, network topology |
| 06 Process and ops | Gantt, swimlane, timing, plus gitGraph, timeline, quadrant |