Plan the Funeral Before You Build
Plan the funeral before you write the code. Most teams are great at building and terrible at removing — so every "temporary" flag, every one-off endpoint, every clever abstraction accretes until nobody dares touch it. The fix is a single design-time question: how would we delete this in three years? Ask it before you commit, and the answer reshapes what you build.
Why removal starts at design time
Deletion is decided long before anyone opens a delete PR. As the Google engineering team puts it in Software Engineering at Google, "choices of programming language, software architecture, team composition, and even company policy and culture all impact how easy it will be to eventually remove a system." You cannot retrofit deletability — you either designed for it or you didn't.
Two forces make removal hard, and both are cheapest to fight up front:
- Hyrum's Law. The more consumers a system has, the more of them depend on behavior you never promised, "and the harder it will be to deprecate." A narrow, explicit interface is a small blast radius; a leaky one is a minefield.
- Invisible carrying cost. Maintenance is quiet and continuous; the cost of removal is loud and one-time. That asymmetry is why "funding and executing deprecation efforts can be difficult politically" — the bill for not deleting never shows up on a dashboard.
The design-time questions
Before you write anything new, answer these on paper:
| Question | What a good answer looks like |
|---|---|
| How do I turn this off? | One flag, one config line — not a redeploy across five services. |
| Who will depend on it? | A named, documented interface; internals stay private so no one couples to them. |
| How do consumers migrate off? | A replacement path exists before launch, not after the deprecation email. |
| Can I remove it in pieces? | Yes — the system is decomposable, so deletion is incremental, not big-bang. |
If any answer is "I'm not sure," you've found the part that will be expensive to kill.
Flags are inventory, not free
Feature flags are the classic example of build-cheap, remove-expensive. Martin Fowler's team frames them as inventory with a carrying cost: "It's very important to retire release flags once the pending features have bedded down in production. This involves removing the definitions on the configuration file and all the code that uses them. Otherwise you will get a pile of toggles that nobody can remember how to use." Every flag is a fork in your control flow that someone has to remember to collapse. Add the removal ticket in the same PR that adds the flag.
Power moves
- Write the deletion plan in the design doc. A one-paragraph "How we remove this" section next to "How we build this." If you can't write it, the design isn't done.
- Give every temporary thing an expiry. Release toggles, migration shims, compatibility shims — tag them with an owner and a kill date so they're not silently promoted to permanent.
- Keep the surface area minimal. Every abstraction is a maintenance surface and every dependency is a relationship. When you're tempted to generalize something used once, write the minimal thing instead — it's the version you can delete without archaeology.
- Decommission is a design constraint, not an afterthought. Other engineering disciplines plan a plant's decommissioning while designing it. Software that leaks its implementation everywhere is painful to kill; software designed to be removed stays cheap for its whole life.
Systems that leak implementation everywhere are painful to kill. Ones designed to be removed stay cheap. Ask how you would delete it — and let that answer drive the build.
Resources
- Software Engineering at Google — Deprecation (Ch. 15)
- Martin Fowler — Feature Flag (retiring release flags)
- Feature Toggles (Pete Hodgson) — managing toggle inventory
- Write code that is easy to delete, not easy to extend
Building something new? Yeda AI designs, audits, and ships production LLM systems that stay cheap to change and cheap to remove.