DocsGitHubBlog
Documentation Best Practices

How to keep your documentation up to date

Stale docs are the most common documentation problem and the easiest to ignore. Six patterns that keep documentation fresh without doubling the team that writes it.

A documentation page with a green 'last updated' badge alongside a pull request showing code and docs changed in the same commit

Every team I talk to has the same documentation problem. It's not tone, it's not structure, it's not the platform. It's that the docs are out of date, and everyone knows the docs are out of date, and nobody has the time this sprint to fix it. The page on authentication still references a header the API stopped accepting last quarter. The tutorial still walks through a button that got renamed in the redesign. The architecture diagram still shows the queue that got ripped out in February.

Stale docs are the most expensive form of documentation, because they look correct. A missing page sends a developer to a search engine. A wrong page sends them down a path that compiles, runs locally, and quietly breaks something in production a week later. And the cost has gone up: an AI assistant reading a stale page doesn't notice it's wrong — it cites it, and the wrongness ships into a customer's editor as code.

Here's the working set of patterns I've seen actually move the needle on freshness, without doubling the team that writes the docs.

1. Block PRs on doc updates the way you block them on tests

The single highest-leverage change is making the documentation review a gate on the code review, not a separate workflow that runs later if anyone remembers. If a pull request changes a public API surface, the corresponding doc page has to change in the same PR — and if it doesn't, the PR doesn't merge.

The mechanism is simple: a CI check that flags any change to your API definitions, public schema, or routing layer and refuses the merge until the docs directory has a matching diff. The check doesn't need to understand whether the doc change is correct; it just needs to enforce that one happened, and that a human reviewed both halves together. The accuracy follows from the proximity. Most stale docs aren't stale because nobody cared. They're stale because by the time anyone got around to updating them, the engineer who knew what changed had already moved on.

2. Own docs at the file, not at the team

"The docs team owns the docs" sounds like accountability and behaves like diffusion. The pages that go stale fastest are the ones with no specific human attached to them. The fix is a CODEOWNERS-style file inside your docs repository that maps every page to a specific engineer or small group, and routes reviews to them automatically.

The ownership doesn't have to be permanent. New page, new owner; ownership rotates with the surface it documents. The thing you're optimising for is that every page has exactly one inbox it lands in when something about it needs to change, and that inbox belongs to someone who knows what the page is supposed to say.

3. Make "last updated" a signal, not a decoration

Most docs sites render a "last updated" timestamp pulled from the file's Git history. That's the floor, not the goal. The version of this that actually works has three pieces:

  • The timestamp is visible on every page, in a place a reader can't miss.
  • A second timestamp tracks the last time the page was verified (someone read it end-to-end and ran the examples), not just edited.
  • A scheduled job opens an issue for every page where either timestamp is older than a threshold you set — six months for stable surfaces, six weeks for fast-moving ones.

The combination turns staleness from an invisible drift into a tracked work item. Pages get reviewed because the system asks; pages get fixed because the system won't shut up until they are.

4. Audit by query, not by sitemap

The conventional staleness audit walks the sitemap and asks which pages haven't been touched in a while. That catches the obvious decay and misses the dangerous kind. A page that's been edited recently can still be wrong if the edit was a typo fix and the API beneath it shifted underneath.

The better audit is by query: pick the ten or twenty questions developers most often ask about your product — the ones support sees, the ones an AI assistant gets asked, the ones your top integration paths depend on — and walk the answer for each, end to end, against the live product. If the docs match the product, the page is fresh. If they don't, the page is stale regardless of what the timestamp says. This is the same audit a careful agent-era reader runs in their head every time they prompt; you might as well run it yourself first.

5. Treat broken examples as broken code

A documentation page with a copy-paste code block that no longer runs is, structurally, a bug. It should be tracked in the same place real bugs are tracked, prioritised the same way, and fixed before the next release. The way to enforce this in practice is to run the examples in CI. Pull every fenced code block tagged as runnable, execute it against a real version of your product, and fail the build when any of them break.

You'll be surprised how many do, the first time. You'll be more surprised how many stay fixed, once breaking a code block costs the same as breaking a test.

6. Lower the activation energy of a docs change

Most of the patterns above are about pressure: making it harder to skip a docs update. The companion pattern is to make doing the update genuinely cheap. If editing a doc page requires cloning a separate repository, learning a proprietary editor, and waiting on a build that runs only when a docs-team member approves it, then your engineers will keep skipping the docs update no matter how stern the policy is.

What works is the opposite shape: a Git-backed docs repository in plain Markdown or MDX, edits accepted from a pull request the same way code is accepted, a preview deploy on every commit, and a path from "noticed a wrong sentence" to "PR open" that takes under two minutes. When the cost of fixing a doc page drops below the cost of leaving it wrong, the staleness curve bends without anyone having to issue a memo about it.

What's underneath all of this

The six patterns share a single premise: documentation freshness isn't a willpower problem, it's a workflow problem. Teams whose docs stay current don't have a better culture than teams whose docs go stale — they have a workflow where the path of least resistance happens to be the correct one. Docs that live next to the code, in the same review system, with file-level owners, instrumented timestamps, query-based audits, and runnable examples, stay current because every individual incentive is pulling in that direction.

The cost of getting this wrong used to be measured in support tickets. Now it's measured in integrations an AI agent shipped against the wrong version of your API, and bots quietly hitting 404s on the pages your sitemap still claims exist. The teams who treat freshness as infrastructure — not as a quarterly cleanup — are the ones whose docs read as canonical to both audiences.

How Doccupine helps here

Most of what I've described is workflow, and most of it is platform-agnostic — you can build it on any docs stack with enough discipline. A few pieces are easier when the platform handles them by default:

  • Every Doccupine site is Git-backed by design, so docs sit in a pull-request workflow indistinguishable from code.
  • Pending changes get previewed in the dashboard before they go live, so reviews happen on the rendered page, not a guess.
  • Per-page .md mirrors, an MCP server, and an llms.txt index are emitted on every build, so AI agents read the freshest version of your content the moment it's published.
  • Custom domains, SSL, and deploy pipelines are handled, so the cost of shipping a doc change is one PR away from live.

The editorial work — the audits, the ownership decisions, the cultural shift towards treating docs like code — is yours on any platform. The substrate is what we take off your hands.

Start your free trial

If you've got a staleness pattern your team has solved in a way I haven't covered, send it over to [email protected]. The interesting answers tend to come from teams who've been quietly running this rhythm for years.

Luan Gjokaj
Written byLuan Gjokaj

On the Doccupine team, building the open-source, AI-ready documentation platform.