Inspiration

In 2023, Taylor Swift's Ticketmaster presale collapsed under load. Seats were sold multiple times. It went to a US Senate hearing. The root cause wasn't incompetence — it was a database architecture problem that nobody had cleanly solved serverlessly.

When we discovered Aurora DSQL's active-active distributed SQL, we knew exactly what to build.

What it does

Encore is a flash-sale ticketing platform that makes overselling mathematically impossible.

  • Live seat map — real-time colour updates as seats are held and sold
  • 16-second seat hold — click a seat, hold it, checkout or lose it
  • Zero oversell guarantee — proven by chaos mode stress test
  • Waiting room — queue management for high-demand events
  • Chaos mode — judges can fire 10–100 simultaneous buyers and watch the OCC retry counter tick while oversell stays at 0

How we built it

Two databases. One principle — the hot path absorbs the spike, the system of record never lies.

Amazon DynamoDB handles seat holds. Every click fires a conditional write:

ConditionExpression: 
  "attribute_not_exists(event_id) AND attribute_not_exists(seat_id)"

Two buyers click simultaneously — exactly one wins. 18-second TTL auto-releases abandoned holds. No cleanup code needed.

Amazon Aurora DSQL handles checkout. Every purchase is a 5-step ACID transaction wrapped in an OCC retry loop:

$$\text{Transaction} = \text{read} \to \text{mark sold} \to \text{order} \to \text{ledger} \to \text{decrement}$$

If two buyers race to checkout the same seat, DSQL returns error 40001. Our retry catches it. One buyer completes. The other gets "seat already sold."

$$\text{Oversell count} = 0 \quad \forall \text{ concurrent buyers}$$

Vercel serves the Next.js frontend with Server-Sent Events pushing live seat status to every connected browser every second.

Challenges we ran into

IAM token auth — Aurora DSQL doesn't use static passwords. It uses IAM tokens that expire every 15 minutes. Error 08P01 ("invalid password packet size") cost us several hours before we found @aws-sdk/dsql-signer.

DynamoDB TTL lag — TTL deletion can take 1–5 minutes in practice. Seats stayed yellow long after holds expired. Fix: check expires_at manually in the SSE stream instead of waiting for DynamoDB to delete the row.

OCC thundering retries — naive retries under chaos mode caused all failed transactions to retry simultaneously, creating new conflicts. Exponential backoff $50 \times 2^n \text{ ms}$ solved it.

Accomplishments that we're proud of

Running the chaos mode stress test for the first time and seeing: Two databases, working exactly as designed, under real concurrent load. That number — 0 — is the whole point of the project.

We also built this as complete beginners to this stack. Neither of us had used Aurora DSQL or DynamoDB in production before. The entire backend — IAM auth, conditional writes, ACID transactions, OCC retry, SSE streaming — was new to us.

What we learned

  • Use the right database for the right job. DynamoDB for throughput, DSQL for correctness. Never the other way around.

  • TTL is for storage cleanup, not real-time state. Always check expires_at yourself.

  • OCC retries are a feature. 9 retries in chaos mode means the system caught 9 race conditions and resolved them correctly.

  • Aurora DSQL IAM auth is non-negotiable. @aws-sdk/dsql-signer. Read the docs first.

Built With

Share this project:

Updates