Back to home
The Scaling Playbook

The whole idea is simple: write down what happened and never change it, and keep small ready-made summaries on the side. New data just gets added to the bottom of the list. When someone opens a page, we read the summary — not the millions of raw records — so the data can grow to billions of rows and pages stay just as fast.

Add the factsKeep summariesPages stay fast

How it stays fast as the data grows

add only
Only add, never edit

Every event is written down once and never changed. New info goes on a new line, so nothing gets overwritten — no two things fighting over the same row, and you always keep the full history.

reads
Pages read the summary, not the raw data

We keep small tables that are already added up. A leaderboard reads a few rows instead of scanning 28 million deliveries.

totals
Totals are counted ahead of time

Each player's totals are stored in advance and indexed, so looking one up takes the same tiny effort whether there are a thousand rows or a billion.

by date
Data is filed by date

The big table is split into buckets by date. Asking about one match or season only opens the right bucket — and clearing out old data is just dropping a bucket.

matching
Every player is matched on the way in

As data arrives, we tie each name to one real person straight away. So there are never duplicate players quietly messing up a leaderboard.

rebuild
Summaries can be rebuilt any time

The raw events are the truth; the summaries are just a shortcut. If one is ever wrong, we rebuild it from scratch — we did that for 28.7 million rows in seconds.

Rules for designing the tables

01
Never change what happened

Fix a mistake by adding a correcting line, not by editing the original. The history stays intact.

02
One shape for every sport

config → masters → fixtures → events → summaries → extras. Every sport uses the same layout, so nothing is a special case.

03
Make a summary for every page

If a screen needs a number, add it up in advance. Never make the big table do the maths while someone is waiting.

04
Label every total by what it covers

Tag each total with its scope — all-time, one competition, or one season — so IPL numbers never mix with another league's.

05
Split the biggest table by date

Decide the date buckets on day one. Faster reads and easy cleanup both come from it.

06
Never reuse a code

Codes are permanent. Rename the label if you like, but reusing a code quietly breaks old data.

07
Match names as data arrives

Line up ids at the door. It's easy up front and painful once you already have a billion rows.

08
Attach notes to fixed facts

Commentary points at an event's id, so text can be edited freely without ever touching the facts.

09
Build the index around the real question

Shape the index to the query people actually run, so the answer comes straight out of it.

10
Make rebuilds safe to repeat

You should be able to rebuild any summary twice and get the same result. One you can't rebuild is a trap.

Why not DynamoDB?

This model (Postgres + summaries)DynamoDB
How data is storedRelated tables plus ready-made summariesOne big table of key → value
What you can askAnything, with SQL — joins, ranges, totalsOnly the questions you planned the keys for
Links between thingsBuilt in across all the tablesNone — you copy data or make many calls
Leaderboards & totalsCounted ahead of time, read in one shotNot built in — you count them yourself elsewhere
Exploring the dataRight here, on the same databaseCopy it out to another tool first
Handling huge writesVery high; you do some housekeepingBasically unlimited, fully managed
Speed of a normal lookupOne indexed row — a few millisecondsOne key lookup — a few milliseconds
Best when you haveLots of related data and changing questionsA few fixed questions at massive write volume
What about the odd query that has to read the whole table?

It happens, but rarely — most pages read a ready-made summary. When a question genuinely needs to scan everything, we run it once, save the answer in Redis, and serve it from there afterwards. So even the heavy one-off is paid for a single time, and everyone after gets it instantly.