The language
Reference
Every statement of the .loadmap language, its properties and what it may hold. It is written from the same table the
checker and the editor's completions read, so it cannot drift from what the language accepts.
On this page
The top level
A loadmap definition.
| Property | Value | |
|---|---|---|
title |
string, constant | The heading above the diagram. |
direction |
right | down |
Which way the diagram runs. Default right, or down when its widest layer has more boxes than its longest chain. Narrow screens always run down. |
layout |
compact | stable |
compact (the default) lays out each scenario, story step, preset and choice of a select or switch on its own and moves the boxes from one to the next; stable gives every box one place, the largest it needs anywhere, so none of them moves a box. Neither the load nor a range moves one. |
speed |
number, constant | Simulated seconds per real second. Default 10. |
transition |
number, constant | Seconds the diagram takes to move to a new structure (a scenario, a story step, a control that adds pods); 0 cuts. Default 0.8, at most 5; with reduced motion it cuts. |
fullScreen |
a list of verdict, live, limits, controls, headroom, compare, assumptions |
The panels full screen shows, compact, below the diagram. Default all of them. |
fullScreenMode |
panels | focus |
What full screen opens with: the panels, or focus (the diagram, the story, the verdict and the load). Default panels. |
assume |
string, constant | A line added before the generated assumptions. |
searchMax |
number, constant | The highest load multiple the limits search. Default 2000. |
Holds: load, param, preset, scenario, growth, expect, step, let, fit, flow, component, node, cluster, pool, tier, thresholds.
Holds edges: a -> b, a -> b: label, a -> b { label: …; when: … }.
loadmap
The first line: the version of the language this definition is written in.
loadmap 1
After the keyword: version.
load
The load, as a multiple of today. It drives the limits.
load "Users, × today" { max: 100; default: 10 }
After the keyword: [label].
| Property | Value | |
|---|---|---|
min |
number, constant | The lowest multiple. Default 1. |
max (required) |
number, constant | The highest multiple on the slider. |
step |
number, constant | The slider step. Default 1. |
default |
number, constant | Where the slider starts. Default the minimum. |
param
A control: options make a select, min and max a slider, a true or false default a switch.
param pods "Worker pods" { options: [2, 3, 4, 6]; default: 3 }
After the keyword: id [label].
| Property | Value | |
|---|---|---|
options |
options, constant | The choices of a select: [2, 3, 4] or ["a", "b"]. |
min |
number, constant | The lowest value of a slider. |
max |
number, constant | The highest value of a slider. |
step |
number, constant | The step of a slider. Default 1. |
default (required) |
value, constant | The starting value. |
hint |
string, constant | One line under the control. |
tag |
string, constant | A short tag next to the label, e.g. "estimate". |
enabled |
boolean, formula of parameters | Greys the control out while this is false; it reads only parameters. |
format |
string, formula of value |
How a value is shown, from value: ${value} pods. |
preset
A named set of values, offered as a button.
preset "Black Friday" { load: 40; pods: 6 }
After the keyword: label.
Its properties are named by parameters (and load).
scenario
A named design to compare: the defaults plus these values, never the load. The first is the baseline.
scenario "Proposed" { pods: 6; gateways: 2 }
After the keyword: label.
Its properties are named by parameters (not load).
growth
How fast the load grows, compounded from asOf, where it is 1×: load multiples become dates.
growth { rate: 0.06; per: month; asOf: "2026-11-01" }
| Property | Value | |
|---|---|---|
rate (required) |
number, constant | Growth per period, as a share: 0.06 is 6 %. |
per (required) |
month | year |
month or year. |
asOf (required) |
string, constant | The day the load is 1×: "2026-11-01". |
expect
What must keep holding, on the pessimistic edge (every capacity at its low bound): loadmap check fails when it does not.
expect "Today keeps 7×" { target: 7 }
After the keyword: [label].
| Property | Value | |
|---|---|---|
scenario |
scenario, constant | The scenario whose values it checks; the defaults without one. |
component |
component, constant | One component; the first limit without one. |
target |
number, constant | The target holds up to at least this load multiple. |
full |
number, constant | Nothing (or the component) runs out before this load multiple. |
step
A step of the story the page walks through, in order: its text, and the values to show it at. Play (and loadmap record --story) shows the whole diagram, closes in on what the step changes, changes it, and steps back.
step "At 30×, the workers run out first." { load: 30; focus: workers; title: "Users to 30×" }
After the keyword: label.
| Property | Value | |
|---|---|---|
scenario |
scenario, constant | Start from this scenario's values; without one, from the defaults. |
title |
string, constant | The few words the diagram shows while Play shows the step. Default: what the step changes. |
focus |
component, constant | The component to point at: its box is outlined. |
seconds |
number, constant | How long Play holds the whole diagram after the step changes it: the time to read it. Default 4. |
Its properties are named by parameters (and load).
let
A named formula other formulas can use by its name.
let perPosition = watchOnly ? 0.3 : 1.2
After the keyword: id = formula.
fit
cost = a + b × x, fitted from measured points. Call it like a function: workerCores(rate).
fit workerCores "Worker CPU per request" { source: "load test"; points rate cores { 200 0.26 } }
After the keyword: id [label].
| Property | Value | |
|---|---|---|
source |
string, constant | Where the points came from. |
through |
origin |
origin: a cost with no idle part (a = 0). |
Holds: points.
points
The measured points of a fit: the names of x and y, then one "x y" row per line.
points rate cores {
200 0.2599
350 0.3061
}
After the keyword: x y.
flow
Something that moves through the system, with its rate and its route.
flow orders "orders" { unit: "order"; rate: 40 * load; route: gateway -> topic -> workers }
After the keyword: id [label].
| Property | Value | |
|---|---|---|
unit |
string, constant | One unit of the flow, singular: "order". |
rate (required) |
number, formula | Units per second. |
priority |
number, constant | 1 is served first. Flows of the same priority share. |
route (required) |
route, constant | The stages it passes, in order: a -> b -> c. |
from (required) |
node, constant | The node its dots start from. |
color |
accent | alt | ok | warn | drop | muted |
A theme colour (accent, alt, ok, warn, drop, muted) or a CSS colour in quotes. |
Holds: drop, merge, retry.
drop
Units older than olderThan simulated seconds are dropped before they are handled.
drop { olderThan: 60; reason: "too old" }
| Property | Value | |
|---|---|---|
olderThan (required) |
number, formula | Seconds. |
reason |
string, formula | Shown with the drop meter. |
when |
boolean, formula | The rule applies only while this is true. |
merge
Under backlog, this share of what is handled is superseded by a newer unit: keep the newest per key.
merge { share: 0.37; reason: "newest kept" }
| Property | Value | |
|---|---|---|
share (required) |
number, formula | The share superseded, 0 to 1. |
reason |
string, formula | Shown with the meter. |
when |
boolean, formula | The rule applies only while this is true. |
retry
A unit turned away on the route (by a pass, limit or cache stage past capacity) is sent again, up to times more times. The attempts settle where the retries they cause are the ones assumed.
retry { times: 3; budget: 0.1 }
| Property | Value | |
|---|---|---|
times (required) |
number, formula of parameters | Retries after the first attempt: a whole number. Reads only the parameters. |
budget |
number, formula of parameters | At most this share of the flow is added as retries: 0.1 adds at most 10 %. Without one, every retry is sent. |
when |
boolean, formula of parameters | The rule applies only while this is true; it reads only parameters. |
component
Something that can run out: its demand against its capacity. On a box, write these lines on the box.
component cache "Cache" { demand: flows.reads; capacity: estimated(9000, "req/s") }
After the keyword: [id] [label].
| Property | Value | |
|---|---|---|
name |
string, constant | The component's name in the limits list. Defaults to the label. |
short |
string, constant | The name inside a sentence, with its article: "the database". |
plural |
boolean, constant | "are past capacity" instead of "is". |
demand |
number, formula | What the component must handle, in its capacity's unit. Without one: the units per second reaching its stages. |
capacity |
capacity, formula | What it can handle: measured(value, unit, source) or estimated(value, unit, source), value ± 30% saying how sure it is; configured(value, unit, source) for a limit someone set. |
when |
boolean, formula | The component is switched off (no utilization) while this is false. |
over |
string, formula | What happens past 100 %, as a clause: "clients get 429s". |
describe |
string, formula | One line under the name in the limits list. |
tier
A lane across the flow (edge, app, data) drawn behind its boxes, its name in a header. Tiers run in the order they are declared.
tier data "Data"
After the keyword: id [label].
node
A box. It may run a stage (pass, store, sink, fanout) and own a component (demand and capacity lines).
node gateway "API gateway" { pass; demand: flows.orders; capacity: estimated(20000, "req/s") }
After the keyword: id [label] [sub].
| Property | Value | |
|---|---|---|
sub |
string, formula | The second line of the box. |
shape |
box | cylinder |
box (the default) or cylinder. |
tier |
tier, constant | The tier the box stands in; without one, that of the boxes that feed it. |
name |
string, constant | The component's name in the limits list. Defaults to the label. |
short |
string, constant | The name inside a sentence, with its article: "the database". |
plural |
boolean, constant | "are past capacity" instead of "is". |
demand |
number, formula | What the component must handle, in its capacity's unit. Without one: the units per second reaching its stages. |
capacity |
capacity, formula | What it can handle: measured(value, unit, source) or estimated(value, unit, source), value ± 30% saying how sure it is; configured(value, unit, source) for a limit someone set. |
when |
boolean, formula | The component is switched off (no utilization) while this is false. |
over |
string, formula | What happens past 100 %, as a clause: "clients get 429s". |
describe |
string, formula | One line under the name in the limits list. |
Holds: pass, store, sink, fanout, cache, limit, component.
cluster
Members (brokers) holding the partitions of one or more queues (topics).
cluster kafka "Kafka" { members: 3; queue topic { partitions { orders: 12 } } }
After the keyword: id [label] [sub].
| Property | Value | |
|---|---|---|
sub |
string, formula | The second line of the box. |
members (required) |
number, formula | How many members. |
memberLabel |
string, formula of i |
Each member's label, from its index i: broker ${i}. |
tier |
tier, constant | The tier the box stands in; without one, that of the boxes that feed it. |
name |
string, constant | The component's name in the limits list. Defaults to the label. |
short |
string, constant | The name inside a sentence, with its article: "the database". |
plural |
boolean, constant | "are past capacity" instead of "is". |
demand |
number, formula | What the component must handle, in its capacity's unit. Without one: the units per second reaching its stages. |
capacity |
capacity, formula | What it can handle: measured(value, unit, source) or estimated(value, unit, source), value ± 30% saying how sure it is; configured(value, unit, source) for a limit someone set. |
when |
boolean, formula | The component is switched off (no utilization) while this is false. |
over |
string, formula | What happens past 100 %, as a clause: "clients get 429s". |
describe |
string, formula | One line under the name in the limits list. |
Holds: queue, component.
pool
A workers stage drawn as pods holding a grid of workers.
pool workers "Workers" { workers { pods: pods; perPod: 8 } }
After the keyword: id [label] [sub].
| Property | Value | |
|---|---|---|
sub |
string, formula | The second line of the box. |
podLabel |
string, formula of i |
Each pod's label, from its index i: pod ${i}. |
tier |
tier, constant | The tier the box stands in; without one, that of the boxes that feed it. |
name |
string, constant | The component's name in the limits list. Defaults to the label. |
short |
string, constant | The name inside a sentence, with its article: "the database". |
plural |
boolean, constant | "are past capacity" instead of "is". |
demand |
number, formula | What the component must handle, in its capacity's unit. Without one: the units per second reaching its stages. |
capacity |
capacity, formula | What it can handle: measured(value, unit, source) or estimated(value, unit, source), value ± 30% saying how sure it is; configured(value, unit, source) for a limit someone set. |
when |
boolean, formula | The component is switched off (no utilization) while this is false. |
over |
string, formula | What happens past 100 %, as a clause: "clients get 429s". |
describe |
string, formula | One line under the name in the limits list. |
Holds: workers, component.
pass
Flows pass through; past capacity the share above 100 % is rejected.
pass "the gateway"
After the keyword: [id] [label].
| Property | Value | |
|---|---|---|
component |
component, constant | The component whose capacity this stage uses. Defaults to its box's component. |
cache
A share of the units (hit) is answered here and goes no further; the rest carry on to the next stage. Past capacity the share above 100 % is rejected.
cache { hit: 0.8 }
After the keyword: [id] [label].
| Property | Value | |
|---|---|---|
hit (required) |
number, formula | The share answered here, 0 to 1. |
component |
component, constant | The component whose capacity this stage uses. Defaults to its box's component. |
limit
A rate limiter: its component's capacity is the limit. Above it the share over is turned away, and the stages after it see only what got through.
limit
After the keyword: [id] [label].
| Property | Value | |
|---|---|---|
component |
component, constant | The component whose capacity this stage uses. Defaults to its box's component. |
store
Where a flow ends: written to its component.
store
After the keyword: [id] [label].
| Property | Value | |
|---|---|---|
component |
component, constant | The component whose capacity this stage uses. Defaults to its box's component. |
sink
Where a flow ends without a component: a receiver, a viewer.
sink "contacts"
After the keyword: [id] [label].
queue
Flows wait here; the next stage of each route drains it.
queue topic "orders topic" { partitions { orders: 12 } }
After the keyword: [id] [label].
| Property | Value | |
|---|---|---|
component |
component, constant | The component whose capacity this stage uses. Defaults to its box's component. |
Holds: partitions.
partitions
Partitions per flow, drawn as cells across the members.
partitions { orders: 12; events: 24 }
Its properties are named by flows.
workers
A pool of workers: pods × workers per pod.
workers { pods: pods; perPod: 8 }
After the keyword: [id] [label].
| Property | Value | |
|---|---|---|
pods |
number, formula | How many pods; an autoscaled pool has autoscale instead. |
perPod (required) |
number, formula | Workers per pod. |
fill |
round-robin | in-order |
round-robin spreads work across pods (the default); in-order fills pod 0 first. |
component |
component, constant | The component whose capacity this stage uses. Defaults to its box's component. |
Holds: autoscale.
autoscale
Pods are added and removed to hold each running pod near target, between min and max. The component's capacity is the pool at max pods: it runs out when the pool cannot grow further.
autoscale { min: 2; max: 10; target: 0.7 }
| Property | Value | |
|---|---|---|
min (required) |
number, formula | The fewest pods, at least 1. |
max (required) |
number, formula | The most pods. |
target (required) |
number, formula | The utilization each running pod is held at, above 0 and at most 1: 0.7 scales out above 70 %. |
fanout
Each unit is copied to several stages; one "flow -> stage: copies" line per branch. Last on a route.
fanout "push broker" {
alerts -> contacts: 1
}
After the keyword: [id] [label].
| Property | Value | |
|---|---|---|
component |
component, constant | The component whose capacity this stage uses. Defaults to its box's component. |
Holds branches: flow -> stage: copies per unit.
thresholds
The utilization of the target and of "runs out".
thresholds { target: 0.5; full: 1 }
| Property | Value | |
|---|---|---|
target |
number, constant | Default 0.5. |
full |
number, constant | Default 1. |
Edges
A line between two nodes: a -> b, a chain a -> b -> c, or with a label a -> b: "…".
| Property | Value | |
|---|---|---|
label |
string, formula | The text on the edge. |
when |
boolean, formula | The edge is left out while this is false. |
Functions
min, max, round, floor, ceil, abs, sqrt, log, exp, pow, fmt, compact, pct, secs, measured, estimated, configured