Latency budgets
CounterFire is judged by one unbroken loop, and that loop has explicit wall-clock budgets. The budgets are not aspirations; they are asserted in the automated test suite so a regression turns the pipeline red instead of silently shipping.
The budgets
| Path | Budget |
|---|---|
| Paid order appears on the KDS | under 2 seconds |
| 86 a dish reaches the customer portal | within a few seconds |
| Customer places an order | under 60 seconds (a usability target for the flow) |
The first two are platform latency budgets the system is engineered and tested against. The third is a user-experience target for how long checkout should take a customer, and it shapes the customer portal design (sticky category tabs, a one-tier modifier sheet, a persistent cart with a live subtotal, guest checkout).
What spans each budget
Order to KDS, under 2 seconds
When a customer pays, the chain is: the Worker handles POST /v1/orders/:id/pay,
emits the order_paid event, writes it to the D1 order_event log, and OrderHub
fans it out to connected KDS clients, where a new ticket appears and the chime
sounds.
To keep this under budget, the paid event is emitted to OrderHub before or in parallel with non-critical work, so the ticket is not waiting on anything the kitchen does not need.
86 to portal, within a few seconds
When an owner toggles a dish sold out via
PATCH /v1/products/:id/sold-out, the chain is: the Worker flips is_sold_out,
invalidates the MENU_CACHE entry for that restaurant, and the next customer
menu load no longer offers the dish.
To keep this under budget, the menu cache is invalidated synchronously with the write, so there is no stale window in which a customer can still add a sold-out item.
Why measurement matters
These budgets span several moving parts: the Worker, the OrderHub Durable Object, the D1 write, and cache invalidation. Latency that crosses that many layers regresses silently if nobody is watching it. The mitigation is to measure it: explicit wall-clock assertions are baked into the Playwright end-to-end suite, so the budgets are continuously verified rather than assumed.
Where the budgets are enforced
The CI pipeline runs on every change: typecheck, lint, unit and Workers-runtime
tests (with the 100 percent coverage gates on packages/core and on the
apps/api business logic), component tests, then Playwright end to end. The
latency assertions (order to KDS under 2 seconds, 86 to portal within a few
seconds) are part of that end-to-end stage. Merges are blocked unless every stage
passes, which keeps the budgets measured and the signature loop reliably green.