What does `Cache-Control: no-cache` on a Server-Sent Events response actually stop, and what does it not?
answer
- about reuse, not buffering
- a stored copy, served again
- revalidate before serving it
- storage is governed by no-store
- does nothing to a buffering intermediary
basics
~20 sCache-Control: no-cache stops any cache on the path from reusing a stored copy of the response without revalidating with the origin first. It does not forbid storing the body, and it has no effect at all on an intermediary that buffers the stream.
solid answer
~40 s`no-cache` is a directive about **reuse**, not about buffering and not about storage: a cache may keep the response, but it must revalidate with the origin before serving it to anyone else. On a `text/event-stream` response it is the conventional suppression, because a shared cache that ever served a stored copy would hand a second reader a frozen prefix of somebody else's stream. The directive people usually mean when they say "do not cache" is `no-store`. Neither of them touches the two failures that actually break a live feed: an intermediary accumulating the body before forwarding it, and a transforming intermediary applying a content coding. `no-transform` is the lever for the second, and buffering is a forwarding decision that no cache directive governs.
code
http · 9 linesHTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
event: speed
data: 412
event: jam
data: clearedgo deeper
Recall that no-cache governs reuse of a stored response rather than storage itself, and that no-store is the directive that tells a cache not to keep a copy at all.
Explain what a shared cache would otherwise do with a long-lived response, and why revalidation is the behaviour being suppressed rather than buffering or transformation.
Show that you separate the failure classes on a streamed response - reuse of a stored copy, accumulation before forwarding, transformation of the body - and reach for the right lever for each one.
The judgment is how much stream health you are willing to express as response directives at all, given that the failure that matters most has no standard directive and is a per-route configuration decision in someone else's tier.
## What the directive says, and what its name suggests `Cache-Control` is the header field that carries caching directives to every cache on the path: a shared cache in front of the origin, an edge tier, or a private cache inside the receiving application. `no-cache` is one of those directives and it is the most misread string in HTTP. It does **not** mean "do not cache". It means a cache **must not reuse a stored response to satisfy a later request without successful revalidation with the origin**. Keeping a copy is still permitted. Serving that copy blind is not. The directive that forbids retention outright is `no-store`. That distinction is worth holding onto before anything else, because on a streaming endpoint people reach for `no-cache` believing it does three jobs it does not do. ## Why a bottling-line feed carries it anyway A plant publishes jam-and-speed events from a filler and capper as `text/event-stream`: one `GET`, a `200 OK`, and a body the origin never ends. Several things on that path are entitled to treat a `200 OK` as a storable response. If any of them ever stored this one and replayed it, a second operator opening the same dashboard would receive a fixed prefix of the first operator's stream: the twenty events that happened to be in the copy, and then silence, since the stored representation has no future in it. `no-cache` is the standard, one-line suppression of exactly that. It is cheap, it is universally understood, and it costs nothing on a response that has no useful cached form. That is the whole of its job on a stream. ## What it does not do This is the half of the answer an interviewer is listening for: - It does **not** stop a reverse proxy, an edge tier or an L7 load balancer accumulating the body and forwarding it in blocks. That is a decision about when to pass along bytes already received, and no cache directive addresses it. - It does **not** stop a transforming intermediary applying a content coding to the body. `no-transform` is the directive aimed at that. - It does **not** stop an intermediary ending a quiet response on an idle timeout. - It does **not** forbid storage. `no-store` does. - It does **not** reach the receiving client's own behaviour after a stream drops; a conforming client reconnects on its own regardless of what directives the response carried. ## The three directives a streamed response tends to carry | Directive | What it governs | The failure it addresses | |---|---|---| | `no-cache` | reuse of a stored copy for a later request | a second reader served a frozen prefix of a live stream | | `no-store` | whether a copy may be retained at all | a body kept somewhere it should not be | | `no-transform` | changing the content coding or media type of the body | compression or rewriting that defeats incremental delivery | Notice what the table does not contain: a row for buffering. There is no standard directive for it. The only per-response lever that exists is a **vendor extension field** that some proxies honour as an opt-out for that one response, and no specification defines one, so its spelling differs by product and an intermediary that does not recognise it ignores it in silence. ## How to say this in an interview Three sentences do it: 1. `no-cache` means revalidate before reuse; `no-store` means do not keep it. 2. On a stream it exists so a shared cache cannot hand a second reader a stale prefix. 3. The failures that actually break streams -- accumulation before forwarding, and transformation of the body -- are governed elsewhere, and one of them is not governed by any standard directive at all. A candidate who can separate those three failure classes has understood the leaf. A candidate who says "we set `no-cache` so the proxy does not buffer" has merged two unrelated mechanisms and will debug the next stalled stream by adding directives that cannot help. ## The cost of getting it wrong The practical damage is not the directive itself -- it is harmless -- but the false confidence. Teams ship a streaming endpoint, set `no-cache`, watch the feed arrive in clumps through the edge tier, and conclude that the media type or the framework is at fault, because the header they believe fixes intermediaries is already there. The directive is doing its job perfectly; its job was never the one they assigned it.
- Which directive would you add if you also want no copy of the body retained anywhere?`no-store`. `no-cache` allows a cache to keep the response and only bars reusing it without revalidation, while `no-store` is the one that tells caches not to retain it. On a stream the practical value is small, since there is rarely a complete response to store, but it is the honest spelling of the intent people usually have when they reach for `no-cache`.
- If neither directive stops an intermediary buffering the body, what does?Nothing in the cache-directive vocabulary. Buffering is an intermediary's decision about when to forward bytes it has already received, governed by that intermediary's configuration for the route, or by a vendor-defined response header field that some proxies honour as a per-response opt-out. No specification defines such a field, so it is a hint rather than a guarantee.
saying these in an interview costs you the question
- Says no-cache stops a reverse proxy buffering the stream
- Treats no-cache and no-store as the same directive
- Claims no-cache forbids a cache from keeping any copy
- Thinks a response directive makes an intermediary forward each event immediately
- Argues the directive is pointless because nothing could ever store a stream