ADR-002: Git as Version Store for KV History
Status: Accepted Date: 2026-04-04
Context
Consul KV has no built-in version history. HashiCorp explicitly rejected the feature request (GitHub issue #1761, 60+ upvotes). We need a way to track every KV change over time for audit trail and point-in-time restore.
The version store must support:
- Full change history with timestamps
- Diffing between versions
- Point-in-time restore
- Off-site backup (push to remote)
Decision
Use Git as the version store. Every KV change is serialized to the filesystem and committed to a local Git repository. Keys map to file paths; values are stored as file contents.
Consequences
Positive
- Free version history.
git logshows every change ever made. - Free diffing.
git diffshows exactly what changed between any two points. - Free audit trail. Commit metadata records who changed what and when.
- Developers already know Git. No new tool to learn for investigation.
- Point-in-time restore.
git checkout <revision>gets you the state at any commit. - Natural GitOps integration. Fits into existing workflows, pull requests, and CI/CD.
- Backup is implicit. Push to a remote repository for off-site backup.
Negative
- Git repo size grows over time. Mitigated by periodic
git gc, shallow clones for CI, and the fact that config data is typically small (KBs, not GBs). - Binary values don't diff well. Mitigated by Base64-decoding binary values and storing them as text where possible.
- Git operations add latency to the sync cycle (typically 10-50ms per commit).
- Requires the
go-gitlibrary (pure Go) or a Git binary on the host.
Alternatives Considered
| Option | Pros | Cons |
|---|---|---|
| SQLite + Litestream | Better for structured queries, replication built-in | Adds dependency, less familiar to ops teams |
| BoltDB / BadgerDB | Embedded, fast | Need a custom versioning layer, no ecosystem tooling |
| Custom file-based changelog | Simple | Loses all Git ecosystem benefits (diff, log, blame, remote) |