Back to blog
Article

The docs that survive two years and the ones that rot in a month

The docs that survive two years and the ones that rot in a month
S

StriveBit

3 min readField Notes

The docs that survive two years and the ones that rot in a month

We inherited a Laravel app last year where the previous agency had left a 40-page Confluence wiki. It covered architecture philosophy, team values, and a diagram of their "service mesh vision." None of it matched the code. The deployment section referenced a Forge server we couldn't find credentials for, the job queue section described Redis when the app was actually running on SQS, and the section on their CI pipeline was last updated before a migration to GitHub Actions that happened eight months prior.

But tucked in the repo's README, there was a single paragraph: "The payments table uses `transaction_ref` as the external ID. If it's null, the payment hasn't been reconciled yet. Don't delete rows — mark them `voided` or the accounting export breaks." That paragraph saved us two days of archaeology. The author had written it during a fix, four months before they left the project, because they'd hit the bug and didn't want the next person to hit it again.

The difference between documentation that lasts and documentation that rots is almost always whether the author was describing a decision or describing a state.

State documentation rots. Architecture diagrams, infra topology, "this service runs on ECS with 2 tasks," the list of endpoints, the ER diagram. These are snapshots. The day someone scales to 4 tasks or adds an endpoint, the doc is wrong and nobody updates it. We've written these ourselves and we've watched them die. The problem is that state docs look thorough — a reviewer sees a big diagram and assumes the project is well-documented. But a thorough description of the wrong state is worse than no documentation, because it delays the moment you realize you need to go look at the actual code.

Decision documentation survives. The deployment script that someone wrote because the existing one broke on a Tuesday — and the note they left explaining that the `ARTISAN_QUEUE` env var has to be set *before* the migration runs, because Laravel queues the job before the schema is ready. The `nginx.conf` rule that strips a trailing slash from the admin path because the React router chokes on it. These are things you learn once, at a cost, and the doc is how you avoid paying that cost again.

When we hand over a project now, we write almost nothing about state. The infra is in Terraform — that's the source of truth. The endpoints are in OpenAPI. The ER diagram is in the migrations. We write a lot about decisions. The README has a section called "Things that surprised us" — we log the gotchas we hit during the build, the workarounds we chose and why we chose them over the alternatives, and the places where we deviated from a library's defaults.

A recent example: we built a SaaS dashboard for a Noida client using their existing auth provider, and the `AUTH0_CONNECTION` for their social login has to be lowercase or it silently fails. The provider's docs say it's case-insensitive. It is not, not for their tenant. We wrote that down in the repo, with the ticket number from their support team, and we'll remember it when we do the tenant migration next quarter.

The test for whether a doc will last two years: does it describe something true about how the system works, or does it describe how the system is configured? Configuration changes. Truths accumulate.

Back to all articles

Ready to build something great?

We help ambitious teams build software that lasts. If you're interested in working with us or want to discuss your project, let's connect.

Get in touch