Inspiration

Live auctions look simple until you try to make them correct.

A hundred people can watch the same item. Thousands can hit "Bid" in the same second. Every bid changes the price everyone else sees. Money is on the line, trust is on the line, and the rules are unforgiving: two bidders must never both win, the price must never move backward, and the last valid bid before the clock expires must count.

That is the distributed data problem hiding inside live commerce.

Most auction demos focus on the UI and quietly avoid the hard part: the single contested piece of state that every bidder is racing to update. We built GavelLive to put that hard part in the center of the product. Not "eventually correct." Not "probably fine." Correct under real concurrent writes, proven against the live database, on screen.

What It Does

GavelLive is a real-time marketplace for timed live auctions.

A buyer opens an auction, watches the current high bid and countdown update, places a bid, and immediately learns whether they are now winning or whether the bid was rejected. If a bid lands in the final seconds, anti-snipe logic extends the auction so the sale ends fairly instead of rewarding latency. When the clock runs out, the system finalizes exactly one winner from the database source of truth.

Under the hood, every bid is processed as a serializable transaction on Amazon Aurora DSQL:

read the auction snapshot -> validate that the auction is live -> check the minimum bid -> insert the bid -> update the high bidder -> extend the clock if needed -> commit.

If two users bid at the same time, Aurora DSQL's optimistic concurrency control aborts any commit that would break serializability. GavelLive catches that conflict, re-reads the new price, and retries with jittered backoff. Business failures like "bid too low" or "auction ended" return immediately. Real concurrency conflicts retry. The result is a price that only moves up and exactly one winner.

Who It's For

GavelLive is for sellers running high-demand timed sales and buyers competing for scarce items: collectibles, watches, sneakers, art, jewelry, rare books, liquidation lots, charity auctions, and live-drop commerce.

For sellers, correctness is revenue. A lost bid is lost money. A duplicate winner is a support nightmare. A broken auction damages trust.

For buyers, correctness is fairness. If they placed the highest valid bid before time expired, they should win. If someone else beat them, they should know immediately.

The marketplace model is straightforward: seller fees, buyer premiums, featured listings, and premium seller tools. This is not just a database demo wrapped in an auction skin. It is a real marketplace business where the database guarantee is the product moat.

Why It Matters

Live commerce is becoming one of the internet's most exciting shopping formats: fast, social, competitive, and global. But as soon as a live auction gets popular, the hardest problem is no longer rendering the page. It is preserving truth under pressure.

Naive auction systems fail in subtle ways:

  • Two concurrent bids both believe they won.
  • A lower bid overwrites a higher bid.
  • A bid accepted by the API never appears in the final result.
  • The auction closes while a valid last-second bid is still racing through the system.
  • The UI looks real-time, but the source of truth is inconsistent.

GavelLive is built around the opposite principle: the shared state must be correct first. The UI, marketplace, and scale-out architecture all sit on top of that guarantee.

That is why the demo includes a concurrency proof. We do not just say the system handles races. We fire hundreds of simultaneous bids at the live endpoint, then verify the invariants directly against Aurora DSQL.

How We Built It

  • Frontend: Next.js App Router with a hand-built auction UI, deployed on Vercel.
  • Primary database: Amazon Aurora DSQL as the source of truth for users, auctions, and bids.
  • Auth to database: Short-lived IAM auth tokens from Vercel serverless functions. No static database password.
  • Bid engine: A serializable transaction in lib/bids.ts with optimistic-concurrency retry handling.
  • Anti-snipe logic: Last-second bids extend ends_at inside the same transaction that accepts the bid.
  • Winner finalization: Lazy close-on-read with an atomic conditional update, so auctions finalize safely when the clock expires.
  • Proof harness: A load test that sends hundreds of concurrent bids to the live API and verifies the final database state.

The core bid flow is:

BEGIN
  read auction snapshot
  validate auction is live and not ended
  validate amount >= current high bid + increment
  insert bid
  update current high bid and bidder
  extend ends_at if inside anti-snipe window
COMMIT

Aurora DSQL uses optimistic concurrency control. When two bids race, conflicting commits return SQLSTATE 40001. GavelLive treats that as a real database-level signal: rollback, backoff, re-read, retry. The retry loop is carefully scoped so contention retries, while normal business rejections do not.

Proven, Not Claimed

We ran 300 concurrent bids against the live API on real Amazon Aurora DSQL.

Invariant Result
No lost or duplicate writes: bid rows match accepted responses Passed
Final price equals the highest accepted bid Passed
Exactly one winner, and it is the top bidder Passed
OCC contention actually occurred 414 retry attempts, max 4 on one bid

This is the heart of GavelLive: the database does not merely store auction data. It enforces the rules that make the marketplace trustworthy.

AWS Databases Used

Amazon Aurora DSQL is the primary database and source of truth for users, auctions, and bids.

We chose Aurora DSQL because the core problem is not generic storage. It is strongly consistent concurrent writes to one contested piece of state. Aurora DSQL gives us serializable transactions and optimistic concurrency control, which are exactly the primitives needed to prove that a live auction stays correct under bid races.

Challenges

Aurora DSQL is powerful, but it is not "just Postgres." It is a PostgreSQL-compatible subset, so we had to design around constraints like no foreign key enforcement. We use UUID keys and application-level integrity checks where needed.

Generating short-lived IAM auth tokens from Vercel serverless functions also took care. The app opens short-lived database connections, avoids static passwords, and keeps the database boundary server-side.

The hardest part was the retry loop. It needed to distinguish between real OCC conflicts, which should retry, and business rejections, which should return immediately. Getting that boundary right is what makes the system both correct and responsive.

What's Next

  • Replace polling with real-time push using DynamoDB Streams, Lambda fanout, and API Gateway WebSockets.
  • Add multi-region active-active Aurora DSQL so bidders in different regions compete against one globally consistent price.
  • Add Clerk authentication, seller dashboards, payment capture, invoices, reserve prices, watchlists, and email notifications.
  • Expand the proof harness into a public "auction chaos test" panel where judges and users can trigger the concurrency test from the UI.

Built With

Next.js · Vercel · Amazon Aurora DSQL · TypeScript · node-postgres · AWS SDK · Tailwind CSS

Disclaimer

All images used in this project are royalty-free demo assets, including product images sourced from Unsplash. Listings, users, bids, and auction lots are sample data for demonstration purposes only.

Built With

  • amazon-aurora-dsql
  • aws-sdk
  • next.js
  • node-postgres
  • tailwind-css
  • typescript
  • vercel
Share this project:

Updates