Skip to content

Warehouse inventory that stays accurate on its own

An inventory automation layer that reconciles counts across warehouses, forecasts replenishment, and flags discrepancies before they become stockouts.

Network inventory

4 distribution centres · one movement ledger · shared catalogue

Directed countsSKU, bin or reference/Thu 17 Sep 2026 · 14:32MO
Count accuracy, network98.7%Against physical cycle counts, all 4 centres
Scans reconciled today18,40611 still awaiting a match
Zones counted, last 24 h7Directed at drifting SKUs, not the whole aisle
Cover under 10 days7 lines3 already past the reorder point

Movements reconciled per hour

All sites · since 06:00
1,642
2,318
2,506
2,441
2,287
2,196
2,354
2,212
450
06:0007:0008:0009:0010:0011:0012:0013:0014:32
18,406 appended to the ledger today 11 awaiting a match

Drift alerts

11 open across the network
MID-2CTN-4410B-14-02-C · 12:31–14:32−4 EA
SCO-4WRP-0045B-04-01-C · 10:02–12:50−2 EA
MID-2LBL-1109C-03-11-A · 11:26–13:04−7 EA
NTH-1BAG-0712A-02-06-B · 08:10–11:45−40 EA
STH-3GLV-0870C-11-03-A · 06:40–09:15−3 EA

Distribution centres

Pilot facility first, then the other three
CentreReconciled todayAwaiting matchZones countedOpen variancesCover < 10 daysReplenishment
NTH-1Wakefield4,8123232Covered
MID-2DaventryPilot5,23642521 past reorder point
STH-3Avonmouth4,39022221 past reorder point
SCO-4Bellshill3,96821111 past reorder point

How the work was scoped

Industry
Warehousing & Fulfillment
Duration
13 weeks
Cooperation model
Fixed price, phased
Services
Inventory automationReplenishment forecastingAlerts
Integrations
StripeSendGridSegmentSentry
Technologies
PythonFastAPIPostgreSQLRedisScikit-LearnReact
Team
1 Project lead1 Product designer1 Data engineer1 Analytics engineer1 Backend engineer1 QA engineer

Client name withheld under NDA. Engagement details are shown to the extent our agreement permits.

Introduction

The question we were asked

Warehouse counts drifted and replenishment was reactive. We built automation that keeps inventory accurate and predicts what to reorder.

Four distribution facilities, a shared catalog, and cycle counts done on a rolling schedule that took six weeks to walk the whole aisle. By the time a count reached a bin, the number it produced was already historical. The engagement was commissioned after a peak week where pickers hit empty bins on lines the system said were in stock at two other sites.

Data & AI

The decision, first

  1. 01

    Inventory count accuracy increased to 98.7% across all 4 distribution facilities.

    Accuracy followed from deriving stock from events: once no one can type over the number, every disagreement has an event behind it.

  2. 02

    Stockouts reduced by 44% through predictive replenishment alerts.

    The stockouts that mattered were the ones where stock existed elsewhere. That's a visibility problem more than a forecasting one.

  3. 03

    Cycle-count labor effort dropped by 60% with automated barcode discrepancy catching.

    Counting effort fell because counting became targeted. The ledger says which SKUs are drifting, so walking the whole aisle stopped being the only option.

What the numbers couldn't answer

Manual cycle counts lagged reality, so pickers hit empty bins and buyers reordered too late across multiple warehouses.

Stock was a stored number that receipts, picks and adjustments each edited in turn, so a disagreement between the shelf and the screen had no history: nobody could say when it had opened or what caused it. Corrections were applied to make the screen match the shelf, which erased the evidence and guaranteed the next discrepancy would be equally unexplainable.

We built an automation layer that reconciles movements across warehouses in real time, forecasts replenishment, and flags discrepancies before they cause stockouts.

The solution

