Let me tell you about a junior engineer called Sam.

Sam had been on the team about four months when I noticed something in a pull request. Tucked between two routine model changes was a new schema.yml entry — five accepted_values tests on a column called customer_status that had been silently accumulating fourteen different spellings of “active” for the better part of a year.

Nobody asked Sam to do this. It wasn’t in a sprint. There was no Jira ticket. Sam had just been working in that part of the warehouse, noticed the mess, and decided to clean it up on the way through.

I left a comment on the PR: “Nice catch.” Sam’s reply was almost apologetic — “Hope it’s okay that I added these, I wasn’t sure if I was supposed to.”

That response stuck with me. I wasn’t sure if I was supposed to.

Here was someone who’d spotted a real problem, built a real solution, tested it, and shipped it — and their instinct was to wonder whether they had permission. Not whether the fix was correct. Not whether the tests were well-written. Whether they were allowed.

I’ve thought about that moment a lot since, because it captures something I see in almost every data team I work with. The people closest to the problems — the ones running the queries, staring at the nulls, fielding the Microsoft Teams messages when dashboards look wrong — are often the last to believe they can do anything about it. Not because they lack skill. Because somewhere along the way, they absorbed the idea that fixing things is someone else’s job.

That belief is expensive. And it’s wrong.

I’m telling you this because data quality — the real, unglamorous, column-by-column work of making data trustworthy — is one of those things that sounds like a senior engineering problem until you see a four-month-old team member fix something a dozen experienced engineers walked past every day. It doesn’t take authority. It takes the willingness to act before you’re told to.

This article is about how to be more like Sam. Five tactics you can start this week — no permission required — backed by real case studies from companies like Airbnb, Google, and Warner Bros. Discovery that figured this out the hard way.




The $12.9 million reason your quality problem isn’t “too small” to fix


Before we get into tactics, let’s talk about why your “small” fix matters more than you think.

Gartner pegs the average annual cost of poor data quality at $12.9 million per organisation. IBM and Harvard Business Review put the aggregate U.S. cost at $3.1 trillion annually. These numbers feel abstract until you realise what they actually represent: knowledge workers spending roughly half their time hunting for data, correcting errors, and searching for confirmatory sources instead of doing their actual jobs.

Monte Carlo’s 2024 State of Data Quality survey found bad data now impacts 31% of company revenue on average — up from 26% just two years earlier. Their 2022 survey found data engineers spend 40% of their time evaluating or checking data quality. Soda’s research put that number even higher: 61% of data engineers spend half or more of their time handling data issues.

And the human cost? A DataKitchen survey of 600 data engineers found 87% are frequently blamed when things go wrong with data. 78% wish their job came with a therapist.

The implication for you: the problem is so large and so costly that any measurable improvement you create has real dollar value attached to it. That null check you added last Thursday? That’s not a minor fix — it’s a tiny piece of a multi-million-dollar problem that nobody else bothered to address.




Tactic 1: write tests for your own models without asking anyone


The single best case study for this tactic comes from Airbnb, and it didn’t start with a VP mandate or an OKR. It started with one engineer.

Airbnb’s engineering blog documents how they went from “an engineering culture in which most new code shipped without a single test” to one where proposing a change without tests got called out immediately. The transformation wasn’t top-down. As the blog explains: “One approach is to rule by edict, but given our culture of engineer autonomy this would have been very poorly received. The other approach is to lead by example and build a movement.”

That single champion’s playbook was remarkably tactical. They spoke in engineering meetings. They held office hours showing teammates how to write tests. They published a weekly newsletter highlighting well-written test specs — giving public credit to engineers who included tests. They revamped the testing bootcamp for new hires, effectively making each new hire a champion. They improved tooling, reducing CI build times from over an hour to roughly six minutes.

The result? Airbnb later applied the same grassroots philosophy to data quality, building a DQ Score on a 0–100 scale across their entire warehouse. Their anomaly detection system now prevents quality issues in new pipelines before they reach production. The Minerva metrics platform manages 12,000+ metrics and 4,000+ dimensions with 200+ data producers.

One engineer. No mandate. A newsletter and some office hours.

What this looks like for you

If you’re working with dbt, you already have the tools. dbt ships with four built-in generic tests — not_null, unique, accepted_values, relationships — that you define in YAML alongside your model definitions. No framework to build. No proposal to write. Just add a few lines to your schema.yml:

