Designing a High‑Concurrency Flash‑Sale (Seckill) System: Key Techniques and Best Practices

This article explains how to design a high‑concurrency flash‑sale system by addressing instant traffic spikes, page static‑generation, CDN acceleration, button activation, read‑heavy/write‑light patterns, cache breakdown and penetration, inventory pre‑deduction, distributed locking, message‑queue handling, and multi‑level rate limiting.

Code Ape Tech Column
Code Ape Tech Column
Code Ape Tech Column
Designing a High‑Concurrency Flash‑Sale (Seckill) System: Key Techniques and Best Practices

Introduction

Designing a flash‑sale (seckill) system is a classic high‑concurrency interview problem that requires knowledge from front‑end to back‑end. A seckill event sells a limited number of items at a very low price, attracting massive traffic but only a few successful purchases.

1. Instant High Concurrency

Traffic surges sharply a few minutes before the scheduled seckill time and peaks at the exact moment, creating a short‑lived burst of requests. To handle this, consider page static‑generation, CDN acceleration, caching, asynchronous MQ processing, rate limiting, and distributed locks.

2. Page Static‑Generation

The activity page is the entry point with the highest request volume. Rendering the page as static HTML reduces server load; only when the user clicks the seckill button at the exact time does the request reach the back‑end.

3. CDN Acceleration

Deploying a Content Delivery Network (CDN) lets users fetch static resources from edge nodes close to them, lowering latency and network congestion.

4. Seckill Button Control

The button is greyed out before the start time and becomes clickable exactly at the seckill moment, usually controlled by a JavaScript file cached on the CDN. A random parameter forces the CDN to fetch the latest script when the event starts.

5. Read‑Heavy / Write‑Light Pattern

During a seckill, the system first checks inventory; if insufficient, it returns “sold out”. Because most requests find the stock insufficient, this is a typical read‑heavy scenario best served by a cache such as Redis.

6. Cache Issues

Cache breakdown occurs when many requests miss the cache and hit the database simultaneously. Solutions include pre‑warming the cache and using distributed locks. Cache penetration (requests for non‑existent IDs) can be mitigated with a Bloom filter or by caching negative results with a short TTL.

7. Inventory Management

Simple database stock decrement can cause overselling due to non‑atomic read‑modify‑write. Optimistic locking (adding stock > 0 to the UPDATE) reduces the risk but still puts pressure on the DB. Redis atomic INCRBY can be used, but naïve implementations still risk negative stock; a Lua script ensures atomicity.

StringBuilder lua = new StringBuilder();
lua.append("if (redis.call('exists', KEYS[1]) == 1) then");
lua.append("    local stock = tonumber(redis.call('get', KEYS[1]));");
lua.append("    if (stock == -1) then return 1; end;");
lua.append("    if (stock > 0) then redis.call('incrby', KEYS[1], -1); return stock; end;");
lua.append("    return 0; end; return -1;");

8. Distributed Lock

Redis can provide a distributed lock using SETNX (non‑atomic) or the atomic SET key value NX PX expire. The lock must be released only by its owner, typically using a request‑ID check or a Lua script for atomic check‑and‑delete.

if (jedis.get(lockKey).equals(requestId)) {
    jedis.del(lockKey);
    return true;
}
return false;

A spin‑lock repeatedly attempts to acquire the lock within a timeout, sleeping briefly between attempts.

9. MQ Asynchronous Processing

Separate order creation from the seckill request using a message queue. To avoid message loss, write a “message outbox” table before sending; retry failed sends with a scheduled job. Duplicate consumption is prevented by a “message processing” table with idempotent handling. Garbage messages are limited by capping retry attempts. Delayed queues (e.g., RocketMQ) handle order cancellation after a payment timeout.

10. Rate Limiting

To prevent bots from hammering the seckill API, apply rate limiting at multiple levels: per user, per IP, per endpoint, using Nginx or Redis. Captchas (including sliding‑puzzle captchas) add a human verification layer. Business‑level throttling (e.g., member‑only participation) can also reduce abusive traffic.

Conclusion

By combining static page delivery, CDN, caching, atomic stock operations, distributed locks, reliable MQ workflows, and layered rate limiting, a flash‑sale system can survive the extreme traffic spikes typical of seckill events.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

cachinghigh concurrencydistributed-lockflash sale
Code Ape Tech Column
Written by

Code Ape Tech Column

Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.