How we worked it through

  • Streamed stock movements into one real-time inventory model

    Streaming was the easy half. The real work was migrating years of stored counts into a ledger without inventing history the sites couldn't vouch for.

  • Automated cross-warehouse reconciliation and alerts

    Reconciliation needed a noise floor before it could alert, and the pilot facility's variance turned out to differ enough by aisle to need measuring per aisle.

  • Forecast replenishment per SKU and location

    Reorder points are solved per SKU per site against the supplier's real lead-time spread. The mean is what the stockouts had been hiding behind.

  • Piloted in one facility, then scaled to the network

    One facility ran the full thirteen weeks before the other three, which is how the per-aisle noise floor came to be measured instead of assumed.

Process

Phase by phase

  1. Phase 1: Stock Drift & Cycle Count Audit

    Warehouse Workflow & Accuracy Analysis

    Audited cycle counts, barcode scanning latency, and stockout frequency across 4 distribution centers.

    • Stock Drift Report
    • Warehouse Data Schema
    • Cycle Count Benchmark
  2. Phase 2: Real-Time Ledger Engineering

    Multi-Warehouse Ingestion Pipeline

    Engineered a real-time reconciliation engine streaming stock movements into a central ledger powered by Redis and PostgreSQL.

    • Real-Time Ledger API
    • Redis Sync Pipeline
    • Barcode Connector
  3. Phase 3: Replenishment & Discrepancy Engine

    Predictive Forecasting & Alerting

    Trained SKU-level demand forecasting models and set up automated discrepancy alerts.

    • Replenishment Engine
    • Discrepancy Alerting System
    • Demand Forecasting Model
  4. Phase 4: Multi-Facility Scale & Rollout

    Network Deployment & SLA Sign-off

    Piloted in the primary warehouse before scaling across all 4 distribution hubs, reaching 98.7% count accuracy.

    • Facility Pilot Report
    • Network Rollout Clearances
    • SLA Sign-off
Pilot & rollout

MID-2 Daventry ran all 13 weeks before anything reached the other three

Pilot reportSKU, bin or reference/Thu 17 Sep 2026 · 14:32MO

Pilot · MID-2 Daventry

Cycle-count team checks the ledger weekly
Weekly ledger check against physical counts
W1W2W3W4W5W6W7W8W9W10W11W12W13
Noise floor per aisle, measured here before any alert could fire
Aisle A±1.2%412 bins
Aisle B±0.6%388 bins
Aisle C±2.4%356 bins
Aisle D±0.9%404 bins
Aisle E±1.6%298 bins
Aisle F±0.8%276 bins

Network rollout

Pilot first, then scaled
2NTH-1WakefieldRolled out after the pilotLive
1MID-2DaventryPilot · 13 weekly checks, per-aisle floor measuredLive
2STH-3AvonmouthRolled out after the pilotLive
2SCO-4BellshillRolled out after the pilotLive

Engagement phases

Deliverables signed off
Phase 1Stock drift & cycle count auditStock Drift ReportWarehouse Data SchemaCycle Count Benchmark
Phase 2Real-time ledger engineeringReal-Time Ledger APIRedis Sync PipelineBarcode Connector
Phase 3Replenishment & discrepancy engineReplenishment EngineDiscrepancy Alerting SystemDemand Forecasting Model
Phase 4Multi-facility scale & rolloutFacility Pilot ReportNetwork Rollout ClearancesSLA Sign-off
On screen

The pilot centre's thirteen weekly checks of the ledger against physical counts, the noise floor it measured aisle by aisle before any alert could fire, the rollout to the other three centres, and the four phases with their deliverables.

What it changed

98.7%

Inventory accuracy

−44%

Stockouts

Inventory accuracy is measured against physical cycle counts across all four facilities in the two quarters after rollout. Stockouts means picker-reported empty bins on lines the system showed as available. That's the failure the engagement was actually about, and a narrower measure than the overall stockout rate.

Client name withheld under NDA. Figures are approximate, drawn from the engagement’s own reporting.

01

Real-Time Stock Reconciliation Ledger

Streams warehouse scans and order fulfillment events into a single real-time inventory model.

Scans, receipts, picks and adjustments all write to one append-only movement ledger, and stock is the fold over it. Nobody updates the number by hand. That's what made reconciliation possible: a disagreement is now a specific event you can point at, not a mystery delta. Redis holds the current fold per SKU per location, so a read is a lookup while the audit trail stays complete.

