How the builder track works
Eight sessions, 45 minutes each, one artifact: a monitor set on one real table, built signal by signal. Tonight the metadata queries and the first two monitors. Then freshness properly in session 2, volume and uniqueness in session 3, schema in session 4, distribution in session 5, expectations as code in session 6, lineage and blast radius in session 7, and in session 8 you run the whole set against 30 nights of history and count what it caught. The table throughout is orders_daily at Bellwether, a grocery delivery company whose warehouse has five real problems in it that nobody has noticed yet.
★ What you walk out with tonight. Four SQL snippets that work on any warehouse table you own, without installing anything. The reason a monitor is a query plus a threshold plus a named human, and useless if any one of the three is missing. And the number that decides whether the whole practice survives its first month: how many false pages a week a team tolerates before it stops reading the channel.
LiveWhy start with metadata rather than the data3 min▶
Checking data means reading rows. Reading rows on a large table costs money and time, which is why the checks that read rows get run nightly at best and quietly disabled by the third invoice. Metadata is different: row counts, load timestamps, column lists and null counts are either already stored by the warehouse or computable in a single cheap aggregate. You can check them every 15 minutes without anybody noticing the bill.
That cost difference decides the shape of the practice. Metadata monitors are the layer that runs constantly and tells you something moved. Row-level tests are the layer that runs at build time and tells you this specific rule broke. You want both, and they are not substitutes.
Bellwether's finance team found a broken revenue number on a Monday morning. The pipeline had not failed, so nothing alerted. One of three regional shards had stopped arriving on the Thursday before, and the table had been at 41 percent of a normal day's rows for two business days. A row count compared against the last four Thursdays would have flagged it before anybody was awake, and it costs one aggregate query to compute.
Self-studyThe vocabulary for the whole track4 min▶
- Signal - one measurable property of a table over time. Freshness, volume, schema, distribution and lineage are the five that carry the practice, and sessions 2 to 7 take one each.
- Monitor - a query, a threshold and a destination. Drop any one and you have a dashboard nobody reads.
- Data downtime - the hours in which a table was wrong, late or missing while people were using it. Detection time is the part you control.
- False page - an alert on a night when nothing was actually wrong. The currency you spend to buy detection, and the reason precision matters more than coverage.
- MTTD - mean time to detect, in hours, from the moment a table went wrong to the moment a human knew. Session 8 measures yours.
- Blast radius - everything downstream of a broken table: models, dashboards, exports, one reverse-ETL job into the CRM that nobody documented. Session 7.
Four numbers, five signals
9 min liveThe five signals are not five separate technologies. Four of them come out of numbers your warehouse either stores for you or computes in one pass, and the fifth is a graph you build once and maintain. Knowing which is which tells you what you can have running by Friday and what needs a project.
LiveFreshness: the load timestamp, not the wall clock3 min▶
Freshness asks whether the data arrived when it was supposed to. The naive version compares max(updated_at) against the current time and fires if the gap is too large. It works, and it is where everybody starts, and session 2 shows why a fixed deadline is the wrong shape for the question.
Two traps worth knowing before you point this at anything real. A table that is rebuilt in full every night has an updated_at that jumps to now on every load, which tells you the job ran rather than whether the data is current: for those, timestamp the source event, not the row write. And a partition that arrives empty still updates the table's metadata in some warehouses, so a freshness check that passes on an empty load is measuring the pipeline's mood rather than the data.
LiveVolume: count(*) is a time series, not a number3 min▶
A row count on its own means nothing. A row count next to the last four values of the same weekday means a great deal, because grocery orders on a Saturday are not grocery orders on a Tuesday and a band wide enough to hold both is too wide to catch a missing shard.
This is the single most common reason a volume monitor gets switched off: it was set as a fixed band, it fired every weekend, and by week three somebody muted it. Session 3 does the arithmetic properly. Tonight just record the number every night, because you cannot compare against history you never stored.
Bellwether's weekend volume is about 45 percent of a weekday. A plus-or-minus 30 percent band around the weekday average fires on all eight weekend nights in a 30-night window. That is eight false pages to catch nothing, and it happens before you have caught your first real incident.
Self-studyUniqueness and null rate in one pass4 min▶
Duplicate rate and null rate are the two signals that catch the failures which leave the row count looking healthy. A merge key that changes upstream can double some rows and drop others, landing you within a percent of a normal night while every downstream sum is wrong.
- Duplicate rate beats a uniqueness test on a big table because it degrades gracefully. A hard uniqueness assertion either passes or fails the build; a rate tells you it went from 1 percent to 8 percent, which is the sentence you need in the incident channel.
- Null rate per column is worth storing for every column you care about, not just the key. The column that goes null is almost never the one you would have picked.
- Store the results in a small metrics table, one row per table per night. That table is the history every later session compares against, and if you start it tonight, session 8 has something real to read.
A monitor is three things, and two of them are not code
8 min liveThe query is the easy third. What decides whether a monitor is worth having is the threshold you set and the person who has agreed to answer it. A query with no threshold is a chart. A threshold with no named human is a chart that changes colour.
LiveThe precision problem, in one number4 min▶
Every monitor buys detection with false pages. The exchange rate is the thing to watch, because a person who is woken for nothing twice in a week stops treating the channel as real, and from that point your monitors are decoration. There is no clean published threshold for where that happens, and the honest version is that it depends on the team and how the page arrives. What is not in doubt is the direction: alert fatigue is the documented failure mode of monitoring systems in software operations and in clinical settings alike, and the fix is always fewer, better alerts rather than more.
So the operating rule for the rest of this track: a monitor that fires more than about once a week without a real cause gets retuned or deleted. Not muted. Session 8 puts a number on what noise costs you, and the number is uncomfortable.
Self-studyWhere to put the check: warehouse, orchestrator or transform4 min▶
Three homes, three jobs, and picking the wrong one is why teams end up with the same check in two places disagreeing with itself.
| Home | Runs when | Right for |
|---|---|---|
| A scheduled query in the warehouse | Every 15 to 60 minutes, independent of any pipeline | Freshness and volume on tables you do not build yourself |
| The orchestrator, as a task | Between pipeline steps | Gating: do not build the mart if the source is short |
| The transform project's own tests | At build time | Row-level rules about the data you produce |
The third one is a different discipline with its own tooling and its own course. What lives here is the layer that runs whether or not anybody's pipeline ran, because the most expensive incidents are the ones where nothing failed.
Two monitors on orders_daily
★ 19 min · everyone buildsBring a table you own. If you have nothing to hand, use the numbers printed below, which are the real first nine nights of Bellwether's history. By the end of this you have a metrics table, a freshness monitor and a volume monitor, and you have set both thresholds from history rather than from a feeling.
Create the metrics table first. One row per table per night. Everything in sessions 2 to 8 reads this, so the shape matters more than the checks do: table_name, load_date, rows, distinct_keys, max_updated_at, late_minutes, null_rate_customer, column_count. Nine columns, no nesting, one primary key of table plus date.
Backfill it if you can. If your warehouse keeps query history or partition metadata you can often reconstruct 30 nights of row counts in one statement. If it does not, start recording tonight and accept that your first thresholds are guesses until you have two weeks. Say that out loud to whoever asks why the monitor is not on yet.
Write the freshness monitor with a deadline you can defend. Bellwether promises the table by 06:00. Nights 1 to 8 landed 8, 14, 6, 19, 11, 22, 9 and 17 minutes past. Set the deadline at 30 minutes past and note what you just did: you picked a number that no clean night in your history exceeds. That is the whole method, and session 2 replaces it with something better.
Write the volume monitor against the same weekday. Nights 1 to 8 held 11,842 / 12,394 / 11,908 / 12,510 / 12,061 / 5,489 / 5,302 / 12,177 rows. Nights 6 and 7 are the weekend. Compare tonight against the median of the last four same weekdays and alert outside 25 percent. Now check what a plus-or-minus 30 percent band around 12,000 would have done to nights 6 and 7.
Name the human and write the action. Two sentences in the repo README: who is on the rota this week, and what they do when the page fires. If you cannot fill in the first sentence, you have built a chart. That is a fine thing to have built, and it is not a monitor.
Run night 9 through both. Night 9 landed 230 minutes past 06:00 with 12,004 rows. Which monitor fires, how long did it take, and what does the message say? Write the message you would actually want to receive, then compare it with what your tool would have sent.
The message is part of the monitor. "orders_daily freshness alert" makes the reader go and look. "orders_daily landed 230 min after the 06:00 promise; trailing p95 is 22 min; 3 dashboards and the finance export read it" makes the reader act. Same query, same threshold, different Monday.
Before session 2
25 min- Get the metrics table recording nightly on one table. One table done properly beats twelve half-instrumented ones, and session 5 explains why tiering is the whole game.
- Pull whatever history you can into it and plot lateness for the last 30 nights. Look at the shape: is it a tight cluster with a tail, or genuinely bimodal because two different jobs write this table?
- Write down the deadline you would defend to a stakeholder and the evidence for it. One line each.
- Find out who would answer a page about this table at 07:00 tomorrow. Actually ask them. This is the homework that fails most often, and it is the one that decides whether any of the rest works.
Three questions
A table is rebuilt in full every night. Why is max(updated_at) a poor freshness signal for it?
A row-write timestamp measures the write. If the source stopped producing events a week ago and the job still rebuilds nightly, the timestamp looks perfect. Timestamp the source event instead.
Bellwether's weekend volume is about 45 percent of a weekday. What does a fixed plus-or-minus 30 percent band around the weekday average do in a 30-night window?
45 percent is well outside a 30 percent band, so every weekend is an alert. This is the most common reason a volume monitor gets muted in its first month.
A monitor has a query and a threshold but no named person who has agreed to answer it. What have you built?
Detection is a human outcome, not a query result. An alert nobody owns changes the colour of a panel and nothing else, and the stakeholder still gets there first.