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.
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.
We keep small tables that are already added up. A leaderboard reads a few rows instead of scanning 28 million deliveries.
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.
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.
As data arrives, we tie each name to one real person straight away. So there are never duplicate players quietly messing up a leaderboard.
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.
Fix a mistake by adding a correcting line, not by editing the original. The history stays intact.
config → masters → fixtures → events → summaries → extras. Every sport uses the same layout, so nothing is a special case.
If a screen needs a number, add it up in advance. Never make the big table do the maths while someone is waiting.
Tag each total with its scope — all-time, one competition, or one season — so IPL numbers never mix with another league's.
Decide the date buckets on day one. Faster reads and easy cleanup both come from it.
Codes are permanent. Rename the label if you like, but reusing a code quietly breaks old data.
Line up ids at the door. It's easy up front and painful once you already have a billion rows.
Commentary points at an event's id, so text can be edited freely without ever touching the facts.
Shape the index to the query people actually run, so the answer comes straight out of it.
You should be able to rebuild any summary twice and get the same result. One you can't rebuild is a trap.
| This model (Postgres + summaries) | DynamoDB | |
|---|---|---|
| How data is stored | Related tables plus ready-made summaries | One big table of key → value |
| What you can ask | Anything, with SQL — joins, ranges, totals | Only the questions you planned the keys for |
| Links between things | Built in across all the tables | None — you copy data or make many calls |
| Leaderboards & totals | Counted ahead of time, read in one shot | Not built in — you count them yourself elsewhere |
| Exploring the data | Right here, on the same database | Copy it out to another tool first |
| Handling huge writes | Very high; you do some housekeeping | Basically unlimited, fully managed |
| Speed of a normal lookup | One indexed row — a few milliseconds | One key lookup — a few milliseconds |
| Best when you have | Lots of related data and changing questions | A few fixed questions at massive write volume |
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.