---
title: Version History
slug: version-history
kind: pattern
summary: Previous states of a record kept, listed and restorable — so an edit is never the destruction of what came before.
problem: >-
  Someone overwrites a paragraph, a price or a whole document and there is no
  previous copy. The information existed an hour ago and now exists nowhere, and
  the only recovery is whoever happens to remember it.
family: [edit, recover]
data_shape: [record]
principles: [orientation, consistency]
interaction: [disclosure, navigation]
density: low
complexity: high
status: stable
visibility: public
use_when:
  - The record holds composed content — text, configuration, a document, a template.
  - The system autosaves, which removes the natural "before" that explicit save provided.
  - Several people edit the same record, so a change can surprise someone who did not make it.
avoid_when:
  - Every change is already an append-only event and nothing is ever overwritten.
  - The record is trivially reproducible from its source.
  - Storage or privacy rules mean old content must not be retained.
alternatives:
  - slug: activity-timeline
    when: People need to know who changed what, not to read or restore the old content.
  - slug: autosave
    when: You have not yet solved durability at all — do that first; history is its companion.
ask_leo: |
  Give this record a version history.

  - Snapshot on meaningful boundaries, not on every keystroke: when the record
    is saved, when an editing session ends, or when the editor changes.
  - List versions newest first with who made the change and when, and give each
    one a short summary of what changed rather than only a timestamp.
  - Let someone open a version read-only, and clearly mark that they are looking
    at an old version and not the current one.
  - Show a comparison between a version and the current state, highlighting what
    was added and removed.
  - Restoring creates a NEW version whose content is the old one. Never delete
    the versions in between — restore must itself be undoable.
  - Collapse consecutive versions by the same person within a short window into
    one entry, so a working session is one row rather than forty.
  - Say how long history is kept, and never silently drop versions people can
    still see referenced.
related:
  - title: Autosave
    url: /patterns/autosave
    summary: Why continuous saving makes history mandatory rather than optional.
  - title: Activity Timeline
    url: /patterns/activity-timeline
    summary: The sibling — timeline records actions, history records content.
---

## Anatomy

```
  Versions                          ┌─ viewing v6 (read-only) ───────┐
  ● Current — Dana, 2h ago          │ Site access is via the rear    │
  ○ v6 — Dana, 3h ago               │ gate. Ask for Marek…           │
      "rewrote access notes"        │                                │
  ○ v5 — Priya, yesterday           │ [ Compare to current ]         │
  ○ v4 — Dana, 3 days ago           │ [ Restore this version ]       │
      (12 edits in one session)     └────────────────────────────────┘
```

Four obligations:

1. **Snapshots on boundaries**, not on keystrokes. Otherwise the list is
   thousands of entries and useless.
2. **A summary per version.** A list of identical timestamps makes people open
   every one.
3. **Restore is a new version.** Rolling back must not destroy what it rolls
   back past, or restore becomes as dangerous as the overwrite it fixes.
4. **An unmistakable read-only marker** when viewing an old version, or someone
   will edit history and be confused when it does not save.

## Why it works

It converts editing from destruction into accumulation. Once nothing is lost,
several other things get cheaper: people are willing to make bigger changes,
disagreements about "what did it say before" become checkable, and
[autosave](/patterns/autosave) becomes safe to adopt.

That last connection is the important one and the most often missed. Autosave
without history is not a feature, it is a hazard — it removes the moment of
deliberation that explicit save provided while providing nothing in its place.
The two patterns are halves of one design.

## The diff is the product

A list of versions is mildly useful. A **comparison** is what people actually
want, because the question is almost never "what did version 4 say" — it is
"what changed between then and now".

If you build only one thing beyond the list, build the diff. It is also what
makes the summaries writable: once you can compute what changed, you can
describe it.

## Getting it wrong

- **A version per keystroke**, producing a list nobody can navigate.
- **Timestamps with no summary**, so finding the right version means opening
  ten.
- **Destructive restore**, which discards the intervening versions and makes
  rollback a decision people are afraid of.
- **No read-only marker**, so people edit an old version and lose the work
  twice.
- **Silent retention limits.** Versions vanishing after thirty days, discovered
  on the day someone needs day thirty-one.

## Exemplars

**Google Docs version history** is the reference: named sessions rather than raw
saves, a readable diff, and restore that itself creates a version. It is also
the clearest demonstration of the autosave pairing — the history is what makes
never pressing save acceptable.

**Git** is the maximal version of the pattern, and the useful lesson from it is
social rather than technical: history is most valuable when every change carries
a human description of *why*, not just a record of *what*.

**Notion's page history** shows the retention trap handled explicitly — the
limit is stated in the interface and tied to the plan, rather than discovered.

The extractable rule: **history is what makes editing safe, and the diff is what
makes history usable.** A list of versions without a comparison is an archive
nobody opens.