models:
  - name: dim_customers
    columns:
      - name: customer_id
        tests:
          - not_null
          - unique
      - name: customer_status
        tests:
          - accepted_values:
              values: ["active", "inactive", "churned", "suspended"]
      - name: email
        tests:
          - not_null

That’s it. Next time the pipeline runs, those tests execute automatically. If someone pushes a change that breaks uniqueness on customer_id, the pipeline catches it before it reaches production.

The dbt-expectations package goes further, porting Great Expectations’ advanced tests into dbt. Unit tests — introduced in dbt v1.8 — let you validate SQL logic with static mock inputs before transformations run. Tests integrate directly into CI/CD, blocking PRs with failures from reaching production.

Not on dbt? You can still write assertion queries. Here’s a completeness check you can run against any SQL database — no framework required:

-- Quick completeness check: what percentage of each critical
-- field is actually populated?
SELECT
    COUNT(*) AS total_records,

    -- How many emails do we actually have?
    ROUND(100.0 * COUNT(email) / COUNT(*), 1) AS email_pct,

    -- How many phone numbers?
    ROUND(100.0 * COUNT(phone) / COUNT(*), 1) AS phone_pct,

    -- How many addresses?
    ROUND(100.0 * COUNT(address_line_1) / COUNT(*), 1) AS address_pct,

    -- Flag: are we below the 95% threshold on anything critical?
    CASE
        WHEN COUNT(email) < COUNT(*) * 0.95 THEN 'BELOW THRESHOLD'
        ELSE 'OK'
    END AS email_status
FROM
    main.customers;

Schedule that to run daily. Store the results in a logging table. You’ve just built a monitoring system — and you didn’t ask anyone’s permission.

The numbers back this up

Monte Carlo’s 2022 survey found that organisations conducting at least three types of data tests weekly experienced 46 incidents per month compared to 61 incidents per month for less rigorous testers — a 25% reduction. The Forrester Total Economic Impact study of data observability platforms (April 2025) found 358% ROI, 6,500+ data personnel hours reclaimed annually, and $1.5M+ in avoided lost revenue from reduced data downtime.

Daniel Beach of Data Engineering Central offers a pragmatic path for getting started: begin with end-to-end tests first when inheriting a pipeline with no tests, then add data quality checks, then unit tests. You don’t need to boil the ocean. You need to start.




Tactic 2: document one thing every time you touch it


The numbers on missing documentation are genuinely staggering. According to DX, developers spend 3–10 hours per week searching for information that should be documented. For a 100-person engineering team, that equals 300–1,000 hours weekly — the equivalent of 8–25 full-time engineers doing nothing but hunting for answers. Stack Overflow’s developer survey found 62% of developers spend over 30 minutes daily on poorly documented issues. And 38% listed poor documentation among their top reasons for leaving a company.

One practitioner tracked “Time to First Production Commit” at 28 days for new engineers — versus an industry benchmark of 3–5 days. Engineers on that team spent 30% of their time rediscovering what previous engineers had already learned. 40% of sprint tickets required inter-team clarification, averaging 12 clarifications per ticket.

This is what documentation debt looks like. Not a gap in a wiki — a tax on every single person who touches the codebase.

“Documentation Fridays” don’t work. This does.

Multiple sources confirm that big-bang documentation efforts fail. As one case study puts it: “‘Okay team, let’s spend Friday afternoon documenting our processes!’ Nobody wants to do that. And it doesn’t work.”

The successful pattern is document-as-you-go. Every time you encounter an issue, you write it down. Shopify Engineering treats documentation as a product, explicitly encouraging new team members to fill documentation gaps from day one. Their philosophy: “The most effective way to encourage others to write is to actually write.”

For data teams specifically, the approach is even simpler. If you’re using dbt, column descriptions live in schema.yml alongside your model definitions. dbt’s column-level lineage means passthrough and renamed columns automatically inherit descriptions from upstream models. Write a description once, and it flows downstream through every model that references that column.

Here’s what this looks like in practice:

