How to avoid storing data you do not need.

•

•

The Safest Data Is the Data You Never Kept

I remember sitting in a dim home office at 3:14 AM, staring at a dashboard while a database migration choked on a table that shouldn’t have even existed. We weren’t even using half the columns in that schema, but they were there because someone, somewhere, thought “we might need this later.” That’s the trap. Most people treat storage like it’s infinite and free, but I’ve learned that the cost isn’t just the monthly AWS bill; it’s the cognitive load and the sheer friction of maintaining a graveyard of useless information. If you want to learn how to avoid storing data you do not need, you have to stop thinking like an archivist and start thinking like a plumber.

I’m not here to sell you on some high-level architectural framework or a shiny new governance tool that requires three months of meetings to implement. Instead, I want to share the practical, somewhat painful lessons I’ve picked up from years of cleaning up production messes. I’ll show you how to build intentionality into your data lifecycle from the very first commit, so you aren’t left debugging a bloated system in the middle of the night.

Table of Contents

Why Bloated Databases Are Your Biggest Production Liability

Why Bloated Databases Are Your Biggest Production Liability

I’ve seen it happen more than once: a database that was manageable during the MVP stage starts to grow like a weed once you hit scale. Suddenly, your backups take twice as long, your index rebuilds are a nightmare, and your queries that used to take milliseconds are crawling because the engine is wading through petabytes of historical junk. It isn’t just a performance issue; it’s a massive liability. When you keep everything “just in case,” you aren’t being prepared—you’re just increasing the surface area for disaster.

The real headache hits when something actually goes wrong. If a malicious actor gains access to your environment, the damage isn’t just proportional to what they can steal right now, but to everything you’ve ever collected. By failing to implement strict data retention policies, you are essentially handing them a treasure trove of stale user info that should have been purged years ago. I’ve learned that reducing data breach impact is often more effective when you simply don’t have the data to lose in the first place. It’s much easier to explain to a stakeholder why a specific table was empty than to explain why five years of unencrypted, unnecessary logs were leaked.

Reducing Data Breach Impact Before the Crisis Hits

Reducing Data Breach Impact Before the Crisis Hits

I used to think that having more data was a safety net, but after seeing a breach at my old logistics startup, I realized it’s actually a liability. When the attackers got in, they didn’t just take what they needed; they took every scrap of historical user data we had “just in case.” If we had followed basic GDPR data minimisation principles and actually purged those old records, the blast radius would have been significantly smaller. You can’t lose what you don’t have.

The reality is that reducing data breach impact isn’t just about better firewalls or more complex encryption; it’s about aggressive hygiene. I’ve found that the most effective way to handle this is to move away from manual cleanup and toward automated data deletion workflows. If you wait for a human to remember to run a cleanup script, you’ve already lost. I prefer setting up TTL (Time To Live) values at the database level or using scheduled jobs that treat data like milk—if it’s past its expiration date, it gets tossed immediately. It’s a bit of extra engineering work upfront, but it beats explaining a massive data leak to the legal team at 4 AM.

Five ways I stopped treating our database like a digital junk drawer

  • Stop using “catch-all” JSON blobs for everything. I used to think storing unstructured data was a shortcut to speed, but it’s actually just a way to hide technical debt. If you don’t know exactly what’s in a field, you can’t prune it, and eventually, you’re paying to store garbage you can’t even query.
  • Set an expiration date on your data at the moment of creation. If a log entry or a session object doesn’t have a TTL (Time To Live) defined in its schema, it’s basically a permanent resident. I’ve learned that if you don’t explicitly decide when data dies, it will live forever and eventually crash your indexing service.
  • Audit your telemetry with a cynical eye. We often log entire request payloads “just in case” we need to debug something later. Most of that data is useless 99% of the time, but it’s still eating up IOPS and storage. If you aren’t actively using a specific field for a business requirement or a critical alert, stop writing it to the disk.
  • Implement a “deletion-first” mindset during schema design. When I’m sketching out a new service, I try to ask “what happens if we lose this field in six months?” if the answer is “nothing much,” then we probably shouldn’t be collecting it in the first place. It’s much easier to not store data than it is to try and surgically remove it from a multi-terabyte table later.
  • Watch your staging and dev environments. It’s easy to let production-sized datasets leak into lower environments for “realistic testing.” This doesn’t just increase your cloud bill; it creates a massive security footprint of data that shouldn’t even be there. Use synthetic data or scrubbed subsets instead of just cloning the whole production dump.

