# The flash sale

> What happens when 50,000 people press "Buy" in the same ten seconds? Straight into Lambda, the spike meets scaling limits, 429s and an Aurora connection storm. With a Worker in front, Cloudflare absorbs it and AWS sees only the winners.

- A decision guide from The Stack by Nicolas Dao (Cloudless Labs, Sydney)
- Web page: https://cloudlesslabs.com/stack/guides/flash-sale/. The whole stack in one file: https://cloudlesslabs.com/stack/brief.md
- Tools: [Cloudflare Workers](https://cloudlesslabs.com/stack/cloudflare-workers/index.md) (My default), [Cloudflare Durable Objects](https://cloudlesslabs.com/stack/cloudflare-durable-objects/index.md) (Use when it fits), [AWS Lambda](https://cloudlesslabs.com/stack/aws-lambda/index.md) (My default), [Stripe](https://cloudlesslabs.com/stack/stripe/index.md) (My default)

**Scenario:** 2,000 concert tickets go on sale at 10:00. 50,000 people press "Buy" in the first 10 seconds: about 5,000 requests a second.

## Without Workers: CloudFront → API Gateway → Lambda → Aurora

| Second | What happens |
|---|---|
| 0–10 | Lambda adds at most 1,000 instances per 10 seconds per function, and the account default is 1,000 concurrent. Every new instance cold-starts. |
| 1+ | Requests over the limit get 429 errors. Users refresh, doubling the traffic. |
| 2+ | 1,000 Lambdas each open a Postgres connection: Aurora runs out. |
| 5+ | Two Lambdas both read "3 tickets left" and both sell one, unless every write is a careful conditional UPDATE. |
| Result | You raise limits weeks ahead, pre-warm, and still worry. |

AWS has a partial fix: API Gateway can write straight to SQS, which absorbs the spike. But users get "pending…" and must poll, and the 10,000 requests/s account limit still applies.

## With Workers

```
50,000 users ─▶ Worker (edge) ─▶ Ticket counters (20 Durable Objects × 100 tickets)
                  │                    │ "you got one" / "sold out" in ~50 ms
                  │                    ▼
                  │             only the 2,000 winners
                  ▼                    ▼
       cached page, bots blocked    AWS checkout: Lambda → Stripe → Postgres
```

1. **No ramp-up limit.** Workers start in milliseconds, at 0 or 50,000 requests a second.
2. **Junk stops at the edge.** Cached page, bots blocked, login tokens checked.
3. **Instant, honest answers.** Each counter is a Durable Object processing one request at a time: no overselling. Split 20 × 100 because each object handles about 1,000 requests a second.
4. **AWS sees 2,000 calm checkouts** instead of 50,000 panicked requests.

The cost of the burst is pennies everywhere. The difference is whether it survives.

## Related

- [A traffic spike I can see coming](https://cloudlesslabs.com/stack/use-cases/flash-sale.md): the use case this guide works through
- [Cloudflare Workers](https://cloudlesslabs.com/stack/cloudflare-workers/index.md): the full entry (verdict, pricing, gotchas)
- [Cloudflare Durable Objects](https://cloudlesslabs.com/stack/cloudflare-durable-objects/index.md): the full entry (verdict, pricing, gotchas)
- [AWS Lambda](https://cloudlesslabs.com/stack/aws-lambda/index.md): the full entry (verdict, pricing, gotchas)
- [Stripe](https://cloudlesslabs.com/stack/stripe/index.md): the full entry (verdict, pricing, gotchas)
- [Every decision guide](https://cloudlesslabs.com/stack/brief.md): listed at the end of the brief
- [Map of every Markdown file on cloudlesslabs.com, with what each one answers](https://ask.cloudlesslabs.com)
