Workspaces in Drupal 11: How Content Staging Actually Works Under the Hood
Workspaces went stable in Drupal core back in 10.3 and ships with every Drupal 11 install. Past the marketing pitch of "stage then publish," here's the actual architecture — ContentWorkspace entities, computed fields, and the one thing it still can't scope.
What Problem It Solves
Before Workspaces, staging a large batch of content and configuration changes meant maintaining a separate staging site and manually syncing a deploy — slow, error-prone, and nearly impossible to do atomically. Workspaces lets a privileged user stage changes, preview them exactly as a visitor would see them, and publish the entire batch at once, without a second site to maintain.
The Architecture
Two workspaces — live and stage — are created on installation. The default workspace is the one anonymous visitors see, and critically, no queries or entity loads are altered for the default workspace — so sites that never touch Workspaces pay zero overhead.
Content created inside a non-default workspace is saved as unpublished at the entity level. The real published state lives on a separate ContentWorkspace entity — conceptually similar to how Content Moderation tracks state via ContentModerationState:
// Simplified: the published flag on the node itself stays FALSE
// while a workspace is active. ContentWorkspace tracks the "real" state.
$content_workspace = ContentWorkspace::load($node->getRevisionId());
A computed entity_reference field named workspace is added to every entity type that can belong to one. When you're inside a non-default workspace, Drupal alters entity queries to join the ContentWorkspace revision table and only load entities that belong to the active workspace or the default one.
Replication and Upstreams
Publishing a workspace is handled by a tagged replication service — the default implementation diffs the two workspaces, loops through every changed revision, and saves it onto the target. Because replication is a swappable service, contrib modules can hook in and replicate against something other than another Drupal workspace entirely — another site, even a non-Drupal system, via the plugin-based "upstream" concept.
The Caveat Nobody Mentions First
Files aren't revisionable in Drupal, so Workspaces can't scope them the way it scopes nodes. The moment a file lands in public://, it's written straight to live storage and served directly by the web server — there's no Drupal access check in that request path, and no "staged" version of a file exists. If your workflow depends on previewing a new hero image before it goes live, that part still needs a manual process.
Extending It
For teams that need actual tree-shaped revision history — parent and merge-parent relationships, not just a flat live/stage split — the contrib Revision Tree module builds on top of core Workspaces rather than replacing it, adding a "Rebuild associations" operation for when things drift.