models:
  - name: dim_customers
    description: >
      One row per customer. Grain: customer_id.
      Source: CRM extract via Fivetran, refreshed daily at 03:00 UTC.
      Owner: data-eng-team@company.com
    columns:
      - name: customer_id
        description: "Primary key. Sourced from CRM.contacts.id. Unique, never null."
      - name: customer_status
        description: >
          Current lifecycle status. Valid values: active, inactive, 
          churned, suspended. Updated by CRM webhook on status change.
          Known issue: legacy records from pre-2023 may contain 
          'Active' (capitalised) — normalised in this model.
      - name: lifetime_value
        description: >
          Cumulative revenue attributed to this customer, in AUD.
          Calculated as SUM(order_total) from fct_orders.
          Excludes refunded orders. Updated daily.

That “Known issue” note on customer_status? That’s worth its weight in gold to the next person who touches this model. It took thirty seconds to write and it’ll save hours of confusion.

Microsoft’s engineering blogs describe the alternative bluntly: “When tribal knowledge holders leave, reverse engineering is the only way to understand what was done.” Enboarder’s 2025 research found 47% of organisations cite institutional knowledge loss as their top offboarding challenge. Atlan’s Modern Data Survey found data professionals waste one full day per week simply trying to figure out what data to use.

You don’t need to document the entire warehouse. You need to document the thing you touched today. Tomorrow, document the next thing. In three months, you’ll have built something genuinely valuable — and you’ll have done it one commit at a time.




Tactic 3: build a quality dashboard nobody asked for


At Warner Bros. Discovery, the DICE team built data quality management frameworks and created a “Data Quality Forum” that became a bridge between teams. During the Olympics livestream, they used custom SQL checks to detect missing content metadata — fixing issues before they broke reporting. The forum evolved into what Pam Zirpoli called a “cultural flywheel.” Patterns surfaced in the forum were incorporated into onboarding, translated into new monitors, and used to refine their priority matrix. Teams shifted from reactive — reacting after dashboards broke — to proactive.

At Tempus, a data engineer documented how adopting Elementary (an open-source dbt package) transformed their monitoring. Before: “test alerting relied on a dashboard in Data Studio built on top of a log sink, and the ‘alerts’ were a daily email that you actually had to open.” After: Microsoft Teams alerts that “@-ed a user and continued to do so until they’re turned off.” The key outcome: tests no longer fail silently.

The six metrics that actually matter

Drawing from IBM, dbt Labs, Databricks, and Alation, the consensus metrics for data quality monitoring are:

  • Freshness: time since last data update. If your orders table hasn’t been updated since yesterday, something’s broken.
  • Volume: expected versus actual row counts. Did today’s load bring in 50,000 rows when you normally get 48,000–52,000? Fine. Did it bring 12? Problem.
  • Schema changes: added, deleted, or altered columns. These should never surprise you.
  • Completeness: null rates per column. Simple COUNT(*) vs COUNT(column) tells you a lot.
  • Distribution shifts: statistical changes in data values. If the average order value suddenly doubles, that’s worth investigating.
  • Test pass/fail rates: the percentage of your quality assertions that are passing. Track this over time.

Here’s a freshness check you can run right now — no tools, no frameworks, just SQL:

-- How stale is each of your critical tables?
-- Run this daily and store results in a monitoring table
SELECT
    'fct_orders' AS table_name,
    MAX(updated_at) AS last_record_timestamp,
    CURRENT_TIMESTAMP AS checked_at,
    ROUND(
        EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - MAX(updated_at))) / 3600.0,
        1
    ) AS hours_since_update,
    CASE
        WHEN MAX(updated_at) IS NULL THEN 'CRITICAL - No data'
        WHEN CURRENT_TIMESTAMP - MAX(updated_at) > INTERVAL '24 hours'
            THEN 'STALE - Exceeds 24hr SLA'
        WHEN CURRENT_TIMESTAMP - MAX(updated_at) > INTERVAL '12 hours'
            THEN 'WARNING - Approaching SLA'
        ELSE 'FRESH'
    END AS freshness_status
FROM analytics.fct_orders;

Store that in a data_quality_log table, connect it to Looker Studio or Metabase (both free), and you’ve got a monitoring dashboard. That’s it. No Kubernetes cluster. No proposal document.

Visibility changes behaviour

