WSWhat Scene?

Guide · 10 min read

What real-time content updates really mean

For a business site, real-time content updates means one of two different things. Either a published edit reaches visitors quickly, which is a caching question solved by revalidation. Or open pages receive data the moment it changes, which needs listeners, server-sent events or WebSockets, and costs far more.

Two different questions behind one phrase

When someone searches for real-time content updates, they usually want one of two things, and the technology for each has almost nothing in common. The first is: I change something in my content system, how soon do visitors see it? The second is: a visitor has the page open, and something happens elsewhere, does their screen change without them doing anything?

Most business websites need only the first. A price, an opening time, a new case study, a corrected sentence. The visitor loads the page, reads it, leaves. What matters is that the next person to load it sees the new version within a time you are comfortable with. The second need is real but narrower: a live order status, a shared document, a chat, a dashboard that should not need a refresh.

MechanismAnswersWho it reaches
Rebuild and redeployHow soon does an edit go liveEvery later visitor
Time-based revalidationHow soon does an edit go liveThe next visitor after a set interval
On-demand revalidationHow soon does an edit go liveThe next visitor after you publish
Database listenerDo open pages update themselvesEveryone with the page open
Server-sent eventsDo open pages update themselvesEveryone with the page open, server to browser only
WebSocketsDo open pages update themselvesEveryone with the page open, both directions
The mechanisms, and which question each one answers.

The rest of this piece takes them in that order, because the cheap, boring ones come first and are the right answer more often than people expect.

Publishing a change and seeing it live

A site built with Next.js can prerender pages ahead of time and serve them from a cache. That is fast, and it means a page is a stored copy rather than something computed per visitor. The question is what makes the stored copy change when your content does.

The first answer is a rebuild: change the content, run the build, deploy. Everything is regenerated and every cache starts fresh. Next.js documents that these stores are scoped to a single deployment, so a new deploy starts from empty. It is the most predictable option and the slowest, and it is the right one for content that lives in the code, such as this site's own guides.

The second answer is time-based revalidation. You give a page a number of seconds. The Next.js guide describes the sequence precisely: once the interval has passed, the next request still returns the cached, now stale page; that request also starts regeneration in the background; and when the new version is ready, the request after it gets the update. Two things follow that are easy to miss. The first visitor after the interval sees old content. And if regeneration fails, the guide says the last successfully generated version keeps being served, with a retry on the next request, so a bad moment at your database does not blank the page.

The third is on-demand revalidation. Your content system calls revalidatePath or revalidateTag when you publish, which invalidates the cached copy straight away. The guide is careful about one detail: it invalidates the entry, and regeneration happens on the next request, not at the moment you click. So the honest description is that the first visitor after you publish pays the cost of the regeneration, and every visitor after that gets the new page from cache.

The Next.js guide recommends a high interval, an hour rather than a second, and says that if you need more precision you should use on-demand revalidation instead. A very short interval buys little freshness and a lot of regeneration.

What we run, and what it tells you

We use all three approaches on this site, deliberately, for different content. Our guides, answers and comparison pages are typed files compiled at build time. Their pages carry an hourly revalidate setting, but because the content is inside the build, that setting re-renders the same compiled text. A new sentence on a guide goes live when we deploy, and we treat that as correct, since they are checked by tests before anything ships. How long that takes: across the ten most recent successful builds of this site, read from Cloud Build on 2026-10-04, build and rollout took a median of 4.4 minutes, with a range of 4.1 to 5.3. That covers the build and the rollout only. It does not include the time for a CDN or a visitor's browser to stop serving an older copy.

The pricing page is different, because its starting figures are edited by an admin in a content form rather than in code. It declares a one minute revalidate, and the code comment next to it gives the reason: the build step has no database credentials, so a deploy would otherwise bake in an empty version and silently drop the published figures. The minute bounds that damage. Publishing also calls revalidatePath for the pricing route, so an intentional change goes live on the next request rather than waiting out the minute. The same publish action writes an audit log entry recording who changed what.

That is the whole pattern for a typical content system: a safety-net interval so nothing stays stale for long, plus an on-demand call so a deliberate publish is not left waiting. It is cheap, it keeps the site serving from cache almost all the time, and it needs no open connections at all.

What the /cms demo shows, and what it does not

The /cms page has an interactive editor, and it is easy to read it as a demonstration of content going live. We read the code before writing this section, and the accurate description is narrower.

  • It runs entirely in the browser, in local React state. There is no network call, nothing is stored, and a reload resets it. The page says so on the face of the demo.
  • The preview panel updates as you type, including unsaved edits. That is deliberate, so an editor is never guessing at what a change will look like. It also means the demo never has to model a delay.
  • Save and publish are separate acts, as in the real thing: a saved draft changes nothing visible, and publishing flips it live. The message that says the live page updated is a line of interface text reacting to that local state.
  • It has no cache, no revalidation and no second visitor. So it shows the editing experience and the draft versus published distinction, and it says nothing about how long a real visitor waits.

For propagation, the closer evidence is the pricing page described above: a form that writes to the database, a publish action that invalidates the route, and a page that serves from cache until then. What a client gets from us follows that shape. The edit surface is yours; the delay between publish and visible is whatever the revalidation setting allows, which we set per page and can tell you in seconds.

