01 — DefineCapture the actual question

Most stakeholder requests come in as a deliverable — "I need a dashboard for X" — when what's actually needed is the answer to a decision. The first job is to translate the request into the underlying decision, because the decision determines the metric, and the metric determines everything downstream.

Three questions I always ask:

  1. What decision will you make differently based on this? If the answer is "none," the work isn't worth doing.
  2. What's the smallest version that would tell you what you need? Always start there.
  3. What would change your mind? If no answer would, it's a confirmation request, not an analysis.

02 — ModelSketch the joins before writing SQL

Before I write a line of SQL, I sketch the join graph on paper. What's the grain of the output? Which dimensions does it need? Where do the joins lose rows or duplicate rows? What's the time-window logic?

This step takes 20 minutes and saves 4 hours of debugging. The most common bugs in analytics SQL aren't typos — they're cardinality surprises: "I joined on user, but the right side has multiple rows per user, so my counts doubled." A grain check at the modeling stage catches these.

SQL bugs hide in joins. Joins hide in vague grain. Pin the grain, and the bugs surface.

03 — BuildLayered, readable, deterministic

I build in layers — staging, then intermediate logic, then the final query. Each layer is a CTE or a view. The names match what they represent. Comments explain why, not what. The final query reads like prose because the CTEs above it have done the hard work.

The discipline is to write SQL that someone else can debug at 3 a.m. without context. That means meaningful aliases, no clever one-liners, and — crucially — deterministic ordering wherever ordering matters.

04 — TestSpot-check, then reconcile

Two kinds of testing matter:

  • Spot checks — pick three known cases and verify the output by hand. If the customer KPI says 47, walk through the data for that one customer and confirm 47 is right.
  • Reconciliation — totals against a known source. If you're computing revenue, the total should match the billing system within tolerance. If it doesn't, find out why before the dashboard ships.

Automated tests are valuable but they're a complement, not a replacement. Tests catch regressions; they don't catch the original misinterpretation.

→ The 3-customer test

For any new metric, pick three customers — small, medium, large — and walk through the calculation manually. Do this before showing the dashboard to anyone. The number of times this catches errors that automated tests didn't is humbling.

05 — ShipDeploy, document, monitor

Shipping isn't deploying. It's deploying plus making the work durable: writing a one-page document explaining the metric (definition, edge cases, known limitations), setting up monitoring so silent failures don't go unnoticed, and following up with the stakeholder a week later to see whether the answer actually changed their decision.

The follow-up is the part most engineers skip. It's also the part that determines whether the work was useful. If the dashboard didn't change anyone's behavior, the work didn't ship — it just deployed.

06 — TakeawaysBoring is the goal

This workflow is unspectacular. There's no novel framework, no clever trick. What it gives you is reliability — the same kind of question, asked six months later, gets the same kind of answer. That's the actual product.

  • The question is always upstream of the SQL. Get it right first.
  • Sketch joins before writing them. 20 minutes saves 4 hours.
  • Spot-check three customers. Manually. Every time.
  • Follow up a week later. If the dashboard didn't change a decision, find out why.

Reliability is a habit. The workflow is the structure that makes the habit easy.