An inventory reservation system protects a commercial promise while multiple stores, marketplaces, service agents, and fulfillment locations compete for limited stock. It does not make physical inventory perfectly real time. Instead, it defines which quantity is authoritative for each decision, atomically creates and transitions holds, bounds their lifetime, and continuously reconciles commercial commitments with warehouse and store events. Overselling becomes a controlled risk with measurable causes rather than a mysterious checkout failure.
The central design mistake is treating one quantity field as on-hand, sellable, reserved, allocated, picked, and available. Those values answer different questions and change at different moments. The second mistake is coupling reservation to a fragile request without idempotency or compensation. A dependable model uses a ledger or equally auditable state transitions, stable order and reservation identity, optimistic or serialized concurrency control, explicit expiry, and channel policy built on a conservative available-to-promise calculation.
Define on-hand, reserved, allocated, and available-to-promise quantities
Create a vocabulary with owners and event triggers. On-hand is a physical or book quantity at a location. Reserved is committed commercially but not yet consumed by a shipment or other terminal event. Allocated identifies the source expected to fulfill. Picked and shipped are warehouse execution states. Safety stock is deliberately withheld. Available to promise, or ATP, is a policy result derived from appropriate supply minus commitments and buffers, adjusted for channel, location, horizon, confidence, and business rules. It is not necessarily the raw warehouse balance.
Define whether stock is tracked by SKU, lot, serial, condition, owner, location, and fulfillment network. A global ATP can hide that stock is in the wrong country or store. A location-specific promise can strand supply if rebalancing is possible. Separate commercial reservation from source selection: at order time the business may promise from a pool, then choose the shipping location later. Adobe Commerce’s current inventory documentation similarly distinguishes salable quantity, append-only reservation operations, and source selection during shipment.
| Quantity or state | Business meaning | Changed by | Must not be confused with |
|---|---|---|---|
| On-hand | Recorded physical stock at a source | Receipt, adjustment, shipment, count, return | Immediately sellable stock |
| Safety stock | Buffer withheld by policy | Planning or risk policy | A customer reservation |
| Reserved | Commercial commitment awaiting completion or release | Order/hold state transitions | Physical deduction |
| Allocated | Selected source and quantity for fulfillment | Order management or source-selection process | Picked or shipped quantity |
| Available to promise | Quantity the channel may promise under policy | Derived calculation or materialized projection | Raw on-hand total |
| In transit / expected | Supply moving or planned with confidence and date | Purchase, transfer, or production events | Current physical availability |
Choose when to reserve and how long the promise lasts
Reservation at add-to-cart protects scarce stock early but lets abandoned carts suppress sales and invites abuse. Reservation at checkout start shortens the hold but still precedes payment. Reservation at order submission maximizes sellable availability yet creates a race late in the funnel. Payment-first can capture funds for unavailable stock unless authorization and reservation are coordinated. Choose by scarcity, checkout duration, payment method, customer expectation, replenishment, and channel behavior. Different products may need different policy tiers.
Every temporary hold needs an owner, purpose, quantity, scope, creation time, expiry time, state, and idempotency key. Use server time and a durable expiry mechanism. Do not rely solely on a delayed job firing exactly on schedule; availability calculation should treat an expired hold as unavailable for transition and eligible for release according to a consistent rule. Define extension conditions for payment authentication or customer service, with a maximum lifetime and audit. Rate-limit or authenticate hold creation to prevent inventory denial attacks.
Make customer communication match the guarantee. A cart message should not imply stock is held when the system has made no reservation. A countdown should reflect server authority and accessibility needs, and it should not be extended through client manipulation. When a hold expires, preserve cart context and offer alternatives rather than failing at payment without explanation. For high-value scarce goods, consider queueing, purchase limits, buyer verification, and bot controls alongside reservation design.
Make reservation creation and transitions atomic and idempotent
The create operation must check eligible ATP and commit the hold as one concurrency-controlled decision. Options include a transaction with a version check, a per-stock-key serialized command stream, conditional writes, or an inventory service that owns the invariant. A read followed by an unrelated write permits two buyers to reserve the same last unit. Partitioning should keep competing decisions for the same stock key coordinated while allowing independent SKUs or pools to scale. Hot products may need sharded counters or admission control with reconciliation.
Use stable idempotency keys for create, confirm, cancel, expire, allocate, ship, and return operations. A retry should return the prior outcome, not add another reservation. Validate state transitions and quantities: confirmed cannot silently return to pending; shipment should offset the commitment once; partial cancel should release only the canceled amount. Append-only ledger entries, as documented in Adobe Commerce’s reservation model, provide strong auditability when compensating entries offset earlier reservations. A mutable state model can also work if every transition and version is durably recorded.
| Transition | Precondition | Inventory effect | Retry and failure rule |
|---|---|---|---|
| Create pending hold | Eligible ATP and valid product/channel policy | Decrease projected ATP by held quantity | Same key returns same hold; failed atomic check creates nothing |
| Confirm order | Pending unexpired hold matches order and amount | Keep commitment; bind durable order identity | Duplicate confirmation is no-op with same result |
| Allocate source | Confirmed commitment and eligible source supply | Assign fulfillment quantities; do not double-reserve | Version check; replan on conflict |
| Expire or cancel | Releasable unconsumed quantity | Offset reservation and increase ATP | One compensating transition per quantity |
| Ship | Allocated/picked quantity with shipment identity | Reduce on-hand and settle corresponding commitment | Duplicate shipment event cannot deduct twice |
| Return or adjustment | Verified receipt or approved correction | Increase appropriate condition/location balance | Separate event identity and reason; never edit history silently |
Coordinate reservation, payment, and order state without a distributed transaction
Most commerce systems cannot atomically commit inventory, payment provider state, and order database state in one transaction. Use an explicit saga. One pattern creates a short reservation, authorizes payment, confirms the order, then captures according to policy; failures void authorization and release the hold. Another creates an order in pending state and completes steps asynchronously. Choose sequence from payment-method behavior and business risk. Persist state before making an external call where needed, and record correlation and idempotency identifiers.
Define uncertain outcomes. A payment timeout may have succeeded remotely. Query by provider operation ID before retrying. An order-write failure after reservation confirmation needs recovery, not immediate release if payment succeeded. A message may be delivered more than once or out of order. Build repair states such as payment-unknown, reservation-confirmed-order-missing, and order-confirmed-allocation-pending. Route them to automated reconciliation first and a human queue with full business context when automation cannot decide safely.
Separate source allocation from channel availability policy
Channel ATP determines whether the business will promise. Source allocation decides where to fulfill based on stock, distance, split-shipment cost, capacity, cutoffs, hazmat or temperature requirements, store workload, and customer service level. Keeping them separate allows a pooled promise while delaying the best-source decision until address and operating conditions are known. However, the pool must be fulfillable; do not aggregate locations whose stock cannot legally or economically serve the channel.
Make fairness and priority explicit. Stores, marketplaces, subscriptions, wholesale orders, and customer service may share stock or receive quotas. Safety stock can vary by source and channel. During scarcity, decide whether priority follows order time, customer commitment, margin, service obligation, or protected allocation. Publish rules internally and record which policy version produced the promise. A hidden last-writer-wins race creates inconsistent customer treatment and makes incident review impossible.
Reconcile reservation ledgers, orders, events, and physical stock
Build continuous invariants: no reservation exceeds its requested quantity; terminal orders have no unexplained active hold; shipped quantities offset commitments exactly once; expired holds are not confirmable; ATP does not exceed policy supply; and every external event has a processing outcome. Compare inventory service, order management, warehouse, store, marketplace, and payment records. GS1 EPCIS offers standard event concepts for what, when, where, why, and how across supply chains; it can inform visibility, though internal reservation semantics still need explicit design.
Use physical counts and warehouse adjustments as evidence, not as silent resets. Differences can result from shrink, damage, delayed events, unit conversion, wrong location, duplicate shipment, missed return, or reservation defect. Record reason, actor, source, and correlation for adjustments. Provide dashboards for oversell rate, reservation rejection, expiry, confirmation latency, stale holds, repair backlog, negative balances, reconciliation age, and lost sales from conservative buffers. Tune policy from observed error and service outcomes rather than maximizing nominal availability.
Test contention, time, and failure before peak demand
Test two and many buyers competing for the final units, duplicate requests, reordered messages, delayed expiry, clock differences, partial quantities, split fulfillment, payment timeout, provider success with local timeout, database failover, queue outage, stale read replicas, warehouse delay, returns, and manual adjustments. Load tests should include hot SKUs because uniform traffic hides lock and partition pressure. Verify invariants with deterministic histories as well as end-to-end journeys. Inject failure at each state transition and prove recovery.
Prepare peak controls: admission rate, queue depth, per-buyer limits, hold duration, buffer policy, source scope, monitoring thresholds, repair staffing, and a switch to more conservative ATP. Avoid emergency direct database edits. Rehearse release of an incorrectly large reservation and recovery from a stuck consumer. After the event, reconcile every commitment and review whether conservative controls caused avoidable lost sales. Reliability means preserving truthful promises under pressure, not accepting every cart action.
Key takeaways
- Define on-hand, safety stock, reserved, allocated, shipped, expected, and ATP as separate quantities and states.
- Choose reservation timing and expiry from scarcity, payment flow, abandonment, abuse, and customer promise.
- Atomically check and hold stock, and make every transition idempotent with auditable quantity effects.
- Coordinate payment and order through explicit saga and repair states rather than assuming a distributed transaction.
- Continuously reconcile commercial commitments, source events, and physical stock, then tune buffers from measured error.
FAQ
Should inventory be reserved when an item enters the cart?
Usually only for scarce products or a deliberate limited-time promise. Early holds improve certainty but increase abandonment loss and abuse risk. Many businesses reserve at checkout or order submission and communicate accurately that cart availability is not guaranteed.
What is a good reservation expiry time?
Long enough for the normal payment and checkout path at a measured percentile, plus bounded exception handling, but short enough to release abandoned demand. Set it by product and payment behavior, monitor extensions and expiry outcomes, and never rely on a universal duration.
Can a reservation system prevent all overselling?
It can protect concurrency within its authoritative scope, but physical shrink, delayed channel updates, manual adjustments, damaged stock, external marketplaces, and integration failures still create uncertainty. Buffers, event quality, reconciliation, and customer recovery complete the control.
Conclusion
Inventory reservations turn uncertain stock into bounded commercial promises. Clear quantity semantics establish what can be sold, atomic holds protect the last units, idempotent transitions survive retries, saga states coordinate payment and orders, and reconciliation connects digital commitments to physical movement. The result is not an illusion of perfect real time; it is an observable system that knows what it promised, why it promised it, and how to repair divergence before customers absorb it.