Exercises: The Medallion Architecture
Solutions and grading notes are in the instructor companion. Exercises marked ๐งช use
code/layer_check.py.
Warm-Up
Exercise 34.1 โ State the guarantee
Difficulty: โ โโ ยท Time: 15 minutes
Without looking back, write the one-sentence guarantee for each layer. Then compare against ยง34.2โ34.4.
Then: for each guarantee, name one thing you could check automatically that would detect a violation. If you cannot name one, the guarantee is decoration.
Exercise 34.2 โ Which layer?
Difficulty: โ โโ ยท Time: 20 minutes
Assign each to bronze, silver, or gold, and give the reasoning in one line:
- Casting
"142"to142. - Deciding a customer is active.
- Deduplicating three CDC rows for one order.
- Excluding orders flagged as tests.
- Renaming
cust_idtocustomer_id. - Converting EUR to USD at yesterday's rate.
- Storing a malformed JSON line exactly as received.
- Turning
quantity = -1intois_return = true. - Splitting
"Ada Lovelace"into first and last name. - Assuming a timestamp with no offset is UTC.
Two of these are genuinely arguable. Say which, and argue both sides.
Exercise 34.3 โ Read the violations
Difficulty: โ โโ ยท Time: 20 minutes ยท ๐งช
python code/layer_check.py --check
- Eight findings across six models. Which two models produce two findings each, and why?
- Five are blocking and three are warnings. Apply ยง34.5's classification test to each of the three warnings and say whether you agree.
gold.fct_sessiontripslayer-skipandcast-in-gold. Which would you fix, and what happens to the other?
Core
Exercise 34.4 โ Run it on your own project
Difficulty: โ โ โ ยท Time: 60 minutes ยท ๐งช
- Express your own models in
build_graph()'s format โ layer, dependencies, materialization, unique key, grain, and operations. Twenty models is enough. - Run
--check. Report the violations honestly, including the count. - For each violation: was it created deliberately, or did it accumulate?
- ยง34.13 claims drift is the normal end state. Does your project support that claim?
Exercise 34.5 โ The boundary cases
Difficulty: โ โ โ ยท Time: 40 minutes
ยง34.3's test: if two competent people could disagree about the answer, it is a business rule.
- Find three transformations in your own silver (or staging) layer that fail this test.
- For each, apply Case Study 2's three markers: did the source specify it, did you use context outside the column, could a reasonable person land elsewhere?
- Move one of them to gold. What did it cost โ a model, a grain statement, an owner, a test?
- ยง34.3 says "when genuinely unsure, push it up." What does that cost when you are wrong in that direction?
Exercise 34.6 โ Tests at the right layer
Difficulty: โ โ โ ยท Time: 45 minutes
ยง34.6: a test at the wrong layer is a false alarm or a missed defect.
- Take Chapter 23's twenty-two assertions and assign each to a layer.
- Find the duplicates โ assertions that exist at two layers and fail for the same reason. Kestrel found 31.
- Now find the row-count exception: the assertion that belongs at two layers because it fails for opposite reasons. Write both versions.
- Do you have a bronze assertion that asserts correctness? Weaken it or move it, and say which.
Exercise 34.7 โ Replay cost
Difficulty: โ โ โ ยท Time: 40 minutes ยท ๐งช
python code/layer_check.py --replay silver.stg_orders
python code/layer_check.py --replay bronze.customers_raw
python code/layer_check.py --replay gold.daily_revenue
- Three models, three costs: $25.92, $102.00, $0.96. Explain the pattern in one sentence.
- Compute the same for your own project, using your own node-hour rate.
- What is your full-rebuild cost? Kestrel's is $198.96.
- Have you ever attempted one? If not, what would break? Predict, then find out if you can.
Exercise 34.8 โ Depth and blast radius
Difficulty: โ โ โ ยท Time: 40 minutes ยท ๐งช
python code/layer_check.py --depth
bronze.customers_rawreaches 47% of the graph. Compute the equivalent for your project โ which model has the widest blast radius?- How many assertions does it have? How many does your most business-critical model have?
- ยง34.10 proposes: test breadth by blast radius, test depth by visibility. Apply it and say what moves.
- Find any model whose depth contradicts its layer. If there is none, say how confident you are that your depth calculation would show one.
Exercise 34.9 โ Design a quarantine
Difficulty: โ โ โ ยท Time: 45 minutes
ยง34.12's four properties: a paging size limit, the assertion that rejected the row, replayability, and a retention that forces the drain.
- Design the quarantine table for one of your pipelines. Include every column.
- Set the size limit. Kestrel's is 0.1% of a load or 500 rows, whichever is smaller. Justify yours.
- Write the replay job. What does it do with a row that fails again?
- Case Study 2's analyst queried the quarantine and produced a number wrong by 1.8%. What would stop that in your design โ and is it a technical control or a catalog one?
Exercise 34.10 โ How many layers?
Difficulty: โ โ โ ยท Time: 30 minutes
ยง34.8: three is a convention.
- Argue for two layers for a specific system you know. What does silver buy there?
- Argue for five. Name the two extra layers and what each guarantees.
- ยง34.8 says a layer that exists because a different team owns it is a mesh domain in disguise. Find one in your organization, or say why there is none.
- What would make you remove a layer from an existing platform, and how would you do it safely?
Advanced
Exercise 34.11 โ Extend the checker
Difficulty: โ โ โ ยท Time: 90 minutes ยท ๐งช
Add three rules to layer_check.py, each with a fixture that triggers it and one that does not:
- A silver model with a timezone-assuming parse (Case Study 2). What is your false-positive rate?
- A gold model with no consumer โ no dashboard, no export, no downstream model. Is it a violation or a finding?
- A bronze table with no retention policy (Chapter 30 ยง30.7).
- Two silver models reading the same bronze column with different logic โ the divergence check.
- A model whose depth exceeds the maximum for its layer.
- Expiring suppressions (ยง34.13), failing the build on an expired one.
Then: classify each new rule as blocking or warning using ยง34.5's test, and defend the classification.
Exercise 34.12 โ Attempt the rebuild
Difficulty: โ โ โ ยท Time: 2โ3 hours
Case Study 1's rebuild failed three times in two years, each time revealing something no test could.
- Attempt a full rebuild from raw for a project you own, into a scratch schema.
- Record every failure and classify it: a missing input, a non-deterministic transformation, a changed source, a hidden dependency.
- If it succeeds on the first attempt, be suspicious: check that you rebuilt from raw rather than from an intermediate that was already materialized.
- What did it cost, in dollars and in hours?
- Put it on the calendar. ยง34.15 argues a capability you never exercise is one you do not have.
Exercise 34.13 โ The ambiguity flag
Difficulty: โ โ โ ยท Time: 60 minutes
Case Study 2's durable fix flags ambiguous timestamps at ingestion.
- Scan your bronze layer for timestamp columns arriving without an offset. Kestrel found 14 of 41.
- For each: has anybody parsed it yet? What did they assume?
- Extend the idea beyond timestamps. What else arrives ambiguous? Currency without a code, a quantity without a unit, an ID without a namespace, a name without an encoding.
- Design the catalog field that records "a decision is required here and nobody has made it."
- Case Study 2 leaves nine columns unresolved and calls that correct. Do you agree?
Exercise 34.14 โ Argue against the pattern
Difficulty: โ โ โ ยท Time: 45 minutes
ยง34.14 names three conditions under which the medallion architecture is wrong.
- Write the strongest case against adopting it for a system you know. Be specific about the costs.
- ยง34.11 lists storage, compute, latency, and arguments. Price the first three for your system.
- The chapter claims one well-tested transformation layer beats three untrusted ones. Test the claim: what would you lose, concretely?
- Now argue the other side, and say which argument you actually believe.
Project Milestone
Exercise 34.15 โ Specify and enforce your layers
Difficulty: โ โ โ ยท Time: 3โ4 hours ยท ๐งช
Formalize the Kestrel platform's layers, per ยง34.15.
- Write the three guarantees for your platform, in one sentence each, as a document in the repo.
- Add the four bronze envelope columns to every bronze table that lacks them.
- Implement
layer_check.py's nine rules against your real model graph, in CI. - Fix the blocking violations, or suppress them with an expiry and a reason.
- Assign every assertion to a layer (Exercise 34.6) and remove the duplicates.
- Build the quarantine for one silver model, with all four properties.
- Compute depth and blast radius, and reallocate assertions accordingly.
- Run one full rebuild and record what it cost and what it found.
Deliverable: the guarantees document, the CI check with its violation count before and after, the assertion-to-layer map, the quarantine, and the rebuild log.
The rebuild log is the deliverable that matters. Everything else states an intention; the rebuild is the only thing that demonstrates the layers do what they claim.