Anna Geller documented how sending data quality alerts to a shared Microsoft Teams channel transforms team behaviour. Her core insight: “As social creatures, we are more motivated to fix issues if other people can see the effort we put into it.” Data owners reply with root cause analysis, add checkmarks, or link tickets — creating a social proof loop that issues are no longer ignored.

This isn’t just anecdotal. Research on the Hawthorne effect shows healthcare hand hygiene compliance increases by up to 70% when workers know they’re observed, and employees increase productivity by an average of 13% when activity is monitored. Making data quality visible doesn’t just inform people — it changes their behaviour.




Tactic 4: create a #data-bugs channel


MIT Sloan Management Review’s HelloFresh case study documents one of the best examples of how visibility catalyses organisational change. HelloFresh transitioned through three modes of data quality management. In Mode 1, issues were dealt with reactively by whoever happened to be affected. In Mode 2, a central engineering team handled cleanup but lacked understanding of how data was actually used — “data customers grew increasingly frustrated as they continued to spend large fractions of their workdays dealing with data that did not meet their needs.”

The transition to Mode 3 — proactive, collaborative quality management — happened precisely because “quality issues became increasingly visible.” Not because someone wrote a strategy doc. Not because a VP mandated it. Because the problems became impossible to ignore.

You can accelerate that transition. Create a Microsoft Teams channel. Call it #data-bugs or #data-quality or whatever feels natural. Start posting issues you find — with specifics. Not “the data looks wrong” but “fct_orders has 3,247 rows with null customer_id from the 2026-02-15 load, affecting the weekly revenue dashboard.”

That’s it. You’ve just created the visibility mechanism that HelloFresh spent years arriving at.

The broken windows effect is real — and it’s been measured

The Pragmatic Programmer introduced the “broken windows” software analogy decades ago: “Don’t leave ‘broken windows’ (bad designs, wrong decisions, or poor code) unrepaired. Fix each one as soon as it is discovered.”

This isn’t just metaphor anymore. A 2024 arXiv paper by Diomidis Spinellis et al. analysed 2 million code commits across 122 projects comprising 5.5 million lines of code. The key finding: “History matters — developers behave differently depending on some aspects of the code quality they encounter.” Developers tailor the quality of their commits based on the quality of the file they’re committing to. Low quality begets lower quality. High quality attracts higher quality.

Mat Ryer extends this to everyday engineering: “If you work on a project that has flaky tests, then you’re more likely to add more flaky tests. If there is a hacky design, you’re more likely to hack more in.”

Fixing one visible data quality issue — or even just making it visible — can interrupt the decay spiral.

Why juniors don’t speak up (and why that’s exactly the problem)

Here’s the uncomfortable part. A Culture Shift UK survey found junior colleagues were twice as likely (54%) as senior leaders (27%) to say speaking up about issues is “pointless.” 37% said speaking up “isn’t worth the personal risk.” A Blind survey found 58% of tech workers experience imposter syndrome.

Google’s Project Aristotle studied 180+ teams over two years and found psychological safety was “by far the most important” of five dynamics for team effectiveness. Amy Edmondson’s foundational research contains a striking finding: while studying hospital teams, she expected high-performing teams to report fewer errors. Instead, better teams reported MORE errors. Her insight: “Maybe the good teams don’t make more mistakes, maybe they report more.”

This is the paradox. The teams that look like they have the most data quality issues are often the healthiest — because they’ve created an environment where problems surface instead of festering.

Etsy pioneered blameless postmortems under CTO John Allspaw. Engineers send company-wide emails confessing mistakes. Etsy even gives out an annual “three-armed sweater” award to the employee who made the most surprising error. As a Hadley Wickham–curated Stanford reading list notes, while blameless postmortems are standard in DevOps, they “have not yet infiltrated standard data science practices.” That’s a gap you can help fill.

Creating a #data-bugs channel isn’t just about tracking issues. It’s about establishing the norm that finding problems is good work, not a sign that something’s wrong with you.




Tactic 5: ship an example, don’t write a proposal


Marcus Blankenship’s article on learned helplessness in software engineering — 96,000+ reads, 900+ Reddit comments — contains a story about a coworker called Milind. Milind wasn’t a manager. He didn’t have a fancy title. But he was an informal leader through pure action. He asked questions about why particular approaches were taken. He admitted ignorance in group settings. He insisted the team understand root causes before moving on.

