Stage 1 of 9 · Model
What one chart has to read
Use 86,400 seconds a day and 1 KB an event. A large team sends 300 million events a month, and its daily-signups chart filters on two properties over 90 days.
What you need to know first
2 billion events a day. About how many events a second on average?
About 23,000 per second.
2,000,000,000 ÷ 86,400 ≈ 23,000 a second; peaks at 4× are about 93,000. A busy write rate, but an ordinary one if writes are batched.
At about 1 KB per event, how many terabytes of raw events arrive per day?
About 2 TB.
2,000,000,000 × 1 KB = 2 TB a day, about 180 TB over 90 days. Far too much to answer charts from memory.
A row store like Postgres keeps each row's fields together on disk. To count rows, it reads whole rows, every field, even if the query uses three of them.
An index helps find rows. It doesn't make reading them cheaper once they're found.
A chart needs 900 million events, using 3 small fields from each 1 KB event. Reading whole rows, about how many gigabytes are read?
About 900 GB.
900,000,000 × 1 KB = 900 GB read, for perhaps 10 to 20 GB of fields actually used. The query isn't slow at finding rows; it's slow because it reads everything else in them.
What the stage asks
Which statements follow?
- Holds
2 billion events a day is about 23,000 a second on average, so peaks near 90,000 a second.
2,000,000,000 ÷ 86,400 ≈ 23,000; four times that is about 93,000. A busy but ordinary write rate if writes are batched.
- Holds
That is about 2 TB of raw events a day, or roughly 180 TB for 90 days.
2 billion × 1 KB = 2 TB a day. The volume, more than the rate, rules out answering from memory.
- Holds
The big team's 90-day chart has to consider about 900 million events.
300 million a month × 3 months. Even if each row takes a microsecond, a single chart is minutes of work on one core unless most of each row is never read.
- Fails
An index on (team, timestamp) in Postgres would make this chart fast.
The index finds the 900 million rows quickly, but then each full row, properties and all, must be read to count them. The problem is not finding the rows; it is reading 900 GB to use three fields from each.
The reasoning
- Analytics queries are wide in rows and narrow in columns.
- Row stores read whole rows, so a three-field question pays for every field.
- Indexes find rows; they don't make reading them cheaper.
Analytical questions are wide in rows and narrow in columns: they touch a large share of a team's events but only a few fields of each. A store that keeps whole rows together must read everything to answer them. That is the bottleneck to design around, not the write rate.