Prasoon AI
ServicesInsights
Let’s talk
GOOD IDEAS DESERVE GREAT ENGINEERING.Explore the possibilities.

WHAT I BUILD

AI systems

Agents, private knowledge, and production AI.

SaaS platforms

Scalable software, from first release to growth.

HOW WE WORK

Services

Engineering expertise for your next challenge.

Industries

Solutions grounded in your business context.

IDEAS & PERSPECTIVES

Insights

Practical thinking on AI and architecture.

About my approach

Bridging research and production.

Available for select projectsDiscuss your project
All insights/Transaction Design

Transaction Design / Practical engineering

Inventory Reservations: Preventing Overselling Under Concurrency

Protect scarce inventory with atomic predicates, durable reservation identities, controlled expiry, and explicit handling of payment outcomes that arrive late.

P.
Prasoon ThakurAI systems architect
September 20, 20264 min read
THE ENGINEERING SERIESTransaction Design
RESERVATION / ILLUSTRATIONOne item. One winner.
Request AReserved
Request BUnavailable
Atomic stock decision1 → 0
Transaction DesignIdeas, connected to implementation.
In this article6 sectionsContents +
  1. 01The invariant belongs in the write operation
  2. 02Reserve with an atomic conditional update
  3. 03Commit the reservation and stock change together
  4. 04Expiry is a competing state transition
  5. 05Keep remote payment calls outside inventory locks
  6. 06Test with barriers, not just parallel requests

The invariant belongs in the write operation

Two customers see one remaining item. Both submit checkout. If each request reads availability and later subtracts one, both can succeed. A faster server does not fix the race; it changes how often the race occurs.

Choose a precise invariant: available stock cannot become negative, and every successful reservation has a unique durable identity. The architecture in this article assumes one authoritative database for a SKU and location. A globally distributed inventory service needs an additional allocation or consensus design; this single-database pattern does not create global serialization.

Reserve with an atomic conditional update

The request should carry a stable operation ID, authenticated account context, SKU, location, and positive quantity. Validate bounds and authorization before attempting the transaction. Scope the operation ID to the account and reject reuse with different parameters.

System Source
UPDATE inventory
SET available = available - $3
WHERE sku_id = $1
  AND location_id = $2
  AND available >= $3
RETURNING available;

One returned row means the update won under the predicate; no row means no matching eligible inventory. A database check constraint on nonnegative availability provides a second line of defense. The application must distinguish an unavailable SKU from an authorization failure without leaking restricted inventory.

Under PostgreSQL Read Committed, a concurrent updater waits for the competing update and rechecks its condition against the updated row. That behavior supports this single-row conditional decrement. It does not make arbitrary multi-row read-then-write logic serializable. PostgreSQL isolation behavior

Commit the reservation and stock change together

In the same transaction, establish the request's idempotency record, perform the decrement, and insert the reservation with its expiry and parameter fingerprint. On duplicate request identity, return the original outcome. A unique constraint must arbitrate concurrent submissions; an application-level existence check is insufficient.

If the reservation insert fails, roll back the decrement. If the transaction commits and the response is lost, the client can safely retry the same operation ID. Persist the decision long enough to cover the business retry window.

For a basket containing several items, acquire inventory locks in a consistent order such as location plus SKU. PostgreSQL row locks block competing writers until transaction completion; inconsistent lock order can create deadlocks. Keep transactions short and retry the entire transaction when the database reports a retryable conflict. PostgreSQL explicit locking

Expiry is a competing state transition

A background sweeper and a payment callback can race for the same reservation. Both must lock or conditionally update its state. Only the worker that changes held to expired may return stock. Only a permitted transition can consume the hold.

Current stateRequested transitionStock consequence
HeldConfirmHold becomes a committed allocation
HeldExpireReturn reserved quantity exactly once
HeldCancelReturn reserved quantity exactly once
ConfirmedExpireReject; the hold has already been consumed
ExpiredConfirmEnter recovery policy; do not assume stock exists

Use the database's time consistently for expiry decisions. Define whether confirmation requires the hold to be unexpired at the moment of transition. A sweeper running late should not silently extend the contractual reservation window.

The state transition and stock return belong in one transaction. Repeated expiry jobs should observe an already expired reservation and do nothing. Deleting the reservation immediately would erase the evidence that prevents a second return.

Keep remote payment calls outside inventory locks

Reserve locally, commit, and then initiate payment with a stable provider operation key. Record uncertain payment outcomes rather than assuming a timeout means failure. A callback or reconciliation job can later complete the workflow.

Payment and inventory do not share an atomic transaction. Design compensation deliberately: release an unused hold, reacquire stock if policy permits, or refund a payment that cannot be fulfilled. Each compensation needs its own identity and state, because compensation requests can also time out or be retried.

Expose these states honestly to the customer. “Payment received; confirming availability” may be appropriate in a recovery case. A generic success screen should not promise fulfillment before the system has established it.

Test with barriers, not just parallel requests

Use a concurrency test that pauses two transactions immediately before the critical write, then releases them together. With one item available, assert that only one reservation commits and the stock never becomes negative.

Repeat the test for confirmation against expiry, duplicate checkout IDs, reversed lock order, worker crashes, and payment confirmation after expiry. Reconcile the stock ledger against active reservations and committed allocations. Measure conflict rate and lock wait time alongside successful checkout latency; rising contention is a capacity signal even while correctness holds.

Frequently asked questions

Can a cache determine whether the final item is available?

A cache may guide the interface, but the authoritative reservation must be decided atomically in the system of record. Cached counts can be stale.

What happens if payment succeeds after a reservation expires?

The workflow must reconcile the payment against current reservation state. Depending on the business policy, it may reserve again, offer an alternative, or initiate a compensating refund. It must not silently promise unavailable inventory.

About the author

Prasoon Thakur

Prasoon is an AI systems architect focused on reliable agents, retrieval, LLM operations, and scalable SaaS platforms. His work connects model behavior to the controls production teams need: evaluation, observability, security, and cost discipline.

GitHubUpwork profile

Need a reliable production system?

Turn the patterns in this guide into a scoped system design, delivery plan, and measurable reliability target.

Start a strategy session

Related insights

API Engineering

Cursor Pagination Under Concurrent Writes: A Consistency Contract

4 min read
Database Engineering

Live PostgreSQL Migrations: Expand, Backfill, Verify, Contract

5 min read

Active Now • 24/7 Availability

Engaging with teams
from Silicon Valley to Singapore.

I operate as a high-availability resource. To maintain secure collaboration, all global engagements are managed via Upwork.

Discuss your project Direct collaboration through Upwork.

Global / Remote

24/7 Timezone Agnostic

Syncing with USA, Europe, UAE & Singapore

Secure Engagement

Top Rated Expert on Upwork

Prasoon AI

Thoughtful architecture.
Software built for the real world.

Based online. Working worldwide.

Explore

AI systemsSaaS platformsServicesIndustries

Discover

Engineering insightsMy approach

Connect

Upwork GitHub Open to project inquiries

© 2026 Prasoon Thakur

Independent thinking. Dependable engineering.Back to top ↑