Inspiration

Every flash sale eventually runs into the same wall: the moment a limited drop goes live — sneakers, concert tickets, GPUs, collectibles scalper bots fire hundreds of purchase requests faster than any human can click, buy out the entire stock in milliseconds, and resell it at a markup. Real customers refresh the page once and see "sold out." The business loses the relationship with the fan it was trying to reach, and the bot operator walks away with the inventory instead.

What made this an interesting problem for this hackathon specifically was the database challenge hiding underneath the product idea: if a hundred-plus requests hit the same row of inventory in the same second, what actually guarantees you never sell the same unit twice? That's not a frontend problem it's a concurrency and correctness problem, which made it a natural fit for proving out what AWS Databases on Vercel could actually do under real contention, not just as a CRUD backend.

What it does

HypeShield is a real-time defense layer that sits in front of a flash-sale checkout endpoint and scores every purchase attempt as it arrives before it's allowed anywhere near inventory. Each request is judged on three signals: velocity (requests per identifier per second), headers (does this look like a real browser at all), and identifier pressure (a shared IP is only suspicious when it's also moving at bot speed — not on its own). Requests that fail the score get blocked outright; requests that pass get a real, atomic shot at the remaining stock.

The live dashboard shows this happening in real time: launch a simulated scalper botnet (a mix of real shoppers, obvious bots, and stealth bots faking real headers) and watch remaining stock, block counts, and outcome tallies update live, with the database enforcing — not just reporting — that the number sold never exceeds the number in stock. A second simulation fires legitimate human-paced traffic from a shared IP pool (the same pattern as an office or campus network) to prove the system doesn't punish real customers just for sharing a connection.

How we built it

  • Frontend: Next.js (App Router, TypeScript), deployed on Vercel
  • Primary database: Amazon DynamoDB (PAY_PER_REQUEST, us-east-1) — a Drops table holding live inventory counts, a Stats table holding aggregate attempt-outcome tallies, and an Idempotency table guarding against duplicate writes
  • Concurrency control: every purchase attempt resolves through a DynamoDB TransactWriteItems call with conditional checks — the database itself rejects any write that would oversell, rather than the application trying to coordinate locking
  • Velocity layer: Upstash Redis (via Vercel KV), using a sliding-window rate limiter, accessed over HTTP/REST so it works on Edge Runtime
  • Request scoring middleware: a custom proxy.ts (intentionally not named middleware.ts, for AWS SDK compatibility) running on the Node runtime, where velocity, header, and identifier-pressure signals are combined into a single trust score before a request is ever allowed to attempt a purchase
  • Admin/demo controls: Server Actions gate the reset and attack-simulation endpoints behind a secret header that's never exposed to the client

Challenges we ran into

The hardest bugs weren't in the scoring logic — they were in making "zero oversells" actually true under real concurrent load, and in debugging Vercel's production environment with almost no visibility into what was failing.

  • Silent retries lied about the numbers. The AWS SDK v3 retries failed requests automatically. Under concurrency, a write would actually succeed server-side, the client would time out anyway, the SDK would retry, the retry would fail its condition check, and the client would log the whole thing as "sold out" — even though zero units were actually oversold. The fix was building real idempotency on top of the transaction: a client-supplied request ID checked against the Idempotency table inside the same transactional write, so a retried request can be recognized as a duplicate instead of a phantom failure.
  • TransactWriteCommand failures all look identical unless you check the index. Distinguishing "this was a duplicate" from "this was actually sold out" required reading which item in the transaction failed its condition, not just catching the error type.
  • A Vercel-specific footgun broke every action button in production. Server Actions doing a self-fetch back to their own deployment were built from process.env.VERCEL_URL — which resolves to a Deployment-Protection-gated per-deployment URL, even when the real production domain is public. Every click returned an HTML auth-challenge page instead of JSON, and Next.js redacts the real Server Action error before it reaches the browser, so the only visible symptom was a generic "An error occurred in the Server Components render" message. The actual fix was a one-line env var swap to VERCEL_PROJECT_PRODUCTION_URL — but finding it meant adding manual server-side logging and reading raw Vercel logs, since the client-facing error told us nothing real.
  • The trust score has a real, unresolved tradeoff. Tuning the penalty for velocity_exceeded is a tightrope: set too low, and stealth bots that fake every header but burst requests slip through almost entirely; set high enough to catch them, and legitimate shoppers on shared/corporate networks start getting blocked alongside real bots. There's no setting that's simply "correct" — only a tradeoff to be honest about.

Accomplishments that we're proud of

  • A live concurrency test firing 150 simultaneous mixed-traffic requests (real shoppers, obvious bots, stealth bots) at a 100-unit drop resolved with 138 blocked (92%) and the remaining stock dropping by exactly the count of requests that actually succeeded — no drift, no phantom oversells, with conflictExhausted: 0 across clean test runs.
  • A second test firing legitimate human-paced traffic from a shared-IP pool got 6 of 6 through with zero blocks — proving the system distinguishes "shared network" from "bot" instead of treating them as the same signal.
  • The whole defense pipeline — scoring, blocking, and the underlying inventory writes — runs against a real, live DynamoDB table in production, not a mocked demo.

What we learned

  • Atomic conditional writes (via TransactWriteItems) are what actually make a "zero oversell" guarantee true under concurrency — application-level checks alone can't promise that once you have more than a couple of simultaneous writers.
  • Rule-based trust scoring is honest in a way that's easy to undersell: a system that openly trades off catch-rate against false positives (and says so) is more credible than one that claims a perfect number with no visible tradeoff.
  • Production debugging on serverless platforms requires planning for opacity — Vercel's Deployment Protection and Next.js's Server Action error redaction both hide the real failure from the client by design, so logging has to be built in deliberately rather than added after something breaks.

What's next for HypeShield

  • Configurable, per-business scoring thresholds, so a retailer can tune their own velocity/identifier-pressure tradeoff instead of using one fixed setting
  • Packaging the scoring middleware as a drop-in SDK/proxy that any existing checkout flow could sit behind, rather than requiring a bespoke integration
  • Expanding the signal set beyond rule-based heuristics — device reputation and behavioral signals were intentionally scoped out of this build for demo clarity, but are the natural next layer
  • Multi-tenant support so one HypeShield deployment could protect many businesses' drops simultaneously, each with its own Drops/Stats partition

Built With

Share this project:

Updates