Your Inventory Software Probably Double-Books Across Date Ranges

May 7, 202611 min readBusinessERPInventory

A rental business owner once described the call he dreads most. It is mid-afternoon. A site coordinator is halfway through setup at a wedding venue. The truck arrived empty of one item. The system said it was available. It wasn't. The same unit had gone out two days earlier on a different booking that ends today, and the software let both reservations through.

He has seven customers booked over the next month with similarly tight handoffs. He doesn't know which of them is going to be the next phone call.

This is the quietest bug in inventory software. It doesn't crash anything. Nothing turns red on a dashboard. The numbers in your reports look fine. You only learn it happened when a customer is standing in a half-built tent looking at you.

I wrote about this briefly in Five Ways Business Software Quietly Loses Your Data. This post goes deeper — into why date-range inventory is hard to get right, what the bug actually looks like inside the software, and what to ask a vendor to find out whether their system has it.

What customers think "available" means

When a customer asks "is it available April 17 to 21?", they mean: I will physically have this item in my possession from the morning of the 17th until the evening of the 21st. Nobody else can have it during those days.

Software has to translate that into a yes or no. The translation is where things go wrong.

The simplest version of the translation — and the version most off-the-shelf inventory tools use — works like this. The system keeps a count of how many of an item it owns. It compares that count to the number "currently out." If the new request fits, the system says yes.

This works perfectly for inventory you sell or check out indefinitely. It falls apart the moment reservations have a start and an end.

Why a running count fails for date-range bookings

A running count tells you what's available right now. It cannot tell you what's available between two future dates, because nothing in the count knows about time.

To handle dates, most systems add a second mechanism: an overlap check. They look at every existing reservation and ask, "does this requested range overlap with any of them?" If yes, deduct the overlapping quantity. If no, the item is free.

This sounds correct. It even works correctly most of the time. The trap is in the word "overlap."

Consider three reservations on a single unit:

  • Reservation A: April 17 – 21
  • Reservation B: April 21 – 25
  • Reservation C: requested April 21 – 22

