4 min read
On this page

Keeping Docs Alive

Stale docs are worse than no docs. No docs tell the developer "you are on your own." Stale docs tell the developer "turn left" when the road now goes right. They create false confidence, waste debugging hours, and erode trust in all your documentation — even the parts that are accurate. Doc rot is not a possibility. It is a certainty unless you actively fight it.

How Doc Rot Happens

Documentation does not go stale because writers are lazy. It goes stale because the systems that produce code changes do not include documentation changes. The root cause is structural, not cultural.

The typical doc rot timeline:

  Month 1:  Feature ships. Docs are written. Everything matches.
  Month 3:  Small refactor changes a parameter name. Nobody
            updates the docs because the PR was "just a refactor."
  Month 6:  New endpoint added. Docs for the new endpoint exist,
            but they reference the old parameter name from Month 3
            because the writer copied from existing docs.
  Month 9:  A developer reports that the docs are wrong. The team
            fixes that one page.
  Month 12: Half the docs have small inaccuracies. Developers
            learn to distrust the docs and read source code instead.
  Month 18: Nobody updates the docs because "nobody reads them
            anyway."

This is a death spiral, and it starts with a single undocumented change.

Docs-as-Code

The single most effective defense against doc rot is treating documentation the same way you treat code: stored in version control, reviewed in pull requests, tested in CI, and deployed automatically.

Docs-as-code principles:
  - Docs live in the same repository as the code they describe
  - Docs are written in plain text (Markdown, reStructuredText, AsciiDoc)
  - Docs go through the same review process as code (pull requests)
  - Docs are built and deployed by the same CI/CD pipeline
  - Docs have tests that verify accuracy

Same Repo, Same PR

The most important practice: documentation changes ship in the same pull request as the code changes they describe. Not in a follow-up PR. Not in a ticket for later. In the same PR.

Good PR:
  Title: Add rate limiting to /v1/orders endpoint
  Files changed:
    src/handlers/orders.go      (implementation)
    src/handlers/orders_test.go (tests)
    docs/api/orders.md          (documentation)
    openapi/orders.yaml         (API spec)

Bad PR:
  Title: Add rate limiting to /v1/orders endpoint
  Files changed:
    src/handlers/orders.go
    src/handlers/orders_test.go

  Follow-up ticket: DOC-1234 "Update orders docs for rate limiting"
  Status of DOC-1234 six months later: Open

The follow-up ticket approach fails because documentation tickets are perpetually lower priority than feature work. The only reliable time to write docs is when the code is being written, by the person writing it.

PR Review Checklist

Add documentation to your PR review checklist. If the PR changes user-facing behavior, reviewers should ask: "Where are the doc changes?"

PR review checklist (relevant items):
  [ ] Tests pass
  [ ] No regressions
  [ ] Documentation updated (if user-facing change)
  [ ] API spec updated (if API change)
  [ ] Changelog entry added (if notable change)

Some teams enforce this with automation: a CI check that flags PRs touching API handlers without corresponding doc changes. This catches the obvious cases.

Automated Doc Testing

Documentation can and should be tested. Not every type of content is testable, but the most critical types are.

Code Sample Testing

Extract code samples from documentation and execute them as part of CI.

Testable doc content:
  - Code samples (extract and run)
  - API examples (execute against staging)
  - CLI examples (run and verify output)
  - Install commands (run in a clean container)
  - Configuration examples (validate syntax)

Approach:
  1. Write code samples in docs as fenced code blocks
  2. A test harness extracts blocks tagged for testing
  3. Each block is compiled or executed in CI
  4. Failures block the docs build

Tools:
  - pytest with code extraction for Python examples
  - mdx-js/mdx for JavaScript examples
  - Custom scripts that parse Markdown and run blocks
  - Doctest-style tools for inline examples

Dead links are the most visible form of doc rot. They are also the easiest to detect automatically.

Automated link checking:
  - Run on every docs build in CI
  - Check internal links (cross-references between pages)
  - Check external links (periodically, not on every build)
  - Check anchor links (heading references within pages)
  - Report broken links as build failures

Tools:
  - markdown-link-check
  - htmltest (for built HTML docs)
  - linkinator
  - Custom scripts using standard HTTP clients

API Spec Validation

If you generate reference docs from an OpenAPI spec, validate that the spec matches the actual API behavior.

