01Rate limiting02Databases03Caching04Flash sale05Idempotency06Circuit breaker07Queues & DLQ

Lab / 04 · Flash sale

Hundreds of buyers, ten items, one distributed lock.

When 100 buyers click 'Buy Now' at the exact same millisecond for 10 available items, a naive backend sells 30+ items because transactions read before other transactions commit. An atomic Redis Lua script ensures zero overselling.

LIVE · 10 Items Stock · Atomic Distributed Lock
Current Stock: 10 / 10
#1
#2
#3
#4
#5
#6
#7
#8
#9
#10
// Concurrency Audit Trail
Click either simulation button to execute concurrent purchases against the inventory.

On the live site, simulations fire real concurrent threads against Spring Boot using atomic Redis Lua scripts.

Concurrency: Naive vs Atomic Lock

Under naive execution, concurrent threads read stock > 0 simultaneously. With Redis Lua or SELECT FOR UPDATE, execution is serialized.

100 Buyers
Simultaneous clicks
Spring Boot Cluster
Multiple worker threads
Redis Lua / Lock
Atomic DECRBY
Inventory DB
Stock balance
Naive: 10 items in stock → 34 sold (-24 stock!) | Atomic Lock: Exactly 10 sold (0 oversold)

Atomic Stock Decrement in Lua

-- flash_sale.lua (executed atomically inside Redis single-thread engine) local current = tonumber(redis.call('GET', KEYS[1]) or 0) local requested = tonumber(ARGV[1]) if current >= requested then redis.call('DECRBY', KEYS[1], requested) return {1, current - requested} -- Success: allowed, remaining stock else return {0, current} -- Failed: out of stock, zero oversold end
Full source on GitHub →

Trade-offs I weighed

Redis Atomic Decrement vs Database SELECT FOR UPDATE

Pessimistic DB row locking saturates PostgreSQL connection pools at >1,000 req/s. Redis Lua handles 50,000+ atomic operations per second in memory, keeping DB write-behind queues manageable.

Distributed Lock (Redlock) vs Atomic Decrement

Acquiring a full distributed lock for inventory involves multiple network round-trips. An atomic DECRBY or Lua script achieves the same mutual exclusion in a single round-trip.

Inventory Reservation vs Immediate Charge

Reserving stock with a 5-minute TTL allows buyers to complete checkout while freeing up unpurchased stock automatically if payment is abandoned.

← ← 03 CachingNext: 05 Idempotent payments → →