Start a project
All articles
Backend Engineering··5 min read

Preventing Oversells in Flash Sales with Redis Atomic Reservations

How to guarantee you never sell the 101st unit of a 100-unit flash deal, using Redis atomic operations and TTL-based reservations instead of database locks.

RedisBackendConcurrencyNode.js

Flash sales break naive inventory systems. When 5,000 people hit 'buy' on 100 units in the same second, a read-then-write against your database will happily let hundreds of them through. The fix is to make the reservation a single atomic operation.

Why the database check fails

The classic bug is a race condition: two requests both read stock = 1, both decide they can proceed, and both decrement. Row locks can help but they serialize your hottest path and fall over under real load. Redis does this better because a single-threaded in-memory decrement is atomic by nature.

// Atomic reserve: DECR only succeeds if stock remains >= 0
const remaining = await redis.decr(`stock:${productId}`);
if (remaining < 0) {
  await redis.incr(`stock:${productId}`); // give it back
  throw new Error("Sold out");
}
// Hold the unit for 10 minutes; auto-releases if unpaid
await redis.set(`hold:${productId}:${userId}`, "1", "EX", 600);

Auto-releasing abandoned carts

A reservation that never expires leaks inventory. Set a TTL on each hold and subscribe to Redis keyspace notifications, when a hold key expires, an event fires and you return the unit to the pool. No cron sweep, no stale locks, no manual cleanup.

  • DECR/INCR give you overselling-proof reservations with no locks.
  • TTL + keyspace notifications release abandoned holds automatically.
  • Persist the confirmed order to your primary database once payment clears.

I built exactly this pattern into a flash-sale reservation API, Express, Redis, MongoDB, all containerized. It handles the concurrency that would sink a database-only approach.

Want this built into your product?

I take on freelance work across AI, voice, backend and full-stack. Tell me what you're building.

Start a project