Documentation-as-Code
Treat documentation like code. Covers docs-as-code tooling, ADRs, API documentation, runbooks, and keeping documentation current alongside your codebase.
Documentation that lives outside the codebase dies. It’s written once, becomes stale, and developers stop trusting it. Documentation-as-code keeps docs in the same repository as code, reviewed in the same PRs, built by the same CI, and deployed alongside the application.
What to Document
| Type | Where | Example |
|---|---|---|
| ADRs (Architecture Decision Records) | docs/adr/ | Why we chose Kafka over RabbitMQ |
| API documentation | Generated from code | OpenAPI spec → rendered docs |
| Runbooks | docs/runbooks/ | How to handle database failover |
| Getting started | README.md | Clone, install, run in < 5 min |
| Architecture overview | docs/architecture.md | System diagram, service boundaries |
| Onboarding | docs/onboarding/ | Week 1 guide for new developers |
Architecture Decision Records
# ADR-003: Use PostgreSQL for Order Service
## Status
Accepted
## Context
Order service needs a transactional database supporting
complex queries, ACID guarantees, and JSON storage for
flexible order metadata.
## Decision
Use PostgreSQL 16 with JSONB for order metadata.
## Consequences
- ✅ Strong ACID guarantees for financial data
- ✅ JSONB eliminates need for separate document store
- ✅ Team has deep PostgreSQL expertise
- ⚠️ Horizontal scaling requires Citus or read replicas
- ⚠️ Must monitor connection pool under load
## Alternatives Considered
- **DynamoDB**: Rejected — complex query patterns don't fit key-value model
- **MongoDB**: Rejected — ACID guarantees more important than schema flexibility
API Documentation from Code
# OpenAPI spec generated from code annotations
openapi: 3.1.0
info:
title: Order Service API
version: 2.1.0
paths:
/orders:
post:
summary: Create a new order
operationId: createOrder
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateOrderRequest'
responses:
'201':
description: Order created
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
'422':
description: Validation error
Runbook Template
# Runbook: Database Connection Pool Exhaustion
## Symptoms
- API returns 503 errors
- Alert: "PgBouncer: active connections > 90%"
- Logs: "connection pool exhausted"
## Severity
SEV-2 (partial outage)
## Steps
1. Check current connections:
`SELECT count(*) FROM pg_stat_activity;`
2. Identify long-running queries:
`SELECT pid, duration, query FROM pg_stat_activity
WHERE state = 'active' ORDER BY duration DESC LIMIT 10;`
3. If blocked queries found:
`SELECT pg_terminate_backend(<pid>);`
4. Scale PgBouncer pool if needed:
- Edit config: increase `default_pool_size`
- Reload: `pgbouncer -R`
5. If queries are from a specific service:
- Check recent deployments for that service
- Consider rollback if new deploy introduced issue
## Escalation
If not resolved in 15 minutes, page database team
Anti-Patterns
| Anti-Pattern | Problem | Fix |
|---|---|---|
| Wiki (Confluence, Notion) for technical docs | Docs separate from code, always stale | Docs in repo, reviewed in PRs |
| No ADRs | Nobody knows why decisions were made | ADR for every significant architecture decision |
| Generated docs only | API docs exist but no context or guides | Combine generated + hand-written docs |
| Docs not in CI | Broken links, formatting issues | Lint and build docs in CI |
| ”The code is the documentation” | Only true for trivial code | Code explains what, docs explain why |
Checklist
- README: clone → install → run in < 5 min
- ADRs: for every significant architecture decision
- API docs: auto-generated from OpenAPI/code annotations
- Runbooks: for every page-level alert
- Architecture diagram: current, covers service boundaries
- Onboarding guide: new developer productive in < 1 day
- Docs in CI: linting, link checking, automatic deployment
- Docs reviewed in PRs alongside code changes
:::note[Source] This guide is derived from operational intelligence at Garnet Grid Consulting. For engineering practices consulting, visit garnetgrid.com. :::