Skip to main content
Back to the matrix Architecting a Flash-Sale System for 100M+ Concurrent Users: Static/Dynamic Split, Atomic Redis Lua Deduction and Queue-Based Load Shedding
Distributed DB Difficulty: Architect 16 min deep read

Architecting a Flash-Sale System for 100M+ Concurrent Users: Static/Dynamic Split, Atomic Redis Lua Deduction and Queue-Based Load Shedding

Layered cache defenses under a million-QPS load test: oversell prevention, bot filtering, distributed IDs and end-to-end circuit breaking

AI Neural Reading Engine — Core Summary & Key Breakthroughs
1

Static/dynamic separation with CDN edge caching: 95% of the flash-sale page is static and served entirely from the CDN, with dynamic data pulled on demand through async endpoints.

2

An atomic Lua script in Redis issues tokens and pre-deducts stock in one step, letting a single node absorb 150,000+ QPS at peak.

3

Inventory bucketing (sub-inventory) splits one product's hot row lock across 16~32 sub-inventories, breaking through the single-row MySQL update ceiling.

4

RocketMQ transactional messages plus an idempotency table guarantee that service failures and retries never cause a double deduction or an undersell.

System architecture topology & data pipelines
01 // Static Resource Caching
CDN Edge Layer
Edge Nodes (90% Filter)
02 // Token Bucket Sentinel
Gateway Rate Limiter
Sliding Window 200k/s
03 // Atomic Pre-Deduct
Redis Lua Cluster
Zero-Lock Memory Engine
04 // Async Traffic Shaping
RocketMQ Cluster
Transaction Message Queue
Measured benchmark resultsQPS throughput

Measured QPS for concurrent flash-sale deductions (higher is better)

Direct MySQL (Hot Row)1200 QPS throughput
Redis Standard Lock34000 QPS throughput
Redis Lua Atomic (Sub-bucket)210000 QPS throughput

#01 1. What a Flash Sale Really Is, and Its Four Fatal Flaws

The defining challenge of a flash sale is extreme, instantaneous read/write skew. In the few seconds after the sale opens, millions of users fire order requests concurrently, all hammering a single database row.

Send that straight at MySQL and, connection pool or not, database CPU pegs at 100% within 50ms, connections are exhausted, and every service on the site cascades into failure.


#02 2. A Seven-Layer Traffic Funnel

We filter and reject in layers:

  1. Client layer: a greyed-out button with a countdown, debounce control, and staggered CAPTCHA;
  2. CDN edge nodes: fully cached static pages, blocking 90% of page traffic from ever reaching origin;
  3. API gateway (Kong / Envoy): IP/token allowlists and denylists plus sliding-window rate limiting;
  4. Distributed cache (Redis Cluster): atomic Lua deduction, letting only valid requests through;
  5. Async message queue (RocketMQ): writes to MySQL asynchronously at a steady rate.
Operator-level prototyping & sandbox test bench
-- Redis Lua script: atomic stock pre-deduction with duplicate-order protection
local stockKey = KEYS[1]
local userOrderKey = KEYS[2]
local userId = ARGV[1]
local quantity = tonumber(ARGV[2])

-- 1. Has this user already ordered?
if redis.call('SISMEMBER', userOrderKey, userId) == 1 then
    return -1 -- Already ordered; block the duplicate
end

-- 2. Check remaining stock
local currentStock = tonumber(redis.call('GET', stockKey) or '0')
if currentStock < quantity then
    return 0 -- Out of stock
end

-- 3. Deduct atomically and record the user
redis.call('DECRBY', stockKey, quantity)
redis.call('SADD', userOrderKey, userId)
return 1 -- Deduction succeeded

đź’ˇ Notes:Running the whole sequence inside Redis's single-threaded engine makes it atomic, so concurrent requests can never oversell.

ENVIRONMENT: JIT ISOLATED CONTAINER (simulated — not real hardware execution)
Thanks for reading and for the support — every tip lights up another node in the compute topology!
Deep-Read Discussion (0)