4.8 KiB
4.8 KiB
| title | aliases | tags | sources | created | updated | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Versions — Overview |
|
|
|
2026-05-15 | 2026-05-15 |
Overview
Payload Versions track the full change history of Collections and Globals. When enabled, every save creates a new version record in a separate _slug_versions collection. The Admin UI gains diff views, version browsing, and one-click restore.
Versions are opt-in and non-destructive — they don't change the shape of your data.
Three Modes
| Mode | What happens on save | Use case |
|---|---|---|
| Versions only | New version created, always treated as "published" | Audit log / change history (e.g. user records) |
| Versions + Drafts | Control which version is published; drafts can be previewed before going live | Content publishing workflows |
| Versions + Drafts + Autosave | Admin UI auto-saves a draft as you type; published version unaffected | Editorial workflows — never lose changes |
Collection Config
// Simple — enable with defaults (max 100 versions per doc)
versions: true
// Custom
versions: {
maxPerDoc: 50, // 0 = unlimited; default 100
drafts: true, // or { autosave: true }
}
Global Config
versions: {
max: 20, // versions per global (no per-doc concept)
drafts: true,
}
Database Storage
A separate collection is created per versioned collection/global:
_posts_versions ← for 'posts' collection
_header_versions ← for 'header' global
Each version document structure:
{
"_id": "...",
"parent": "...", // parent doc ID (collections only)
"autosave": false,
"version": { /* full copy of the document */ },
"createdAt": "...",
"updatedAt": "..."
}
All fields inside version are set to not required — partial versions are valid.
Version Operations (REST / GraphQL / Local API)
REST — Collections
| Method | Path | Description |
|---|---|---|
GET |
/api/{slug}/versions |
List versions (paginated) |
GET |
/api/{slug}/versions/:id |
Get single version |
POST |
/api/{slug}/versions/:id |
Restore version |
REST — Globals
| Method | Path |
|---|---|
GET |
/api/globals/{slug}/versions |
GET |
/api/globals/{slug}/versions/:id |
POST |
/api/globals/{slug}/versions/:id |
Local API — Collections
// Find versions
await payload.findVersions({ collection: 'posts', sort: '-createdAt', limit: 10 })
// Find single version
await payload.findVersionByID({ collection: 'posts', id: '...' })
// Restore
await payload.restoreVersion({ collection: 'posts', id: '...' })
Local API — Globals
await payload.findGlobalVersions({ slug: 'header' })
await payload.findGlobalVersionByID({ slug: 'header', id: '...' })
await payload.restoreGlobalVersion({ slug: 'header', id: '...' })
GraphQL
| Operation | Query Name |
|---|---|
| Find versions | versions{CollectionPlural} |
| Find by ID | version{CollectionSingular} |
| Restore | restoreVersion{CollectionSingular} |
Access Control
Add readVersions to your collection/global access control to gate who can view version history:
access: {
readVersions: ({ req: { user } }) => !!user?.isAdmin,
}
This automatically restricts the Admin UI version tab as well.
Key Takeaways
- Separate collection — versions live in
_slug_versions, never polluting your main data - Three levels — versions-only (audit log), +drafts (publish control), +autosave (live editing safety)
- maxPerDoc — defaults to 100; set to
0for unlimited; tune for storage budget - Global versions use
max(notmaxPerDoc) and have noparentfield - All versions store a full copy of the document — fields are non-required to allow partial saves
- readVersions access function controls version history visibility independently of document read access
- Restore via POST — any version can be promoted back to current
- Autosave is safe — it only writes drafts, never touching the published version until you explicitly publish
Related
- wiki/payloadcms/versions-drafts — draft vs published, access control, scheduled publish
- wiki/payloadcms/versions-autosave — autosave interval config, storage strategy
- wiki/payloadcms/access-control — readVersions and publish access
- wiki/payloadcms/local-api — payload.findVersions / restoreVersion
- wiki/payloadcms/hooks-collections — afterChange hooks fire on version saves too
Sources
raw/versions__overview.md— https://payloadcms.com/docs/versions/overview