What "Real-Time Content" Really Means for Production Frontends
Your marketing team schedules a homepage hero swap for a product launch.
Your marketing team schedules a homepage hero swap for a product launch. The CDN serves stale HTML for nine minutes after the publish button is pressed, the campaign team is refreshing in a panic, and your on-call engineer is purging caches by hand. Or worse: an editor fixes a pricing typo, sees it correct in preview, but production keeps serving the wrong number because preview and published read from two different pipelines. "Real-time content" gets promised on every CMS landing page, but in production it usually means something far narrower than what your stakeholders heard.
Sanity is the Content Operating System for the AI era, an intelligent backend where the same query that powers your build can also subscribe to changes and stream them as they happen. That distinction, between content that is merely fetchable and content that is genuinely live, is the difference between a frontend that reflects reality and one that lies to your users for as long as your cache TTL allows.
This guide breaks down what real-time actually requires at each layer of a production frontend: the data store, the query path, the preview loop, and the edge. Then it shows where the marketing claim and the engineering reality diverge, so you can shortlist on mechanisms instead of adjectives.
The four meanings hiding inside one phrase
When a vendor says "real-time," they could mean any of four very different things, and conflating them is how teams end up surprised in production. The first is fast publishing: the time between hitting publish and the change being queryable through the API. The second is live preview: an editor seeing unpublished drafts rendered in the actual frontend before anyone else does. The third is live delivery: end users seeing a change without a page reload or a cache purge, the classic use case for prices, inventory counts, scores, and breaking news. The fourth is collaborative editing: two people in the same document watching each other's cursors and edits land character by character.
Most platforms are strong at one or two of these and quietly weak at the rest. A CMS can have near-instant publishing but no real-time delivery, so the content is queryable in milliseconds yet still sits behind a CDN serving a ten-minute-old render. A platform can offer collaborative editing in its editor while delivery to production remains a rebuild-and-deploy cycle measured in minutes. The phrase flattens all of this into one checkbox.
The practical move is to interrogate each layer separately. Ask where the freshest copy of a given field lives, how a frontend learns that it changed, and how long the longest stale path can be. Once you decompose the claim, you can map your own requirements onto it. A documentation site might only need meaning one. A live sports frontend needs meaning three with no exceptions. A 30-person editorial desk needs meaning four to stop overwriting each other. The rest of this article walks each layer and the mechanism that makes it honest.
Layer one: the content store has to be the source of truth
Real-time at the delivery layer is impossible if your content store is not itself queryable in real time. If the freshest representation of your content only exists after a static build flattens it into files, then "real-time" is bounded by your build time no matter what the edge does. This is the layer where most architectures quietly cap themselves, because the store was designed for read-on-publish, not read-on-change.
Sanity's Content Lake is the queryable backend that holds your content as structured documents, not pre-rendered pages, and it exposes those documents over the Live Content API so a frontend can subscribe to a query and receive updates as the underlying data changes. This is the architectural difference that makes the other layers possible: because the store understands your content model rather than storing opaque HTML blobs, a subscription can be scoped to exactly the documents and fields a given view depends on. An inventory widget subscribes to the stock field; it does not get woken up because someone edited an unrelated blog post.
The model lens here is "Model your business." When content is modeled as typed documents with references between them, the store can reason about what changed and who needs to know. A flat key-value cache or a folder of Markdown files cannot do this; they have no notion of a query result that should update when a referenced author record changes. The structured store is the precondition for everything downstream. If you only remember one thing about evaluating real-time claims, start at the store and ask whether it can push, not just answer when polled. A platform that can only answer when asked will always be one poll interval behind reality, and that interval becomes your floor.
Layer two: the query path decides what "changed" even means
A subscription is only useful if it can describe precisely the shape of data a view needs, because otherwise you are re-fetching and re-diffing far more than necessary, and the frontend cannot tell a meaningful change from noise. This is where the query language stops being a developer-convenience detail and becomes a real-time architecture decision.
With GROQ, a single query asks for exactly the shape the component renders: projections that pull only the needed fields, the `->` operator to follow references and inline a related author or product, filters to scope to the right documents, and array slicing to bound the result. Because the query expresses the precise dependency graph of a view, a real-time subscription over that query knows exactly which underlying changes are relevant. The classic GraphQL alternative often forces multiple round trips or over-fetching, and over a live subscription that means more invalidation churn and more work on the client to figure out what actually moved.
The payoff is concrete. Imagine a product page that shows a price, a stock count, and the three most recent reviews. In GROQ that is one query with a projection and a slice. Subscribe to it, and a price edit, a stock decrement, or a new review each push a fresh result in the exact shape the component already consumes, with no second request to hydrate references. The frontend swaps state and re-renders the affected node. Contrast this with a path where the price lives in one service, reviews in another, and the page must orchestrate several calls and reconcile them on every change. The single round-trip query is not just terser; it is what makes the live update tractable instead of a distributed-systems problem you solve by hand on every component.
Layer three: preview is where real-time pays for itself first
Before a single end user benefits from live delivery, your editors do, because the most expensive real-time failure is the one where an editor cannot trust what they see. If preview reads from a different pipeline than production, every edit is a leap of faith, and teams compensate with publish-and-check cycles that burn time and erode confidence. The fix is a preview loop where the editor sees the real frontend, rendering real draft content, updating as they type.
Sanity's Presentation Tool and Visual Editing put the live frontend inside the Studio, so an editor clicks an element on the rendered page and lands on the exact field that produced it, while the Live Content API streams draft changes into that preview without a rebuild. This collapses the gap between editing and seeing. There is no separate "preview build" that lags the production code, because the preview is the production frontend pointed at draft content. The editor is looking at what the user will look at.
This is the "Automate everything" pillar in disguise: the loop that used to be a manual publish, wait, refresh, and verify ritual becomes continuous and ambient. Content Releases extend the same idea to scheduled and bundled changes, so a team can stage an entire launch, preview the future state of the site as it will appear at go-live, and ship the bundle atomically rather than racing to publish twenty documents in the right order. For a production frontend, this is where real-time stops being a delivery gimmick and becomes an editorial-confidence feature. The teams that move fastest are not the ones with the lowest cache TTL; they are the ones whose editors never have to guess whether the thing they shipped is the thing the user will get.
Layer four: the edge, and the honest limits of "instant"
The last mile is the CDN, and this is where most real-time promises quietly expire. A frontend can subscribe to live data all it wants, but the first paint a user gets is usually a cached document served from an edge node, and that cached copy is exactly as fresh as your invalidation strategy makes it. Real-time delivery in production is therefore a negotiation between three things: how the initial HTML is cached, how quickly that cache learns a change happened, and whether the client upgrades to a live subscription after hydration.
The mature pattern is layered. Serve a cached initial render for speed and resilience, invalidate it precisely when the relevant content changes rather than on a blunt time interval, and then let the hydrated client open a live subscription for the fields that genuinely need to move in real time, like price, stock, or a live event status. The fields that change rarely stay cached aggressively; the fields that change constantly ride the subscription. Treating the whole page as either fully static or fully live is the mistake; real-time is a per-field decision, not a per-page one.
This is also where honesty matters when you evaluate vendors. Almost every platform can serve a cached page and almost every platform can purge on publish. The differentiator is whether the store and query path let you scope invalidation and subscriptions to exact content dependencies, so you are not purging the entire site because one footer link changed, and not polling every five seconds because you have no push channel. The edge is not where real-time is won. It is where a weak store and a coarse query path get exposed. Decide your freshness budget per field, then check that each layer beneath the edge can actually honor it.