Skip to content

Chesterton's Fence: Don't Remove What You Don't Understand

Scribelet Team
10 min read

Someone on your team finds a sleep(3) call sitting inside a retry loop in the deploy script. No comment. No ticket reference. Nothing in the commit message but "fix flaky deploy." It looks like dead weight, so they delete it in the next cleanup pass. Three weeks later, deploys start failing intermittently in a way nobody can reproduce locally, and it takes a day of bisecting to find out that the sleep was there to dodge a race condition in a downstream service that still exists.

That is a fence removed by someone who never asked why it was built. The rule that would have stopped this has a name, and it is older than software: Chesterton's fence.

What is Chesterton's fence?

Chesterton's fence is the idea that you should not remove a rule, structure, or restriction until you understand why someone put it there in the first place. It comes from G.K. Chesterton's 1929 essay collection The Thing, in a passage about a reformer who wants to tear down a fence blocking a road:

"There exists in such a case a certain institution or law; let us say, for the sake of simplicity, a fence or gate erected across a road. The more modern type of reformer goes gaily up to it and says, 'I don't see the use of this; let us clear it away.' To which the more intelligent type of reformer will do well to answer: 'If you don't see the use of it, I certainly won't let you clear it away. Go away and think. Then, when you can come back and tell me that you do see the use of it, I may allow you to destroy it.'"

Chesterton was not arguing that fences should stay forever. He was arguing that not understanding a thing is not evidence that it is useless, and it is exactly the wrong basis for a decision to remove it. The reasoning behind a fence almost never gets written down at the moment it matters, which is the same gap Scribelet exists to close, and a thread we come back to at the end.

The parable, restated for people who build things

The fence in the essay is a stand-in for any inherited constraint: a law, a custom, a rule nobody remembers writing. The reasoning transfers cleanly to anything you did not build yourself and don't fully understand, which for most engineers is most of the codebase they work in on any given day.

The failure mode Chesterton describes has two matching versions. One is tearing the fence down blind, the retry-loop story above. The other is refusing to touch anything that looks old or strange, on the theory that it must be there for a reason, which is really just superstition wearing the same coat. Chesterton's actual position sits between them: go find out, then decide.

Chesterton's fence in software engineering

Codebases accumulate fences constantly, and almost none of them come with a sign explaining why they exist. A few shapes show up often enough to be worth naming:

  • A retry, timeout, or sleep with no comment. Someone hit a specific failure once, patched around it under deadline pressure, and never wrote down what the failure was. The code still runs fine, so nobody revisits it until someone "cleans it up."
  • A feature flag or config value nobody remembers flipping. It defaults to something odd. Removing it feels safe because nothing visibly breaks in staging, right up until it breaks in the one account still depending on the old behavior in production.
  • A branch condition that special-cases one customer, one region, or one legacy data format. It reads like leftover cruft. It is often the only thing standing between a clean release and a very expensive support ticket.
  • A "do not touch" comment with no explanation attached. The instruction survived; the reasoning did not. Whoever wrote it assumed the context would stay obvious. It never does.
  • An index, a lock, or an ordering guarantee that looks redundant. Databases and concurrent systems are full of constraints that exist to prevent a specific class of bug that only shows up under load nobody sees in development.

Every one of these looks removable from the outside. That is the trap. The cost of investigating first is a few minutes or a few hours. The cost of guessing wrong is a production incident, and usually one that takes far longer to diagnose than it would have taken to just ask.

When to tear the fence down, and when to stop and dig first

Chesterton's fence is not a blanket instruction to leave everything alone. It is a filter for deciding which changes need investigation before they need action.

SignalWhat it tells you
You can find the commit, PR, or ticket that added it, and the reasoning still appliesSafe to remove once you've confirmed the reasoning is actually gone, not just old
Tests fail immediately when you remove itThe fence is load-bearing; you found the reason the hard way instead of the easy way
Nobody currently on the team wrote it, and there's no comment, ADR, or doc referencing itStop. This is the highest-risk case, because the reasoning may be gone for good
It only affects a code path you can't fully exercise locally (a specific customer, region, or scale)Stop. Absence of a visible effect in your environment is not absence of an effect
The person who wrote it is reachable and remembers whyAsk before you touch it, even if you're fairly sure you already know
It duplicates logic that exists somewhere else in a cleaner formProbably safe, but verify the duplication is actually redundant and not handling an edge case the clean version misses

The pattern underneath the table: the less evidence you have about why something exists, the more investigation it earns before you act on it. A fence with a clear, current, still-valid reason attached is not really a Chesterton's fence problem anymore. It is a fence with a sign on it.

Decision flowchart: found something you don't understand, then two paths, one investigating first when the reason is unknown and one proceeding when the reason is documented and still valid

How to find out why the fence is there

