The copy you cannot reach
Send a response and it is gone. The browser or app on the other end may keep a copy, and from then on it can answer the same request without asking you at all. No network, no server, nothing to pay for.
Headers control it, rather than hope. Cache-Control is the instruction you attach to a response, and max-age says how many seconds the copy may be reused. Set it to 3600 and the browser will not ask you again for an hour, however wrong the copy becomes. Set no-store and it keeps nothing.
An ETag helps when the answer usually has not changed. You send a short identifier alongside the response, and next time the browser asks it includes that identifier. If nothing has changed you reply 304 Not Modified with an empty body, which still costs a round trip but saves sending the data again. That is the difference between a fast page and a cheap one, and they are not the same goal.
The hard part is that you cannot reach a copy once it has left. There is no delete for a million browsers. Whatever max-age you chose is a promise you cannot break. That is why long-lived assets carry a version in the filename. Change the file, change the name, and the old copy is simply never requested again instead of being corrected.
The copy is public unless you say otherwise. A response cached by a shared proxy and handed to the next person is a serious bug when the body held somebody's account details. Cache-Control: private is what prevents it.
Worked example
Arjun set a one hour max-age on his product responses, which are JSON documents served straight to the browser, to cut load further. It worked, and then a pricing error went out on a Friday afternoon.
He corrected the database in two minutes and Redis in three. Browsers that had already fetched the wrong price kept showing it for the rest of the hour, and there was nothing he could deploy to change that. Support handled 40 calls about a price the site no longer had.
The rule he wrote afterwards was simple: anything a human might need corrected in a hurry gets no-cache on the client, and the caching happens in Redis where he can still reach it. Images and scripts keep the long expiry, because their names change when their contents do.