What shipped
  • Append-only movement ledger; stock is the fold over it
  • Every discrepancy traceable to a specific event
  • Redis holds the current fold, so reads stay instant
Movement ledger

MID-2 Daventry · append-only · stock is the fold over these rows

All event typesSKU, bin or reference/Thu 17 Sep 2026 · 14:32MO
Scans, receipts, picks and adjustments all append here. Nothing edits a stored count.18,406 reconciled today11 awaiting a match

Live stream

Newest first
TimeEventRefSKUBinQtyDeviceState
14:32:11ADJTVA-0318CTN-4410B-14-02-C−4AUTOHeld
14:32:08CYCLCC-2611CTN-4410B-14-02-C=88RF-07Matched
14:29:51PICKSO-88241VOD-3300D-21-04-A−18RF-04Matched
14:26:33RCPTPO-4472GLV-0870A-07-01-B+48DOCK-3Awaiting match
14:22:07MOVEMV-7721TPE-2200B-15-03-A−12RF-02Matched
14:18:44PICKSO-88236RBL-0090D-22-01-B−3RF-06Matched
14:05:58RETNRMA-1187RBL-0090D-22-01-B+2DOCK-1Awaiting match
13:58:12PUTWPA-0088LBL-1109C-03-11-A+36RF-01Matched
13:49:30PICKSO-88229LBL-1109C-03-11-A−12RF-04Matched
13:41:07MOVEMV-7719WRP-0045A-09-02-C−30RF-02Matched
13:18:26PICKSO-88231CTN-4410B-14-02-C−12RF-04Matched
13:02:15PICKSO-88224GLV-0870A-07-01-B−4RF-06Matched
12:31:56MOVEMV-7714CTN-4410B-14-02-C−36RF-02Matched
12:05:40PICKSO-88220RBL-0090D-22-01-B−6RF-04Matched

Newest 14 of 5,236 rows at MID-2 today · highlighted rows touch B-14-02-C

The fold for one bin

MID-2
CTN-4410 at B-14-02-CDouble-wall carton 457×305 · each
Fold carried in at 06:00140
07:52PICKSO-88190−24116
09:47RCPTPO-4471+60176
10:22PICKSO-88213−24152
11:05PICKSO-88219−12140
12:31MOVEMV-7714−36104
13:18PICKSO-88231−1292
Current fold · RedisA lookup, not a sum over the day92
Blind count CC-2611 · 14:32Counted 88 · window 12:31–14:32−4
VA-0318 −4 appended, not typed overHeld
On screen

The movement ledger at the pilot centre: every scan, receipt, pick and move appended as a row, and beside it one bin's fold from the 06:00 carry-in to the figure Redis holds now, the blind count that disagrees by four, and the adjustment appended and held rather than typed over.

Replenishment

Reorder points per SKU per site · triggered on the supplier's lead-time spread

Draft purchase ordersSKU, bin or reference/Thu 17 Sep 2026 · 14:32MO
Cover under 10 daysAll 4 sitesAll suppliers7 lines · 3 past the reorder point

Lines by cover

Reorder point = velocity × p90 lead time × site seasonal factor
SKUSiteOn handPer dayCoverLead p50 / p90SeasonReorder ptSuggestedStatus
CTN-4410Double-wall carton 457×305MID-2540 EA628.74 / 11 d×1.006821,100Past reorder point
GLV-0870Nitrile glove, blue, LSTH-362 BX232.73 / 7 d×1.00161430Past reorder point
WRP-0045Stretch wrap 500 mmSCO-496 RL128.06 / 9 d×1.00108180Past reorder point
TPE-2200Packing tape 48 mmNTH-1310 RL447.03 / 6 d×1.10291—Above
VOD-3300Void-fill paper rollSTH-3150 RL188.32 / 5 d×1.0090—Above
LBL-1109Thermal label 100×150MID-2186 RL218.95 / 8 d×1.00168—Above
BAG-0712Mailing bag 250×350NTH-12,400 EA2609.24 / 7 d×1.152,093—Above