API spec validation:
  - Run the spec through a validator (spectral, openapi-lint)
  - Generate client code from the spec and run integration tests
  - Compare spec schemas against actual response shapes
  - Flag undocumented endpoints (code exists, spec entry does not)

Ownership

Documentation without an owner is documentation that rots. Every document needs a clear owner who is responsible for keeping it accurate.

Who Owns What

Ownership model:
  API reference docs    -> The team that owns the API
  SDK docs              -> The team that owns the SDK
  Guides and tutorials  -> Developer relations or docs team
  Runbooks              -> The on-call team for that service
  Architecture docs     -> The tech lead for that system
  README                -> The project maintainer

Not an ownership model:
  "The docs team" owns everything.

A centralized docs team can provide tooling, standards, and editorial review. But they cannot own the accuracy of content they did not write about systems they do not operate. The people who change the code must own the docs for that code.

Scheduled Reviews

Even with docs-in-the-same-PR, some drift is inevitable. Schedule periodic reviews.

Documentation review cadence:
  - Runbooks: Review quarterly (or after every incident that
    revealed a gap)
  - API reference: Review when major version ships
  - Guides and tutorials: Review every 6 months
  - README: Review when project scope changes
  - Architecture docs: Review annually or after major redesign

Review process:
  1. Owner reads the document end to end
  2. Owner verifies all code samples still work
  3. Owner checks all links
  4. Owner updates or removes stale content
  5. Owner records the review date at the bottom of the doc

Freshness Indicators

Some teams add freshness metadata to documents so readers can gauge reliability.

Freshness metadata example:

  ---
  last_reviewed: 2026-03-15
  reviewed_by: jsmith
  review_cadence: quarterly
  ---

Display logic:
  - Reviewed within cadence: show green "Current" badge
  - Approaching review date: show yellow "Review due" badge
  - Past review date: show red "May be stale" badge

This does not prevent rot, but it signals to the reader how much they should trust the content.

Deprecation & Removal

Removing outdated documentation is as important as writing new documentation. A page that describes a feature you removed two years ago is actively harmful.

Documentation deprecation process:
  1. Mark the page as deprecated with a visible banner
  2. Link to the replacement (if one exists)
  3. Keep the deprecated page live for one release cycle
  4. Redirect the URL to the replacement page
  5. Remove the deprecated page content (keep the redirect)

Never:
  - Delete a page without a redirect (breaks bookmarks and links)
  - Leave deprecated pages without a banner (misleads readers)
  - Keep deprecated pages indefinitely "just in case"

Measuring Doc Health

You cannot manage what you cannot measure.

Doc health metrics:
  - Percentage of pages reviewed within their cadence
  - Number of broken links detected per build
  - Number of code samples that fail tests
  - Age of oldest unreviewed document
  - Support tickets caused by incorrect documentation
  - Time between code change and corresponding doc change

Actionable thresholds:
  - More than 10% of pages overdue for review: schedule a doc sprint
  - Any broken links in CI: block the build
  - Any failing code samples: block the build
  - Doc change more than 1 sprint behind code change: flag in standup

Common Pitfalls

  • Follow-up ticket for docs — "We will update the docs in a separate PR" means the docs will not be updated. Same PR or it does not happen.
  • Docs team as sole owner — a docs team that owns accuracy for systems they do not build will always be behind. Code owners must own doc accuracy.
  • No automated testing — if your code samples are not tested in CI, they will break. It is a matter of when, not if.
  • Never deleting anything — accumulating deprecated pages dilutes the docs and confuses search results. Deprecate, redirect, remove.
  • Reviews without action — scheduling reviews but never actually doing them. If the review is always deferred, the process is theater.
  • Blaming writers for stale docs — doc rot is a systems problem, not a people problem. If the system does not require docs with code changes, docs will lag. Fix the system.
  • Ignoring search analytics — search queries with no results tell you exactly where your documentation gaps are. Most docs platforms provide this data. Use it.

Key Takeaways

  • Stale docs are worse than no docs. They create false confidence and erode trust in all documentation.
  • Docs-as-code: same repo, same PR, same review process, same CI pipeline. This is the single most effective defense against doc rot.
  • Test your docs: code sample execution, link checking, and API spec validation. All automated, all in CI.
  • Every document needs an owner. The owner is the team that owns the code, not a centralized docs team.
  • Schedule periodic reviews and track freshness. Measure doc health the same way you measure code health.
  • Remove stale documentation. Deprecated pages without banners are traps. Deleted pages without redirects are broken links.