-
-
Every limited drop is handed out by a fair random draw.
-
Enter the draw once, one entry per person, charged only if you win.
-
Built on Amazon Aurora DSQL: exactly-once allocation, strongly consistent across regions, and a verifiable draw.
-
Recompute the draw in your own browser. 100/100 winners reproduced, zero discrepancies.
-
Same 50,000-request stampede, two outcomes: a normal store oversells to 127/100; NoScalp holds at exactly 100 and fans win.
I got tired of losing to bots
In 2020 I tried to buy a PS5 over and over, and scalpers beat me to it every single time. Since then it's been the same story with sneakers, concert tickets, graphics cards, and basically anything in limited supply: it sells out in seconds, then reappears an hour later at triple the price. First-come-first-served doesn't reward the people who actually want the thing, it rewards whoever has the fastest bot. NoScalp is the store I wished existed.
What it does
NoScalp is a drops storefront where limited releases are handed out by a provably fair random draw instead of a checkout race.
- You enter a drop once. Everyone gets one entry, and there's nothing to gain from being fast or running a hundred accounts.
- When registration closes, winners are drawn at random and each gets a unit reserved to check out. You're only charged if you win.
- It can't oversell — 100 units means exactly 100 winners, no matter how big the stampede.
- The draw is verifiable: anyone can recompute the winners in their own browser and confirm it wasn't rigged.
How it's built
The whole thing runs on Amazon Aurora DSQL, and the hard guarantees live in the database layer:
- Exactly-once, never oversold. Every unit is its own row. Allocation is a guarded
UPDATEthat only succeeds once, so concurrent claims collide on the row and one retries — there's no hot counter to oversell. 100 units, 100 winners, always. - One human, one entry. A verified identity is keyed by a one-way HMAC of the person's email or phone, used as the primary key of an identity table. A bot firing 250,000 requests from 60 fake accounts collapses to 60 entries — volume buys nothing.
- Provably fair draw (commit-reveal). When a drop is created I publish
sha256(seed)as a commitment. The seed itself isHMAC(secret, dropId), fixed in advance and revealed only at draw time. Winners are the entries with the lowestmd5(entry_id || seed). Because the commitment is published before anyone enters, I can't pick a seed after seeing who entered. A client-side verifier re-runs the whole computation in the browser (a dependency-free MD5 plus SubtleCrypto SHA-256) and flags any tampering. - Single-leader, idempotent draw. Only the transaction that flips the drop from
open → drawingruns the allocation; concurrent or repeated draw calls just return the existing result, so an entry can never win twice.
On top of DSQL: Next.js 16 (App Router, React 19) on Vercel, Tailwind v4, Stripe test-mode embedded checkout, and pg + @aws-sdk/dsql-signer for short-lived IAM auth tokens.
Why Amazon Aurora DSQL
This is where DSQL earns its place. NoScalp runs as two peered DSQL clusters — us-east-1 and us-east-2 — with a us-west-2 witness, presented as one logical, strongly consistent database. A global drop can take writes in one region and reads in another with no replication lag: the /fairness page has a live probe that writes through us-east-1 and reads it straight back through us-east-2, and the regions agree instantly. Strong cross-region consistency is exactly what oversell-proof inventory needs, and it's something most multi-region databases can't offer without eventual-consistency caveats.
Challenges I ran into
- DSQL's ~3,000-rows-per-transaction limit. Seeding thousands of fans and running the draw meant batching every bulk insert and delete into ≤1,000-row chunks.
- Optimistic concurrency (SQLSTATE 40001). DSQL has no locks, so the engine is designed around guarded single-row updates with retries instead of hot counters or
SELECT ... FOR UPDATE. - No foreign keys or sequences. Idempotency comes from deterministic UUIDv5 ids (an order id derived from the allocation and identity, for example), so retries can't create duplicates.
- The 100-new-connections-per-second cap. Small warm connection pools with cached short-lived IAM tokens per region.
- Standing up multi-region and proving it. Peering two clusters plus a witness region, then building a live consistency check so "strongly consistent across regions" is demonstrable, not just asserted.
What I learned
How to get exactly-once, oversell-proof allocation out of a distributed SQL database without a single lock or counter — and that "provably fair" (a draw you can recompute yourself) is far more convincing than "trust us." DSQL's strong consistency across active-active regions turned out to be the cleanest possible foundation for inventory that absolutely cannot oversell.
What's next
Real identity verification (phone OTP or Stripe Identity behind the existing pluggable provider), re-drawing forfeited claims to a waitlist, and rate-limiting the public endpoints for production and a mobile app with push notifications so you never miss a drop.
Built With
- amazon-aurora-dsql
- amazon-web-services
- framer-motion
- next.js
- node.js
- postgresql
- react
- stripe
- tailwind-css
- typescript
- vercel
Log in or sign up for Devpost to join the conversation.