Lead time · carton supplier, last 30 deliveries

CTN-4410 · days from order to receipt
3135211131
usually 4 dmean 5.6 dp90 11 d · the trigger
3456789101112

Why this line orders today

CTN-4410 at MID-2
On the mean · 5.6 dReorder at 350 · on hand 540 looks coveredNo order
On the spread · p90 11 dReorder at 682 · order 1,100 todayPast
Seasonal factor this week, this SKU
NTH-1×1.10MID-2×1.00STH-3×1.05SCO-4×0.95
02

Predictive SKU Replenishment Engine

On screen

Replenishment filtered to cover under ten days: seven lines, three past a reorder point solved per SKU per site. The carton supplier is usually four days and sometimes eleven, so the line that looks covered on the mean orders today on the spread, with this week's seasonal factor set per site.

Forecasts reorder triggers based on lead times, order velocity, and seasonal spikes.

Reorder points are set per SKU per site, solved from order velocity, that supplier's real lead-time distribution and the seasonal curve. No single global cover figure. The trigger uses the lead-time spread instead of the mean, so a supplier who is usually four days but sometimes eleven is treated as the eleven. Averaging that away was what produced the stockouts.

What shipped
  • Reorder points per SKU per site, not one global cover rule
  • Triggered on the lead-time spread, not its average
  • Seasonal curve applied site by site
03

Discrepancy Warning System

Detects inventory drift between physical scans and system balances automatically.

Drift is detected by replaying the ledger against cycle-count scans and flagging where the two diverge faster than the site's normal noise floor. Alerts name the SKU, the location, the size of the gap and the window it opened in, which usually points straight at the shift or the process that caused it. Counting goes where the drift is, instead of sweeping the aisle blind.

What shipped
  • Ledger replayed against cycle counts to find divergence
  • Alerts carry the gap size and the window it opened in
  • Counting aimed at drifting SKUs, not the whole aisle
Variances raised today

MID-2 Daventry · ledger replayed against cycle-count scans

Direct next countsSKU, bin or reference/Thu 17 Sep 2026 · 14:32MO
7 raised today2 cleared5 waiting on a personRaised only where the gap is wider than the aisle’s noise floor, measured at the pilot

System against counted, bin by bin

Newest first
RefBinSKUSystemCountedGapGap %Aisle floorWindowState
VA-0318B-14-02-CCTN-4410Double-wall carton 457×3059288−44.3%±0.6%12:31–14:32Awaiting review
VA-0317D-22-01-BRBL-0090Rubber mallet 450 g130126−43.1%±0.9%12:05–13:52Awaiting review
VA-0316B-15-03-ATPE-2200Packing tape 48 mm412409−30.7%±0.6%10:44–13:20Awaiting review
VA-0315C-03-11-ALBL-1109Thermal label 100×1505851−712.1%±2.4%11:26–13:04Awaiting review
VA-0314A-09-02-CWRP-0045Stretch wrap 500 mm9691−55.2%±1.2%09:10–10:55Awaiting review
VA-0313D-21-04-AVOD-3300Void-fill paper roll240244+41.7%±0.9%07:12–09:38ClearedPO-4468 receipt posted late
VA-0312A-07-01-BGLV-0870Nitrile glove, blue, L8684−22.3%±1.2%06:20–08:40ClearedRecount agreed with the ledger

VA-0318 · CTN-4410

Alert as sent to the shift lead
BinB-14-02-CGap−4 EA · 4.3%Window12:31–14:32Aisle floor±0.6% · aisle B
Opened after MV-7714 at 12:31: 36 moved to overflow B-14-04-AOne pick since, at 13:18. The move is the event to check first.
Count B-14-04-AApprove adjustment · appends −4

Gap against the aisle's noise floor

× floor · marker at 1×
B-14-02-C7.2×
D-22-01-B3.4×
B-15-03-A1.2×
C-03-11-A5.0×
A-09-02-C4.3×
D-21-04-A1.9×
A-07-01-B1.9×
On screen

