Simulation · Systems

To reason about inventory allocation, I made it a simulation you can run

Essay · project notes · 6 min read
Project notes This piece belongs to the InventorySim build — see the whole project →

Inventory allocation is one of those problems that looks simple in a spreadsheet and turns out to be anything but. You have supply. You have demand. You split one across the other. How hard can it be?

The trouble is that the interesting part is time. Supply doesn’t arrive all at once — it lands in waves. Demand isn’t one number — it’s two very different kinds of promise. And the moment you add a clock, the static picture a spreadsheet gives you stops telling the truth.

I kept running into this while thinking through a B2B wholesale setup, so I stopped drawing it and built it: a live simulation you can actually run, pause, and poke at. This is a note on what it models and why a simulation, of all things, turned out to be the right way to reason about it.

Two kinds of demand, one pool of supply

Wholesale demand usually comes in two flavours, and they behave nothing alike.

Committed (pre-buy) demand is a promise. Partners commit to orders ahead of the season; you’re on the hook to fulfil them. It’s high-priority and mostly known in advance — but it’s not certain, because partners can typically cancel some slice of it up to a cutoff. So the “real” commitment is the ordered quantity minus an expected cancellation buffer.

Reactive (at-once) demand is a forecast. It’s the opportunistic, fill-in-when-you-see-it ordering that happens during the season. You can’t commit inventory to it the way you can to pre-buy, but you don’t want to strand supply either — so it acts as a shock absorber for whatever the committed side doesn’t consume.

Now give both of them a single, shared pool of incoming supply — and make that supply arrive in waves rather than on day one. The question stops being “how do I split it” and becomes “how do I split it, right now, given what’s landed so far, what’s already committed, and what might yet cancel.” That’s a control problem, not an arithmetic one.

Why a spreadsheet lies

You can absolutely model the end state in a spreadsheet. What you can’t model is the path — and the path is where the decisions live.

A cancellation buffer that frees up units only after a cutoff. A supply wave that lands three ticks late and turns a comfortable position into a shortfall for exactly that window. Shrinkage quietly eating the safety margin you thought you had. Fulfilment draining the committed pool while the reactive pool sits full. Each of these is a second-order effect, and a spreadsheet shows you none of them — it shows you the average, after everything has already happened.

A simulation shows you the shape. You watch the committed pool get reserved first, the reactive pool fill with the remainder, a wave land and change the answer, a cancellation free units that shift from reserved to available. You feel which decisions are fragile and which are robust, because you can see them wobble.

What the model actually does

The simulation runs on a tick engine — press play and time moves, or step it one tick at a time to inspect a moment. At its centre is an OMS-style “control layer” doing two jobs on every tick:

  • Segmentation — deciding, from current on-hand inventory, how much to reserve for committed pre-buy demand versus how much to make visible to reactive at-once demand. Committed gets priority; the reactive pool gets what’s left.
  • Allocation — splitting each pool further: the committed pool across partners by their share, the reactive pool across programs by theirs, using a remainder-to-largest algorithm so no units are lost to rounding.

Around that core, the things that make it feel real: inbound supply scheduled as waves at specific ticks, a cancellation buffer that releases committed units after the cutoff, shrinkage, fulfilment drain, and a manual override so a planner can shove units from reserved to visible and immediately see the downstream cost. It periodically snapshots what each channel “saw,” so you can review the season after the fact — the same way a real control plane publishes a periodic view to its downstream systems.

You set the inputs — demand, allocation percentages, the cancellation buffer, the supply waves — and then you watch the system respond. Nothing is hard-coded to come out clean; you can absolutely configure a scenario that runs short, and the point is to see when and why it does.

Why build it at all

Two reasons, and they’re the whole argument for simulations as a thinking tool.

The first is that it made the decision legible to me. I built it to drive a real set of choices, and reasoning about them in a running model surfaced things — timing sensitivities, the true cost of a generous cancellation buffer — that a table of numbers had been hiding. Building the model was the analysis.

The second is that it’s legible to everyone else, too. A spreadsheet is a private argument; a simulation is a shared one. Anyone can open this, change an assumption, and watch it play out — no setup, no walkthrough, no “trust me.” That’s a far better way to align a room than a static deck, and it’s the reason I’m putting it out rather than leaving it on my machine.

Run it yourself → the simulation is live here. Set a scenario, press play, and watch an inventory control plane make its decisions one tick at a time.

I’m Nirat — I build at the intersection of product and systems. This is one of the things I make to think with; more at niratpatel.com.