<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: john lee</title>
    <description>The latest articles on DEV Community by john lee (@64johnlee).</description>
    <link>https://dev.to/64johnlee</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3997295%2F79493f6e-fe4c-465d-b092-e0551a9373fc.png</url>
      <title>DEV Community: john lee</title>
      <link>https://dev.to/64johnlee</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/64johnlee"/>
    <language>en</language>
    <item>
      <title>I built a million-scale World Cup prediction game on DynamoDB + v0 in a weekend</title>
      <dc:creator>john lee</dc:creator>
      <pubDate>Wed, 24 Jun 2026 07:32:26 +0000</pubDate>
      <link>https://dev.to/64johnlee/i-built-a-million-scale-world-cup-prediction-game-on-dynamodb-v0-in-a-weekend-1gn5</link>
      <guid>https://dev.to/64johnlee/i-built-a-million-scale-world-cup-prediction-game-on-dynamodb-v0-in-a-weekend-1gn5</guid>
      <description>&lt;p&gt;&lt;em&gt;I created this project and this post for the **H0: Hack the Zero Stack&lt;/em&gt;* hackathon&lt;br&gt;
(Vercel v0 + AWS Databases). #H0Hackathon*&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live demo:&lt;/strong&gt; &lt;a href="https://world-cup-prediction-game-psi.vercel.app" rel="noopener noreferrer"&gt;https://world-cup-prediction-game-psi.vercel.app&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;60-second walkthrough:&lt;/strong&gt; &lt;a href="https://youtube.com/shorts/tTPotTmi4fE" rel="noopener noreferrer"&gt;https://youtube.com/shorts/tTPotTmi4fE&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;A World Cup is one of the few events where you genuinely might get hundreds of millions&lt;br&gt;
of people doing the same thing at the same time. So when I set out to build a prediction&lt;br&gt;
game for it, the question wasn't "can I make a CRUD app" — it was "would the data layer&lt;br&gt;
survive matchday?" That's exactly the bet &lt;strong&gt;H0&lt;/strong&gt; asks you to make: prototype on the same&lt;br&gt;
&lt;strong&gt;Amazon DynamoDB&lt;/strong&gt; foundation real products run on, with a &lt;strong&gt;v0&lt;/strong&gt;-scaffolded Next.js&lt;br&gt;
frontend on &lt;strong&gt;Vercel&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here's how it came together — and the one design decision the whole thing hinges on.&lt;/p&gt;

&lt;h2&gt;
  
  
  The app
&lt;/h2&gt;

&lt;p&gt;Every match shows a &lt;strong&gt;10,000-run Monte-Carlo forecast&lt;/strong&gt; (win/draw/loss + a likely&lt;br&gt;
scoreline) next to what &lt;strong&gt;the crowd&lt;/strong&gt; actually picked. You call the result, earn points&lt;br&gt;
(+5 exact score, +3 right outcome), and climb a &lt;strong&gt;global leaderboard&lt;/strong&gt; that settles&lt;br&gt;
against real results pulled from ESPN. No login — an anonymous cookie makes every visitor&lt;br&gt;
a player instantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  v0 did the frontend; I owned the data layer
&lt;/h2&gt;

&lt;p&gt;v0 scaffolded a genuinely good Next.js App Router app — match cards, a pick sheet, three&lt;br&gt;
tabs, SWR data fetching against &lt;code&gt;/api/*&lt;/code&gt; — in minutes. It even left placeholder route&lt;br&gt;
handlers with a literal TODO: &lt;em&gt;"wire to DynamoDB."&lt;/em&gt; My job was to make that real without&lt;br&gt;
fighting the contract v0 generated. I dropped in the sim engine + a DynamoDB data layer&lt;br&gt;
and rewrote the four routes to return the exact shapes v0's TypeScript types expected.&lt;br&gt;
The UI never knew the difference — it just started showing real fixtures.&lt;/p&gt;

&lt;h2&gt;
  
  
  The decision the whole thing hinges on: the leaderboard
&lt;/h2&gt;

&lt;p&gt;Single-table DynamoDB is the easy part. The trap is the leaderboard. The naive design —&lt;br&gt;
"put every user in one partition, sort by points" — is a &lt;strong&gt;hot partition&lt;/strong&gt; waiting to&lt;br&gt;
happen: on matchday every score update hammers one partition key.&lt;/p&gt;

&lt;p&gt;So the leaderboard is &lt;strong&gt;write-sharded&lt;/strong&gt;. A user's profile is indexed under&lt;br&gt;
&lt;code&gt;LB#&amp;lt;season&amp;gt;#&amp;lt;hash(uid) % 10&amp;gt;&lt;/code&gt; with their (zero-padded) points as the sort key. Writes&lt;br&gt;
spread across 10 partitions; to read the global top-N I &lt;strong&gt;scatter-gather&lt;/strong&gt; — query the&lt;br&gt;
top-N of each shard in parallel and merge. A user's rank is &lt;code&gt;COUNT(points &amp;gt; mine)&lt;/code&gt; summed&lt;br&gt;
across shards. It's the pattern AWS literally recommends, and it means the board scales&lt;br&gt;
horizontally instead of melting.&lt;/p&gt;

&lt;p&gt;One GSI does triple duty (all-string keys):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;LB#&amp;lt;season&amp;gt;#&amp;lt;shard&amp;gt;&lt;/code&gt; → leaderboard&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DATE#&amp;lt;yyyymmdd&amp;gt;&lt;/code&gt; → today's slate&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;MPICK#&amp;lt;matchId&amp;gt;&lt;/code&gt; → every pick on a match (so settling fans out cheaply)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Picks bump an &lt;strong&gt;atomic counter&lt;/strong&gt; on the match (that's the "crowd picked" split) inside a&lt;br&gt;
transaction. On-demand capacity means I never pre-provision — matchday spikes just work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shippable, not a demo
&lt;/h2&gt;

&lt;p&gt;The thing that makes me happiest: it's &lt;strong&gt;actually deployed and serving real data&lt;/strong&gt; —&lt;br&gt;
real 2026 fixtures, real sim odds, a real sharded leaderboard on real AWS — and it plugs&lt;br&gt;
into a daily-content funnel I already run that sends real fans to it. The whole point of&lt;br&gt;
the "zero stack" is that the weekend prototype &lt;em&gt;is&lt;/em&gt; the production foundation. This one is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it:&lt;/strong&gt; &lt;a href="https://world-cup-prediction-game-psi.vercel.app" rel="noopener noreferrer"&gt;https://world-cup-prediction-game-psi.vercel.app&lt;/a&gt; · built with v0 + Vercel +&lt;br&gt;
Amazon DynamoDB for &lt;strong&gt;#H0Hackathon&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>hackathon</category>
      <category>aws</category>
      <category>dynamodb</category>
      <category>nextjs</category>
    </item>
  </channel>
</rss>