Before you remove anything you don't understand, run through the cheap checks first:

  1. Check git blame and the commit history. The commit message and the diff around it often name the bug or the customer, even when the code comment doesn't.
  2. Search the PR or issue tracker for the file or function name. Reviews and linked tickets frequently carry context that never made it into the code itself.
  3. Check for an ADR, design doc, or runbook that references the area. A decision this consequential sometimes got written down properly, even if the code comment is silent. Architecture decision records exist precisely so this search has somewhere to land.
  4. Ask the person who wrote it, if they're still around. This is the fastest path when it works, and it fails more often than teams expect, because people rotate off projects faster than institutional memory transfers.
  5. Time-box the investigation, then decide. Chesterton's fence is not permission to research forever. Give it thirty minutes to an hour. If you still can't find a reason after a genuine search, that itself is a data point, not a green light: proceed carefully, behind a flag, with a fast rollback path.

None of this is exotic. It is the difference between deleting code and doing archaeology on it first, and the second one is almost always faster than the incident that follows skipping it.

A worked example: the mystery timeout

Say you inherit a service with a hardcoded 45-second timeout on an outbound HTTP call, where every other call in the codebase uses the default 10 seconds. It looks like a typo, or a lazy fix someone never revisited. Here is what investigating first actually looks like in practice.

git blame points to a commit from over a year ago titled "bump timeout for vendor API." The commit message alone tells you something happened, but not what. The PR it belongs to links a support ticket: the vendor's API has a documented cold-start delay after periods of low traffic, and 10 seconds wasn't enough to cover it without dropping legitimate requests. Nothing in the code says any of this. Without the PR link, you'd have deleted the fix for a problem you never knew existed.

Now you have a decision to make, and it isn't "restore the default." It's "check whether the vendor's cold-start problem is still real." A quick message to the team, or a look at the vendor's current status page and changelog, tells you whether that constraint from a year ago still holds. If the vendor fixed their cold-start issue in the meantime, the 45-second timeout is now dead weight and safe to shorten. If they didn't, you just avoided reintroducing a bug that took someone a support escalation to diagnose the first time.

The point is not that the timeout should stay forever. It's that the ten minutes spent finding the PR turned a guess into a decision.

The trap: don't let it become "we've always done it this way"

Chesterton's fence gets misquoted into its opposite more often than almost any other mental model. The reformer's critics in the essay were not arguing to keep the fence forever; they were arguing to understand it first. Turning that into "never remove anything old" is exactly the failure Chesterton was warning against, just aimed the other direction. It is a close cousin of reflexively rejecting new evidence because it contradicts the established way: one defends the old by refusing to examine it, the other dismisses the new by refusing to examine it, and both skip the step where you actually look.

A codebase where every team member cites Chesterton's fence to block every change is a codebase where the fence has become an excuse instead of a filter. The rule only works if the investigation actually happens and actually concludes something. If the answer keeps coming back "we don't know, so let's not touch it," that is not caution, it is unaddressed technical debt with a philosophy quote attached. The same trap keeps stale dashboards alive: a measure that hardened into a target long ago, defended now only because no one remembers what it was ever a proxy for, is a fence worth investigating rather than saluting.

Write down why the fence is there, so nobody has to guess again

The entire premise of Chesterton's fence, that removing something you don't understand is risky, only exists because the reasoning behind decisions doesn't travel with the decision. Someone knew why the retry loop was there. They just didn't write it anywhere durable, and eighteen months later that knowledge is gone even though the code is still running.

This is the same gap that shows up across engineering documentation generally: the code shows you what happens, but rarely why it happens, and the people who could explain the why eventually leave, forget, or move teams, which is really a bus factor problem wearing a different hat. Every fence in your system is a decision someone made under specific constraints that may or may not still hold, and constraints have a way of quietly expiring while the code that encodes them keeps running unchanged. The worst fences are the ones with no real reasoning to recover at all, because the decision was never truly made, just backed into by a group that each assumed the others wanted it. Architectural boundaries have the same problem at a larger scale; a seam that made sense under the org structure that drew it can outlive the org chart that justified it. Treating "why is this here" as a first-class question, the same way a good decision-making framework forces you to record the reasoning up front, is what turns archaeology into a habit instead of a fire drill.

Scribelet exists for exactly this gap. When you capture the reasoning behind a workaround, a config value, or a "don't touch this" the moment you write it, not months later when someone else is staring at it confused, that note becomes the fence's sign. Background agents then re-check what you wrote against reality on a schedule, so if the downstream service that needed the retry gets fixed, or the customer special-case gets migrated off the old format, you get a diff instead of a fence nobody can explain anymore. The boundaries in your system don't have to stay opaque just because the people who understood them moved on.

Getting started

Next time you're about to delete something you don't fully understand, stop for the thirty minutes it takes to find out why it's there. If you can't find a reason after a genuine search, at least write that down too, so the next person doesn't repeat the same investigation from zero. Try Scribelet free and give the reasoning behind your fences somewhere durable to live, before the next person has to learn why the hard way.

Share this article

We use cookies for analytics to improve your experience. Learn more