What I'd do differently with the leaderboard
A note on the query I under-designed the first time.
The global leaderboard on Rate My Username is one of the stickiest parts of the product — it's the reason people come back after they've already rated their own handle. It's also the part I designed worst in version one.
The naive version
The first implementation did exactly what you'd expect from a feature built fast: on every page load, pull every scored username, sort by score, render the top of the list. That's fine at a few dozen rows. It stops being fine once the table has real volume behind it — sorting the whole table on every request is wasted work the moment the leaderboard only ever displays a fixed-size top slice of it.
Where it actually broke
The symptom wasn't a crash, it was something worse for a tool built around feeling instant: the leaderboard got noticeably slower to load on mobile connections specifically, which is most of this site's traffic. A tool whose entire pitch is "verdict in ten seconds" can't have its most social feature feel sluggish.
The fix
Two changes, both small: a composite index on score and timestamp so the database doesn't have to scan the full table to find the top entries, and capping the live leaderboard query to a windowed top-N read instead of sorting everything — older or lower-ranked entries get paginated separately rather than loaded upfront on every visit. Neither change touched the frontend at all; it was entirely a question of asking the database for less work on the request that mattered most.
What I'd do from the start next time
Design the access pattern before the schema, not after. A leaderboard is a read-heavy, write-light feature by nature — almost nobody is adding a new score at any given moment compared to how many people are just viewing rankings — and that asymmetry should decide the indexing strategy on day one, not after the first real traffic spike exposes it.