Reservations A and B overlap on exactly one day: April 21. Some systems will count that as "they don't really conflict" and let both stand. Some will count A as free by April 21 (because that's the end date) and B as starting on April 21 (so it claims the unit). And then reservation C asks about April 21 — both A and B are technically still associated with that day, but the simple overlap check sees A as ending and B as beginning, and concludes the unit is free for C too.

You now have three reservations on one physical unit, all "valid" according to the software, all claiming the same day.

The customer's mental model is simple: if you handed it to me on the 17th and I'm bringing it back on the 21st, then on the 21st I have it. The software's mental model has rounded that day off as a transition. They are not the same thing.

The right model is a timeline, not a count

The way to fix this is to stop modelling availability as a number, and start modelling it as a timeline.

For every requested date range, the system pulls every active reservation that overlaps with that range — even by one day. Then it walks through the timeline, day by day, and counts how many of the item are concurrently reserved on each day. The peak across that timeline is the maximum number that any day in the range demands.

If you own twelve units and the peak demand across the requested range is ten, three units are available. If the peak is twelve, none are. If the peak is thirteen — which is what happens when the math is wrong — the system has just told someone yes when the answer is no.

The technical name for this is a sweep. You imagine each reservation as two events on a calendar: a "start" event and an "end" event. You walk the timeline forward, incrementing a counter on every start and decrementing it on every end. The highest the counter gets is the peak.

This is the right shape of the calculation. But there is one rule about how you walk the timeline that decides whether the math is correct or quietly wrong.

The rule that decides whether you double-book

Look at reservations A and B again. A ends on April 21. B starts on April 21. On April 21, how many copies of the item are in use?

The answer is two — one is still with the A customer (they return it that evening) and one is going out to the B customer (they collect it that day). On April 21, you need two of the item, not one.

The way you walk the timeline has to reflect this. When a start event and an end event share the same day, the start event must be processed first. You increment for B before you decrement for A. The peak counter on April 21 reads two, and the system correctly tells reservation C that the item is not available on April 21.

Reverse the order — process the end event first — and the counter dips back to one before B comes in. The peak reads one, and the system happily double-books.

This sounds like a tiny ordering detail. It is. It is also the difference between "this software is correct" and "this software has a quiet bug that surfaces every two or three months as a customer complaint."

In our own ERP, this is a load-bearing rule. The line in the system map that documents it is short and slightly grim: any refactor of this sweep must preserve this ordering.

A regression we caught — and what it taught us

We had this rule from the start. We even had tests for it. Then in April, during an unrelated refactor of the availability code, the ordering rule got accidentally inverted. Same-day boundary reservations started being treated as non-overlapping. The tests we had didn't cover that exact ordering case — they covered overlapping ranges, but not the boundary edge.

It ran in production for about a week.

We caught it because two reservations on a single high-demand unit overlapped on a boundary day, and the operations team noticed when the dispatch list showed the same serial number against two different events. By that point a handful of bookings had been accepted on bad availability. We had to manually rework them.

Two things came out of that incident. First, the regression test we should have had — explicitly checking same-day boundaries with both orderings — went into the suite. Second, we wrote the ordering rule into the system documentation in plain English, so anyone touching that code in the future knows it isn't a stylistic choice. It's the rule. Refactor around it.

The reason I'm telling you this is not to advertise that we had a bug. It's to make a point: this bug exists in lots of inventory software, and most of those teams will never know it's there because they don't have the customer base or the operational discipline to surface it. Boundary-day double-booking is the kind of thing that happens once every few months and gets blamed on "human error" or "the salesperson messed up." It usually wasn't.

The places this bug hides that nobody talks about

Boundary-day overlap is the most common form, but it isn't the only one. A few others worth knowing about:

Cancellations that don't free inventory. When a reservation is cancelled or an order is deleted, the system needs to release the inventory it was holding. If the release path runs separately from the cancellation — even by a few seconds — there's a window where another booking can come in and miscalculate availability. The fix is to make cancellation and release a single atomic operation. Either both happen or neither does.

Reservations created without the order. Some systems create the order first, then create the reservations in a separate step. If the second step fails — server hiccup, network blip — you end up with an order that has no reservations attached. The system thinks the inventory is free; the order is real and will be dispatched. Same outcome as double-booking, different root cause. The fix is the same atomic principle: order and reservations are a single transaction or nothing happens.

Items in repair counted as available. If your inventory software lumps "broken" and "in repair" into the same available pool as working units, you can quote ten when you only have eight working. The right structure is four separate states per item — available, in use, in repair, broken — with a hard rule that those four numbers always sum to the total quantity, no exceptions.

Multi-branch reservations. If you have stock at two warehouses and a reservation is allowed to draw from "either," the availability math has to be branch-aware. Otherwise customer A reserves the Mumbai unit, customer B reserves the Pune unit, and on dispatch day the system realises they were supposed to be the same unit. Less common, but I've seen it happen.

What to ask before you buy

The fastest way to test for this is to set up two test reservations and ask the system a third question:

"I reserved unit X for April 17 to 21. I reserved another unit X for April 21 to 25. Show me availability for April 21 to 22."

If the answer says one unit is available, the software has the bug. There is no version of correct math that ends with one unit available on April 21 — both your existing reservations are using a unit that day.

A few related questions for a vendor:

  • How does your system handle the case where a reservation ends on the same day another begins? They should be able to answer in plain English. "Both reservations are treated as using the item that day" is the right answer. "The system optimises for one of them" is a soft yes to the bug.
  • If a reservation is cancelled, when is the inventory released? The right answer is "immediately, in the same transaction." If it's "shortly after" or "during the next sync," there's a race window.
  • What states can a unit be in? Look for at least available, in use, in repair, broken — not just "available" and "out."
  • Can I see how availability is calculated? A vendor confident in their math will explain the timeline-sweep model in two sentences. A vendor who hand-waves is either hiding it or doesn't know.

The deeper problem

Date-range inventory is one of those problems that looks simple from the outside and turns out to have a load-bearing detail buried five layers down. The detail in this case is one line about how to order events on a timeline. Get it right and the system is correct forever. Get it wrong and the bug shows up months later as a phone call from a venue.

Most software, including most expensive software, isn't tested at the boundary. It's tested at the middle. Two reservations that don't overlap pass. Two reservations that fully overlap pass. The case where they touch on a single day — the case where customers actually live, because real bookings end and begin every day of the week — is the one that quietly fails.

If you operate a rental business, an event-equipment business, a supplier of date-bounded resources of any kind, this is the bug to ask about. It is also a fair test of whether the team that built the software has actually run the kind of business that uses it. The teams that have don't make this mistake. The teams that haven't almost always do.

If you'd like to talk about a specific availability problem in your own system — or an apology call you don't want to make again — I'm happy to take a look. I've debugged this in production.

Next Step

Thinking about custom software for your business?

If something you just read hit close to home, let's talk. I'll respond within 24 hours with an honest assessment of whether custom is the right call.

Tell me about your challenge