Blankenship’s observation: “Milind changed our environment by his actions… He showed me that I had much more power than I thought, if I would only stop expecting to be spoon-fed everything. His actions showed me that true leadership isn’t granted, it’s grasped.

A junior engineer on Irina Stanescu’s newsletter shared something similar: “Even as a junior engineer, I remember influencing my chief architect and brought Terraform into my organisation 7 years ago by simply pointing out a common pain point and how much longer things took without managing our infrastructure in code.” They added: “Being able to influence without authority is a very underrated skill, and I believe this is what helped me get promoted to senior engineer even more than my technical skills.”

The pattern is consistent. Don’t propose a data quality framework. Don’t write a 15-page RFC. Build the thing. Make it work. Show people.

Why working examples spread faster than proposals

Everett Rogers’ Diffusion of Innovations theory identifies five characteristics that determine how fast an idea spreads: relative advantage, compatibility, complexity (lower is better), trialability, and observability. A working example maximises both trialability and observability — the two factors most under your control as a junior engineer.

A proposal says “we should do this.” A working example says “look, I already did this, and here’s what happened.” One requires people to imagine the benefit. The other puts the benefit directly in front of them.

Addy Osmani, after 14 years at Google, captured the complementary lesson: “Early in my career, I believed great work would speak for itself. I was wrong. Code sits silently in a repository.” You need to build the example and make its impact visible. Post in Microsoft Teams. Show the before and after. Quantify what changed.

The junior advantage nobody talks about

Ant Weiss’s widely-read article on organisational learned helplessness identifies common symptoms: “This is how we were told to work,” “These are the limitations of the system,” “We don’t have the resources.” His core observation: “No engineer starts their career willing to be unproductive, pessimistic and stressed out. But the companies they work at teach them to.”

The cure, drawn from Seligman’s original research, is critical: “Threats, rewards, and observed demonstrations had no effect on the ‘helpless’ dogs. The dogs had to be physically moved through the escape action at least twice before they would do it themselves.” You can’t just tell engineers things can be better. You have to walk them through the experience of making something better.

Here’s the part that should give you confidence. JazzTeam reports a remarkable finding: “To prove that any problem can be solved, our team many times gave a task to Junior and even Intern Engineers who did not have psychological fears and tunnel thinking.” Juniors, unencumbered by years of “that’s impossible” conditioning, were able to tackle problems seniors had declared unsolvable.

Your fresh eyes aren’t a weakness. They’re an asset. You haven’t yet learned that “it can’t be done.” So go do it.




Putting it all together


None of these tactics require a committee meeting. None require architectural approval. None require you to be senior.

Here’s what they do require: the willingness to act before you’re told to.

Write a test this week. Add a column description tomorrow. Build a freshness check and schedule it. Create a Slack channel and post the first issue. Turn one of your quality checks into a reusable example your team can copy.

DORA’s research — surveying 39,000+ professionals — finds that with focused effort and the right tooling, teams typically see measurable improvements within 1–3 months. A GitHub engineer who went from junior to mid-level in 2.5 years described the compound effect: “If I got stuck on some undocumented functionality, I made sure to update the docs and let the team know. Tackling a tricky bug requiring cross-team collaboration? I’d summarise everything we discovered so that it would be easier for others later. Post about it in Microsoft Teams and highlight its impact.”

Kevin Workman, a former Google engineer, captured the mindset that makes all of this work: “Realising that I had agency and even a responsibility to advocate for my ideas is one of the most important lessons I learned on my journey to becoming a ‘senior’ software engineer… Some of the most interesting and most successful moments of my career have come from advocating for changes I thought nobody would agree to.”

I think about Sam sometimes — that four-month-old team member whose instinct was to apologise for fixing something. The tests Sam added that day caught three data quality issues in the following month. Other engineers started adding their own tests alongside model changes. Six months later, the team had 200+ automated quality checks running on every pipeline, and the weekly “data looks wrong” Microsoft Teams messages had dropped to nearly zero.

Sam never got a mandate. Never wrote a proposal. Never waited for Q3.

The data quality problem in your organisation is a $12.9 million issue wearing a “we’ll get to it in Q3” disguise. And you — yes, you, the person who’s been here five months and noticed fourteen spellings of “active” — are exactly the right person to start fixing it.

Not because someone gave you permission. Because the data doesn’t care about your title.