Analytics Engineering

Rescuing a 2-year-old dbt project

We inherited 460 dbt models, a README last touched 14 months ago, and a team afraid to merge anything. Here is the audit we ran before changing a single model - and the hardening checklist that followed.

The inheritance

A B2B SaaS platform called us with a familiar brief: their dbt project was two years old, the two people who built it had left, and the nightly run now failed roughly one morning in five. Nobody wanted to touch it. Every dashboard question started with "well, it depends which table you trust."

This is the most common shape of analytics engineering consulting work we get at Satyadata. Not greenfield builds - rescues. And the first rule of a rescue is counterintuitive: do not fix anything yet.

Audit first: before changing a single model

The temptation on day one is to open the ugliest model, wince, and start refactoring. Resist it. A dbt project that has survived two years of production is a fossil record of decisions, and you need to read the record before you rearrange the bones.

Our audit took about a week and touched nothing. We just read, ran, and wrote things down.

What we looked at

The ugliest model has an author, and the author has answers

Here is a habit I recommend to anyone inheriting a codebase: run git log on the ugliest model you can find, and make its most frequent author your onboarding buddy. Not to assign blame - the opposite. That person was in the room when the ugly decision was made, and the ugliness almost always encodes a real constraint: a source system that lied, a finance rule with eleven exceptions, a migration that half-happened.

In this project, the ugliest model was an 800-line revenue mart with nested CTEs seven levels deep. Its author was still at the company, in a different team. One coffee with her explained more than the entire audit week: the nesting existed because billing had changed providers mid-year and both systems had to reconcile to the cent.

Most of what gets labelled "tech debt" was never a skill problem. It was a deadline decision made by someone who knew better, under pressure, without time to write down why.

Once you see it that way, the rescue stops being a cleanup of other people's mistakes and becomes something more useful: turning undocumented decisions into documented ones.

The hardening checklist

With the audit written up, we spent roughly six weeks hardening the project. Not a rewrite - a rescue. About 80% of the models survived with modest changes.

1. Enforce a layered structure

We reorganized into the boring, standard three layers: staging (one model per source table, renaming and typing only), intermediate (business logic, joins), and marts (what BI tools and stakeholders touch). Boring is the point. Anyone who has seen a dbt project before can now navigate this one.

2. Declare sources, test freshness

Half the "pipeline failures" were actually upstream data arriving late. Declaring every input in sources.yml with freshness checks turned mystery failures into named, alarmed, upstream problems:

sources:
  - name: billing
    schema: raw_billing
    config:
      freshness:
        warn_after: {count: 6, period: hour}
        error_after: {count: 24, period: hour}
      loaded_at_field: _loaded_at
    tables:
      - name: invoices
      - name: subscriptions

3. Test the contracts, not everything

We added two standard open-source packages - dbt_utils for the common data quality checks, and Elementary for anomaly detection and alerting - and put tests where they earn their keep: primary keys unique and not null on every staging model, accepted values on status columns, and anomaly detection on row counts for the five business-critical marts. Around 300 tests total - enough to catch real breakage, few enough that a red test still means something.

4. CI on every pull request

Every PR now compiles the project, builds the changed models plus their first-order children into a disposable schema, and runs their tests. Merge is blocked on green. This did more for the team's confidence than any other single change: within a month they went from batching changes into nervous weekly releases to merging small changes most days.

5. Alerts where the team lives

Elementary pipes run results and anomalies into a Slack channel, with an owner tagged per mart. A failure at 6 a.m. is now a Slack message to one accountable human, not a surprise in a stakeholder meeting at 10.

6. Style enforced by robots, not reviews

SQLFluff as a pre-commit hook ended the era of code reviews about comma placement. Humans review logic; the linter reviews style. Nobody has argued about leading commas since, which may be the project's most measurable quality-of-life gain.

Making the project AI-ready

Here is the step most rescues still skip in 2026. A clean dbt project is no longer just for humans - it is context for AI coding agents, and the returns on preparing it are immediate.

The payoff compounds: the client's analysts now use AI assistants to draft staging models and tests, and the assistants are actually good at it - because the project finally tells them what "good" looks like. I've written more about this workflow in how I work as an AI-enhanced data analyst: agents don't get smarter, they get context.

Results

What to take away

If you are inheriting a dbt project: audit before you touch, befriend the author of the ugliest model, and treat tech debt as decisions to be documented rather than sins to be punished. Then harden the boring things - layers, sources, tests, CI, alerts, linting - and write your conventions down in Markdown so both humans and AI agents can follow them.

And once the pipes are trustworthy, point them at something worth measuring - a messy project and a messy metric layer usually travel together, which is why this engagement flowed straight into defining a KPI framework and North Star metric for the same client.

A rescued project is not one with no ugly models. It is one where every ugly model can explain itself.

Inherited a dbt project nobody dares to touch?

Satyadata offers analytics engineering consulting for exactly this: a one-week audit, a prioritized hardening plan, and a pipeline your team - and your AI tools - can finally trust. Let's talk about your project.

Start a conversation