Why Great Systems Delete Less and Focus More
Hatched by Jaeyeol Lee
May 02, 2026
9 min read
7 views
72%
The hidden cost of trying to remember everything
What if one of the fastest ways to make a system more reliable is to stop making it remember so much? That sounds backward, because most teams assume reliability comes from adding safety nets, more storage, more abstractions, and more options for recovery. But at a certain scale, the opposite becomes true: every extra thing a system is asked to remember creates new failure modes, more coordination, and more confusion about what is actually real.
This is the deeper connection between software design, infrastructure, and product strategy. A system that grows well is not the one that accumulates the most features or preserves the most history. It is the one that is willing to make clear decisions about what matters now, what can be rebuilt, and what should simply not exist. Whether you are designing a messaging platform or choosing how to model data, the same principle keeps appearing in different clothes: clarity scales better than completeness.
Soft deletion is not kindness, it is deferred complexity
Soft delete looks humane. Instead of removing a record, you mark it as deleted and keep it around, just in case. That seems safer than hard deletion, which feels final and risky. But soft delete often becomes a quiet tax on every future decision, because the system must now distinguish between what is present, what is deleted, what is hidden, what is recoverable, and what is accidentally zombie-like but still queryable.
Imagine a library where books are never removed. Instead, some are placed in an invisible room, some have their covers removed, and some are flagged as unavailable but still listed in the catalog. Every librarian, every reader, and every automation layer now has to ask: is this book real, accessible, archived, or gone? The system did not preserve simplicity. It preserved ambiguity.
That ambiguity has cascading effects. Indexes become more complicated, queries get slower, and business logic starts sprouting exceptions. People stop trusting the meaning of a record's presence because presence no longer means present. In other words, soft delete does not just keep data around. It rewrites the semantics of the whole database.
The problem with “keeping it just in case” is that the system does not keep the case. It keeps the uncertainty.
The deeper lesson is not that deletion should always be irreversible. It is that retention and reversibility are architectural choices, not moral ones. If you need auditability, build audit trails. If you need recovery, use backups or event logs. If you need compliance, separate archival storage from live operational state. Do not force one table to play all three roles.
WhatsApp’s real advantage was not just scale, it was subtraction
The surprising thing about a lean messaging system that handles enormous traffic is not merely that it can scale horizontally. Plenty of systems can add machines. The deeper story is that scaling becomes possible when the product is intentionally narrow, the infrastructure choices are opinionated, and the team refuses to blur the boundaries between core function and everything else.
A messaging service that focuses only on messaging avoids the trap of becoming a general purpose platform too early. That matters because every extra feature introduces more states, more edge cases, and more operational burden. The system does not just need to send messages. It may also need to store media, manage presence, sync devices, handle notifications, support delivery semantics, and maintain consistency under load. Each new capability multiplies the cross-cutting concerns that must be managed across the stack.
This is where the architecture becomes philosophical. Horizontal scaling is often celebrated as the magic answer, but scaling is not only a matter of adding servers. It is a matter of making sure the state of the system can be distributed without becoming incoherent. Vertical scaling helps when a machine needs more memory or CPU. Diagonal scaling, the hybrid approach, helps when some bottlenecks are local and some are networked. Yet all of those strategies fail if the product itself is trying to do too much.
The most important scaling decision, then, is not where to place your load balancer. It is what kind of complexity you are willing to carry forward.
Cross cutting concerns are where systems quietly die
There is a reason cross cutting concerns are so dangerous. They do not look like product features, but they shape every feature. Authentication, logging, retries, consistency rules, deletion semantics, deployment safety, data retention, and load testing all cut across the system and force coordination. Once these concerns become entangled, even simple changes require wide knowledge and careful orchestration.
A messaging app that prioritizes product quality must treat these concerns as first class, not as cleanup work. That is why disciplined teams obsess over testing with artificial traffic, controlled DNS changes, and feedback loops from production behavior. They are not just checking if the service works. They are testing whether the system's assumptions still hold when reality pushes back.
This creates a powerful mental model: a system is not defined by its happy path, but by how many hidden dependencies it forces every team to carry in their heads. If deleting a record, scaling a service, or deploying a change requires tribal knowledge, then the system has become cognitively expensive. And cognitive expense always becomes operational expense later.
Think of a restaurant kitchen. A well-run kitchen has stations with clear responsibilities, but it also has a few simple rules that apply everywhere: where ingredients live, how orders are tracked, how burns are handled, when food is discarded. If every station invents its own rules for disposal, cleanup, and inventory, speed collapses. Likewise, in software, cross cutting concerns are manageable only when they are made explicit, narrow, and consistent.
The best systems optimize for recoverability, not nostalgia
A common mistake is to confuse keeping data with keeping options. Those are not the same. Soft delete preserves a kind of nostalgia, a wish that the past can remain available in the operational layer. But operational layers are for current truth, not historical memory. If you want recoverability, you need mechanisms designed for recovery, not a live system burdened with ghost records.
This is where the connection between deletion and scaling becomes unexpectedly strong. Both are about reducing the number of states the system must support at once. A live service becomes easier to scale when it has fewer ambiguous states. A database becomes easier to reason about when deleted means deleted, not maybe deleted unless some flag, filter, or special join says otherwise. In both cases, the win comes from making the system's state space smaller and clearer.
That is why a strong engineering culture tends to value the boring virtues: clear boundaries, explicit ownership, narrow product scope, and ruthless separation of live state from historical archives. These are not conservative habits. They are high leverage design moves that let teams move faster without compounding confusion.
Reliability is often the art of making fewer promises inside the live system and more guarantees outside it.
Consider two organizations. One keeps all old accounts, partially deleted objects, legacy protocols, experimental toggles, and special cases inside the production path. The other aggressively simplifies the hot path and moves history, recovery, and experimentation into dedicated systems. The first company looks safer because nothing is ever truly lost. The second company is actually safer because its current system is easier to test, scale, and understand.
A practical framework: separate live truth, historical truth, and recovery truth
The most useful synthesis here is a simple framework for deciding what belongs where. Many systems fail because they collapse three different kinds of truth into one layer.
- Live truth: what the system needs to know right now to serve users.
- Historical truth: what happened, for audit, analytics, or compliance.
- Recovery truth: what you need to restore the system if something goes wrong.
When these are mixed together, soft delete is often the result. A record is simultaneously active and inactive, present and absent, visible and hidden. But when they are separated, the design becomes cleaner. Live truth stays lean and fast. Historical truth can be append only, searchable, and optimized for reconstruction. Recovery truth lives in backups, snapshots, or event streams, where it does not contaminate the operational model.
This framework also clarifies product strategy. A messaging app that tries to make every historical message behave like live state will eventually drown in edge cases. A database model that tries to preserve every deleted thing inside the active schema will eventually force every query to become a detective story. The problem is not memory itself. The problem is mixing memory with action.
If you want a simple test for whether a system is drifting in the wrong direction, ask: Does this thing need to participate in the day to day logic of the product, or does it only need to exist somewhere safely? If the answer is the latter, it probably does not belong in the hot path.
Key Takeaways
- Delete from the live system when you can. If the data is no longer operationally relevant, move it to archival or backup storage instead of preserving it with a soft delete flag.
- Keep the hot path narrow. Every extra feature in the core product increases cross cutting complexity and raises the cost of scaling.
- Separate three kinds of truth. Live truth, historical truth, and recovery truth should not be forced into the same table, service, or workflow.
- Design for clarity under load. A system that is easy to reason about at low traffic is not necessarily ready for real scale unless its semantics stay simple when pressure rises.
- Test the assumptions, not just the code. Load tests, artificial traffic, and controlled infrastructure changes reveal whether your architecture can survive reality.
The real lesson: systems scale by refusing to blur
The deepest connection between deletion policy and large scale messaging is not technical, but conceptual. Both reveal that growth punishes vagueness. The more users, messages, records, and deployment events a system must handle, the more expensive every ambiguous decision becomes. A soft delete that felt harmless at small scale becomes a source of confusion, just as a broad, feature heavy product becomes harder to operate than a focused one.
The instinct to preserve everything comes from fear: fear of losing data, fear of making the wrong call, fear of having to rebuild later. But mature systems do not eliminate risk by hoarding complexity. They manage risk by placing complexity where it belongs. Live systems should be clean enough to trust. Historical systems should be rich enough to inspect. Recovery systems should be strong enough to restore.
That is the real reframe: good engineering is not about keeping more of everything. It is about making sure each kind of thing lives in the right place. Once you see that, soft delete stops looking like a safe compromise and starts looking like a symptom of architectural confusion. And scaling stops being a story about bigger machines and starts being a story about disciplined simplification.
In the end, the systems that last are not the ones that remember most. They are the ones that know exactly what deserves to stay alive.
Sources
Hatch New Ideas with Glasp AI 🐣
Glasp AI allows you to hatch new ideas based on your curated content. Let's curate and create with Glasp AI :)
Start Hatching 🐣