The TL;DR for the Next Person

If you aren’t actively using a piece of data to drive a business process or a feature, it shouldn’t be in your primary database; treat storage like a high-interest loan, not a free resource.

Implement automated TTLs (Time To Live) or expiration policies early in the development cycle—relying on a manual “cleanup script” written by a developer who will eventually leave the company is a recipe for a disk-full outage.

Audit your logging levels in production; a “debug” flag left on in a high-traffic environment is just a slow-motion way of filling up your expensive SSDs with useless noise.

The Long View on Data Hygiene

The Long View on Data Hygiene concept.

At the end of the day, avoiding data bloat isn’t about following some abstract compliance checklist or being a purist about storage costs. It’s about reducing your blast radius. Every extra column in a table and every legacy JSON blob sitting in a cold storage bucket is just another potential liability waiting for a misconfigured permission or a rogue script to turn it into a crisis. If you implement strict TTLs, automate your cleanup scripts, and—most importantly—start asking “do we actually need this?” during the design phase, you aren’t just saving money on your AWS bill. You are building a system that is fundamentally easier to defend when things inevitably go sideways.

I’ve spent enough nights staring at flickering monitors to know that complexity is the enemy of sleep. You can try to build the most sophisticated monitoring stack in the world, but it’s much more effective to simply not have the junk in your system to begin with. Treat your data like a heavy backpack on a long cycling trip; if you carry everything “just in case,” you’re going to burn out long before you reach the summit. Aim for a lean, intentional architecture. It might feel like extra work now, but your future self—the one getting paged at 3 AM—will definitely thank you for it.

Frequently Asked Questions

How do I actually identify which data is "dead weight" without accidentally breaking a downstream service that relies on a field I thought was unused?

I’ve spent too many nights staring at a broken pipeline because I deleted a “useless” column that a legacy reporting service was secretly scraping. Don’t just delete; observe. I use database audit logs and query telemetry to see who is actually touching what. If your infra doesn’t track field-level access, you’re flying blind. My rule of thumb: if you can’t prove a field hasn’t been queried in ninety days, treat it like a live wire.

At what point does the engineering cost of building a robust data retention policy outweigh the actual risk of keeping the data?

It’s a sliding scale, but the math changes once you hit the “compliance or death” threshold. If you’re just cleaning up old user preferences, it’s a low-priority chore. But if you’re sitting on PII that triggers GDPR or PCI-DSS audits, the cost of building an automated deletion pipeline is almost always cheaper than the legal fees or the fine. If you can’t automate the cleanup, you’re just accumulating technical debt that eventually pays out in a crisis.

How do you handle the "just in case" mentality from product managers who want to keep everything for future analytics?

I’ve been in these meetings. The “just in case” argument is usually a proxy for “I don’t know what we need yet.” My approach is to stop arguing about the data and start talking about the cost of the mistake. I tell them: “We can store this, but it’s going in a cold S3 bucket, not our production DB.” If they want it in the live system, they need to define the query that justifies the storage overhead.

What's the safest way to prune massive production tables without causing a locking nightmare or a massive spike in replication lag?

Don’t try to run a single `DELETE` statement with a massive `WHERE` clause. You’ll lock the table, spike your replication lag, and probably get paged at 3 AM.

Tomasz Wierzbicki

About Tomasz Wierzbicki

I am not interested in arguing about frameworks. I am interested in why the thing broke at two in the morning and what would have prevented it. Most of what I know came from being wrong in production and writing it down afterwards.