← Back to all articles
Ilya Petrov

When to Delete Code

A gentle argument for removing old paths, stale abstractions, and comments that no longer describe reality.

maintenancerefactoringengineering

Deleting code feels risky because the absence of a thing is harder to inspect than its presence. Yet every unused path adds another possibility a future change has to preserve.

Signs of a removable path

Look for:

  • a feature flag that has been permanently enabled;
  • a fallback for a system that no longer exists;
  • a helper with one caller and no meaningful abstraction;
  • a comment describing behavior that the code no longer has;
  • a test for an intentionally removed requirement.

Delete in small steps

1. Confirm the old path has no active callers.
2. Remove the entry point.
3. Remove tests and helpers that only served it.
4. Build and inspect the diff.
5. Record the reason in the change description.
Question Why it matters
Is it reachable? Dead code may still be called indirectly
Is it documented? Users may depend on an undocumented path
Is it tested? Tests can reveal hidden contracts
Is there a migration? Removal may need a transition period

Deletion is a user-facing improvement

Less code means fewer branches, fewer assumptions, and fewer places for a security fix to be missed. A smaller system is easier to explain and easier to trust.

Maintenance is not only adding support for the future. It is removing support for the past when the past is no longer part of the product.