Retail · Distributed ERP

Two messages a day.
Books to the penny.

Every checkout sends head office a tiny daily summary — not a firehose of every sale. From those summaries the central books rebuild exactly, and the whole thing keeps working when the network is bad, a server crashes, or a store burns down.

“Every till sends head office just two small messages a day — morning stock-in, nightly close. From those we rebuild your books to the penny. It keeps working on bad networks, never double-counts, survives a server crash or a store fire, and we’ve proven it at 10,000 tills with no slowdown — and the bottleneck that bogs down the big-name ERP systems at that scale, we’ve engineered out.”

How it works

10,000 TILLS · STORES ON A WAN HEAD OFFICE · WAREHOUSE · BOOKS TO THE PENNY 2 messages a day PER TILL ☀ MORNING — REPLENISHMENT OUT (HQ → TILLS) 🌙 NIGHT — REPORTS IN (TILLS → HQ)
☀ Morning — replenishment flows HQ → tills (SODA) 🌙 Night — each till reports back to HQ (EODA close)

What each till sends

Start of day · SODA

“Here’s the stock that arrived.”

One small message listing the morning replenishment received into the store.

🌙
End of day · EODA close

“Here’s what I sold, and what got used up.”

One small message: the day’s takings (to the cent) and the stock consumed. The full sale-by-sale detail stays at the store — only the summary travels.

It’s not literally only two messages. A sale still does a real-time card approval and a points check at the moment of payment — quick calls straight from the till to your processor. The two daily messages are the reporting + replenishment summary. The point: head office and the network are never on the critical path of a sale.

Payments, members & the customer’s phone

💳

Card & e-wallet payments

Legacy: tendered through the central server / broker — another hop that can stall the sale.

Go straight from the till to your bank/processor, as they do today — head office is never in the middle. The approval is a signed line on the receipt; at close it auto-reconciles to the bank’s settlement file, to the cent. Lost link → store-and-forward by your processor’s rules.
🎟️

Members & bonus points

Legacy: a central member lookup on every sale — slow when the line is down.

Members are known by their phone. Points earned just add up — no central lookup. Points spent are checked against one shared balance, so they can’t be double-spent across two stores. Earn is instant and offline-friendly; only redemption needs the quick shared check.
📱

The customer owns their receipts

Legacy: you custody all their data — a breach liability and a compliance burden.

Each customer’s phone keeps their own signed receipts and points — verifiable proof of purchase for returns/warranty with no “let me look you up”, and far less personal data for you to guard. They back it up to their own cloud; you keep only what the books need.

When things go wrong

📡

Network drops

Legacy: sales stall, queue, or fail when the link to the server is down.

The till runs on its own and sends when it can. Re-sending is safe — never double-counts.
💥

Server crashes

Legacy: restore from last backup; anything since the backup can be lost.

Head office rebuilds itself from its log — nothing lost.
🔥

A store burns down

Legacy: whatever never reached the server is gone for good.

That store’s last nightly report is recovered from a signed email backup — and a faked one is rejected.

Proven at scale

0
tills tested, one laptop
0
reports/sec accepted
0
double-counts on retry
0
rebuilt to the penny

As the fleet grows, the central relay keeps up — throughput stays high and cost grows in a straight line, with no wall (measured: W-POS-WAN-SCALE).

200 tills1,890/s
1,0003,340/s
5,0004,424/s
10,0004,597/s

More stores → more throughput, not a slowdown. The work per store stays the same.

The bottleneck we removed

Big ERP systems share one central “next document number” counter. Every till has to queue for it — that’s what chokes them at thousands of tills. We let each till number its own.

Legacy — one shared counter

Every till waits its turn

At 10,000 tills that’s 90,000 locked hand-offs a day — the queue is the wall.

This approach — each till numbers its own

No queue, no clashes

Same 90,000 documents, 0 clashes, no central lock. The wall is gone.

Side by side

What matters to youLegacy centralized ERP / POSThis approach (measured)
What each till sendsEvery sale, in real time, to the central server2 small messages a day per till
Bad / dropped networkSale stalls or queues; leans on the server being upTill runs on its own; sends its summary when it can
The “next document number”One shared counter — every till queues (the choke point)Removed — each till numbers its own
A message gets re-sentRisk of double-counting; needs careful handlingDuplicate ignored — safe to retry
Head-office server crashesRestore from last backup; gap can be lostRebuilds from its log — nothing lost
A store burns downWhatever didn’t reach the server is goneRecovered from a signed, tamper-proof backup
Rebuild books from the summariesN/A — server already holds it allProven exact to the penny
Scale we testedNeeds a server farm + tuning to push high till counts10,000 tills on one laptop, straight-line scaling
InfrastructureCentral servers, DB licences, ops teamNo server farm; runs lean
Card paymentsRouted via the central server / brokerTill ↔ processor direct; result is a signed receipt line, auto-reconciled to the cent
Members & pointsCentral member-DB lookup per salePhone-identified; earn adds up offline, redeem checked against one shared balance
Customer dataYou custody all of it (breach risk)Customer’s phone owns its receipts; you hold only what the books need
Honest caveatDecades of features (finance, HR, manufacturing…)This proves the reporting + recovery backbone at scale, not the full feature catalogue. One known gap: two stores inventing the same brand-new product at once needs more work.

Same books, to the penny — but it survives bad networks, crashes and fires, and it doesn’t hit the wall that bogs legacy systems down at thousands of tills.

How the benchmark reads — the workings

What the run actually does (and where each number comes from)

  1. Real unit, synthetic fleet. One real store’s economics are read from the seed database (ad_seed_fullwidth.db): a real product, its real price, its real bill-of-materials recipe. The fleet size N (200 → 10,000) is the only made-up number — each till replays that one real unit. Nothing is invented; the per-store totals trace to actual rows.
  2. Two messages per till. Each till sends a SODA (morning stock-in) and an EODA (nightly close) over real HTTP to a central relay. So central receives exactly 2 × N messages — that’s the 2N-ops column. The relay just orders and de-duplicates them; it computes nothing.
  3. Throughput (the bar chart). We time how long the relay takes to accept each wave. reports/sec = messages ÷ seconds. It stays high as N grows because the work per message is fixed — that’s the “straight line”, and why the bars rise rather than collapse.
  4. “To the penny.” Central re-adds every nightly summary and checks the total against the expected figure computed independently — money in exact cents (no rounding drift). Match = pass (test B4).
  5. “0 double-counts.” We deliberately re-send a fifth of the tills (a flaky-network retry). The relay accepts 0 extra and the totals don’t move (test B3).
  6. Crash & fire. We kill the relay and restart it — it rebuilds from its log, totals identical (B5). We simulate a store losing everything — its last signed nightly report is recovered from an email backup, and a forged one is rejected (B6).
  7. The bottleneck. A traditional shared document-number counter would need 90,000 locked hand-offs a day at 10,000 tills (and clash 89,991 times if naively split). Letting each till number its own gives 0 clashes, no lock (test G1).

Run it yourself — Node.js, no server, ~10 seconds

# full sweep 200 → 10,000 tills (writes build/erp/poc_pos_wan_scale.log)
node scripts/poc_pos_wan_scale.js

# quick check at two sizes
node scripts/poc_pos_wan_scale.js 200,1000

the benchmark script (raw)  ·  the spec it proves