Variances raised today, system against counted bin by bin: two cleared and five waiting on a person. The selected alert names the SKU, the bin, the gap and the window it opened in, points at the move that likely caused it, and every gap is set against its aisle's noise floor.

Ways of working

How the engagement ran

A cross-functional team of 6 worked on a fixed price, phased basis over 13 weeks, covering Inventory automation, Replenishment forecasting, Alerts. We ran a standing mid-week checkpoint and written decisions in place of status meetings. Nothing shipped without a live demo first.

One facility ran the whole thirteen weeks before anything reached the other three, with its own cycle-count team checking the ledger against physical counts weekly. That pilot is where the drift detector's noise floor came from: the facility's normal variance had to be measured before an alert could mean anything, and it turned out to differ by aisle.

One bin, replayed

A stored number forgets why it is wrong. A ledger remembers.

The same afternoon at one bin, first against a stock figure that every event edits in place, then against the append-only ledger Orbit folds, and finally a carton line reordered on the supplier’s average lead time and on its spread. Switch tabs, or use the arrow keys once one is focused.

Receipts, picks and moves each edit one stored figure in turn. When the count disagrees, the figure is corrected to match the shelf, which makes the screen right and erases any trace of when the gap opened or what opened it.

CTN-4410 · B-14-02-CDouble-wall carton 457×305 · carried in at 140
  1. 07:52 pick edits on hand by −24
  2. 09:47 receipt edits on hand by +60
  3. 10:22 pick edits on hand by −24
  4. 11:05 pick edits on hand by −12
  5. 12:31 move edits on hand by −36
  6. 13:18 pick edits on hand by −12
  7. 14:32 count finds 88, screen says 92
  8. On hand typed over to 88
The on-hand field
88Matches the shelf. The four units are gone from the record.
History of this figureNone. Each edit replaced the last.
When did the gap open?Unknown
Which event caused it?Unknown

Step timing and the reorder chart’s starting stock of 1240 are illustrative. The bin’s events, the 62-a-day velocity, the lead times and both reorder points are the ones Orbit’s screens show.

Architecture

From a scan on the floor to a number nobody types over

Python and FastAPI services over PostgreSQL and Redis, scikit-learn for the SKU-level demand models, and a React console on top. Every stage below reads from or writes to the same movement ledger.

  1. 01 · Source
    Scans, receipts, picks, adjustmentsWarehouse scans and order fulfillment events from all four facilities arrive through the barcode connector as movements. None of them edits a stored count.
  2. 02 · Ingestion
    Redis sync pipelineStock movements stream in real time into one inventory model, so reconciliation runs across the whole network at once.
  3. 03 · Engine
    Reconciliation, drift and replenishmentThe ledger is replayed against cycle counts and flagged only beyond the aisle's noise floor; reorder points are solved per SKU per site on the lead-time spread.
  4. 04 · State
    Append-only ledger in PostgreSQLStock is the fold over the movement ledger. Redis holds the current fold per SKU per location, so a read is a lookup while the audit trail stays complete.
  5. 05 · Delivery
    React console and alertsAlerts name the SKU, the location, the size of the gap and the window it opened in, and counting is directed at the SKUs that are drifting.

Why the number can be trusted

Audit trail & alert integrity

A correction can't erase the evidence

Stock is the fold over an append-only ledger, so no one can type over the number. An adjustment is one more movement beside the event it corrects, and every disagreement keeps the event behind it.

No history the sites couldn't vouch for

Years of stored counts were migrated into the ledger without inventing movements to explain them, so the history it holds is only what the sites can stand behind.

Alerts only past a measured noise floor

The pilot facility ran all thirteen weeks, checked weekly against physical counts, before the other three. Its normal variance was measured per aisle, so an alert means a gap wider than that aisle's usual noise.

Does the stock on your screen still match the shelf? Scope your build in 3 minutes.

Scope your build
Have a project?

Let's talk

Running a large platform, shaping a first MVP, or getting a product ready for a funding round? Tell us where you are. We'll shape the process around it, and stay with you after launch.