Database vs data warehouse

DataTier 3 · scale vocabularyPhase 7 · Grow beyond one city

A separate copy of your data built for analysis, so heavy reporting queries don't slow down the live product.

Running heavy analytical queries against the live production database slows the app for real users, and the two jobs want different structures. A data warehouse exists as a separate store built for analysis, so reporting and data science can crunch large history without touching the database that serves customers.

The production database is tuned for fast, small operations, place an order, read a profile. Running a giant analytics query ("revenue by region by month for two years") against it would slow the whole product down. So data is copied into a data warehouse, built specifically for big analytical queries.

Analysts and dashboards query the warehouse, not production. This keeps the live product fast while enabling deep analysis, and it's where tools like BigQuery fit.

A junior PM, stuck

My morning dashboard shows 412 orders for yesterday, but ops counted 445 from their own screens, and now everyone is asking me which number is right. The analyst just said the warehouse syncs at 6am and went back to work. I do not know if that means my dashboard is wrong, ops is wrong, or this is expected, and I have to answer in standup.

Both numbers are right; they are counting two different copies of the data. Your dashboard reads a data warehouse, a separate copy built for heavy reporting, and that copy is refreshed on a schedule, last night at 6am. Ops reads the live production database, which has every order up to this second. Below are the two copies side by side and the one query that behaves very differently depending on which it runs against. The gap is the lag, not a bug.

Production and the warehouse, same orders, two copies
production orders, live to this second
id | area | total | created_at
o_5512 | Dhaka | 649 | 2026-03-06T12:41:00Z
o_5601 | Dhaka | 280 | 2026-03-07T05:20:00Z
o_5602 | Dhaka | 320 | 2026-03-07T08:15:00Z
warehouse orders, a copy stamped last_synced 06:00
last_synced: 2026-03-07T06:00:00Z
id | area | total | created_at
o_5512 | Dhaka | 649 | 2026-03-06T12:41:00Z
o_5601 | Dhaka | 280 | 2026-03-07T05:20:00Z
the revenue-by-area report query
SELECT area, count(*), sum(total) FROM orders GROUP BY area;
-- safe on the warehouse: heavy scan, nobody waiting on it
-- dangerous on production: same scan competes with live checkouts

Click a step to see the lines it points at.

Calling a sync lag a data bug. The warehouse being hours behind is by design; raising it as numbers do not match sends engineers debugging a pipeline that is working exactly as built.
Quoting a warehouse number as if it were live. Reporting copies refresh on a schedule, so a warehouse figure is always as-of its last sync; state the sync time or someone acts on stale counts.
Running heavy reports against production. A giant analytics scan on the live database competes with real customer traffic; that is the whole reason the warehouse exists, so point big queries there.
Comparing two dashboards without checking their source. The same orders counted from production versus the warehouse will differ by the unsynced window; confirm both sources before declaring either one wrong.

In standup, say: "Both are right. My dashboard reads the warehouse, correct as of the 6am sync; ops reads live production. The 33-order gap is everything placed after 6am, and it closes at the next sync." You traced a mismatch to a warehouse sync lag and named the source of each number, which is the skill.

"Pull that report from the warehouse, not production" protects live performance; knowing the split explains where analytics data lives.
There's a lag: data flows from production to the warehouse periodically, so warehouse numbers may be hours behind live.

"That analysis runs on the warehouse so it won't touch production load."

Appears in Phase 7, Grow beyond one city.