Services Process Blog Demo

Get in touch

hello@sovont.com
Back to blog
· Sovont · 4 min read

The Column You Dropped That Wasn't Actually Dead

Dropping 'unused' columns without lineage visibility is how you break three downstream teams at once — and none of them will tell you until production is already wrong.

Data Engineering

Someone on your team checked the query logs. The column hadn’t been touched in ninety days. The table was already wide. So they dropped it — clean migration, clean PR, clean deploy.

Then the weekly finance reconciliation failed silently. Then an upstream ML feature started returning nulls. Then a data contract your team wrote six months ago started producing schema mismatches no one noticed for two weeks because the monitoring was on the wrong thing.

The column wasn’t dead. It was just quiet.


This is a column lineage problem, and it’s one of the most common ways data teams cause production incidents while following best practices.

Query logs tell you what ran. They don’t tell you what runs quarterly. They don’t tell you what runs on a schedule you don’t control — a vendor export, a BI tool refresh, a downstream model retrain that fires on the fifteenth of each month. They don’t tell you what’s referenced in a dbt model that’s been paused for two sprints because no one needed to touch it. They don’t tell you about the Looker calculation that joins to this table and just returns an empty column instead of erroring.

Absence of recent queries is not proof of absence of dependents. It’s just a gap in your visibility.


The failure modes:

Silent nulls over errors. Many query engines don’t fail when you reference a dropped column — they return null, or they fail only at join time, not at read time. The downstream consumer gets bad data instead of an error. You find out when someone compares last month’s numbers to this month’s.

Quarterly and monthly jobs. Usage logs with a 30 or 90-day lookback are nearly useless for catching these. Finance jobs, regulatory extracts, model retraining pipelines — they run infrequently and they’re exactly the kind of thing no one is thinking about when they’re cleaning up a schema.

Cross-team dependencies you don’t own. Your table is used by the analytics team’s Tableau workbook that gets refreshed on Monday mornings. They didn’t tell you they depended on that column because they assumed it was permanent infrastructure. You didn’t ask because you assumed no one cared about it anymore.

Unversioned external consumers. APIs that expose your data, vendor integrations that pull via query, any consumer that doesn’t have a formal data contract — they will break quietly and blame you loudly.


What actually helps:

Extend your lookback window before dropping anything. Ninety days is not enough. Run a full year of query logs before declaring a column dead. For columns in tables used by finance, compliance, or external systems, require sign-off from known stakeholders before removal.

Build or adopt column-level lineage tracking. Tools like dbt, OpenLineage, or Marquez can map which transformations and models touch which columns. If your stack doesn’t have this, you’re operating blind. That’s fixable — but it requires investment, not just discipline.

Treat schema removals as breaking changes. Deprecate before you drop. Add a notice period. Give downstream consumers time to respond. Mark columns deprecated in your metadata layer and surface the deprecation in your data catalog. If no one complains in 30 days, you still check with stakeholders — you don’t assume silence is consent.

Publish a data contract for any table with external or cross-team consumers. Contracts make dependencies explicit and create a forcing function: if you want to break the contract, you have to coordinate. That coordination is exactly what you’re currently skipping.


Schema hygiene matters. Wide tables with dead columns are a real problem. But the cleanup is only safe when you can see everything that depends on what you’re removing.

You don’t have a dead column problem. You have a lineage visibility problem. Fix that first.