Pushing data to a page that is already open

Revalidation does nothing for someone who loaded the page ten minutes ago. If their screen has to change without a reload, the browser needs a way to hear from the server, and there are three standard ways.

Database listeners are the lowest effort when your data already lives in a service that offers them. In Firestore, you attach a listener to a document or a query. The documentation says an initial call creates a snapshot with the current contents, and each time the contents change another call updates it. Local writes also fire the listener immediately, before the data reaches the backend, which is called latency compensation, so the writer sees their own change at once. Our dashboard uses this for the notifications bell: it listens to the signed-in client's own notifications and updates the unread count without a refresh.

Server-sent events are a one-way channel. MDN describes the EventSource interface, a server that responds with the text/event-stream type, and a default behaviour of restarting the connection if it closes. You cannot send events from the client over it. That is the right fit for a feed, a progress bar or a live status. MDN also records a limit: when not used over HTTP/2, browsers cap the open connections per browser and domain at a very low number, 6, shared across tabs.

WebSockets open a two-way session between browser and server, so both sides can send at any time without polling. That is what chat and collaborative editing need. MDN also notes that the WebSocket interface does not support backpressure: if messages arrive faster than the page can process them, it buffers them in memory, becomes unresponsive, or both. A real-time feature that handles bursts needs thought about that.

What each one costs to run

None of the prices are quoted here, because they move and the vendors publish their own. What is worth knowing is what gets counted and what has to be built.

ApproachWhat gets counted or kept openWhat you have to build or watch
RevalidationA regeneration per page per interval, and one more after each on-demand publishChoosing the interval. With several server instances, the default cache is per instance, so on-demand revalidation only reaches the instance that received the call, and you need a shared cache handler
Firestore listenerA document read each time a document in the result set is added or updated, plus security rule evaluation on each updateDetaching listeners when a page closes. After more than 30 minutes offline, or a reconnect without offline persistence, you are charged as if you had issued a new query
Server-sent eventsOne open connection per viewer for as long as the page is openThe connection limit on HTTP/1.1, and a server that can hold many idle connections
WebSocketsOne open connection per viewer, in both directionsReconnection, backpressure, and keeping several instances in agreement
What the primary documentation says each approach asks of you.

The last row hides the largest cost. Google's Cloud Run documentation says WebSocket streams are HTTP requests still subject to the service's request timeout, so a client will eventually be disconnected and must be able to reconnect. It also says new WebSocket requests may land on different instances despite session affinity, and recommends an external publish and subscribe layer, such as Redis or Firestore real-time updates, to keep instances in sync. A feature that looks like a few lines in a demo becomes a design problem the moment there are two servers.

A listener is billed by change, not by time, so a quiet page is cheap and a busy collection watched by many people is not. The number to estimate is changes per minute multiplied by viewers, which is why a live dashboard over a busy collection deserves arithmetic before it deserves a build.

Deciding what you actually need

Work through these in order and stop at the first one that settles it.

  1. Is the content in code, or in a database that someone edits? Code means a deploy, and the question of freshness is really about how fast you can ship. A database means revalidation.
  2. How stale can it be before it hurts? If the honest answer is a minute, a short interval plus on-demand publishing solves it, with no open connections.
  3. Does anyone have the page open when the data changes, and does it matter that they see it? A price change does not matter to someone mid-read. A booking slot that just filled does.
  4. Only if yes: does the data flow one way or both? One way points to a listener or server-sent events. Both ways, as in chat or shared editing, is where WebSockets earn their cost.
  5. How many people at once, and how often does it change? This is the figure that decides the running cost, and it is the one most requests for real-time never state.

The existing short answer on this site says real-time is worth it when immediacy is the point and overkill when a normal refresh would do. That holds. The addition here is that for content updates the refresh question is usually settled by an interval of seconds, which costs almost nothing.

What this does not cover

  • It describes the Next.js model without Cache Components, which is what the route-level revalidate setting belongs to. The newer Cache Components model (the use cache directive with cacheLife) has different controls, and the Next.js documentation says so on both pages.
  • The one measurement it carries is the build and rollout time of this site, from ten builds on one day's read of Cloud Build. It is not a publish-to-visible time, it excludes CDN and browser caching, and it says nothing about load. For everything else it gives the sequence the documentation describes, not a figure.
  • It quotes no prices. Listener, hosting and connection costs depend on your provider and volume, and the vendors publish their own pages.
  • The Cloud Run notes apply to a service running on Cloud Run. Other hosts impose different timeouts and different limits on long-lived connections.
  • It is about content for business sites. Collaborative editing, multiplayer state and large-scale messaging need techniques not covered here.
  • The /cms demo is a demonstration of an editing surface. It is not evidence of how quickly any real install updates.

Sources

Revisions

  • 4 October 2026 Added this site's own push-to-live time, measured from Cloud Build: median 4.4 minutes over the ten most recent successful builds. Build and rollout only.
  • 4 October 2026 First published, written from primary documentation read on this date and from the code behind the /cms demo and the pricing page.

This page is revised in place rather than replaced, so its address does not change.

Next step

Want this built, not just explained?