{"id":13498,"date":"2026-10-13T07:35:00","date_gmt":"2026-10-13T05:35:00","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/?p=13498"},"modified":"2026-09-25T09:45:53","modified_gmt":"2026-09-25T07:45:53","slug":"cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do","status":"publish","type":"post","link":"https:\/\/www.lukaswojcik.com\/blog\/en\/web-development\/tutorials-en-web-development\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\/","title":{"rendered":"Cache-Control Explained: What no-cache, no-store, max-age and s-maxage Each Do"},"content":{"rendered":"<p>A page that loads instantly on the second visit was not fetched again. It came out of a store somewhere between the server and the screen, and one header line decided that it could.<\/p>\n<p>That line is <code>Cache-Control<\/code>. It is short, it is made of words that look self-explanatory, and two of those words mean nearly opposite things while sounding like synonyms.<\/p>\n<figure class=\"lw-diagram\">\n<img decoding=\"async\" src=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/diagrams\/cache-control-en.png\" width=\"1120\" height=\"580\" loading=\"lazy\" alt=\"Two storage bands - the browser and shared caches - with the directives that govern each, and no-store standing outside both\"><figcaption>A directive sits in the band it governs. What appears in both applies to both.<\/figcaption><\/figure>\n<h2>Two stores, not one<\/h2>\n<p>Between a server and a screen there are usually two places a response can rest.<\/p>\n<p>The first is the browser on one device. What it keeps serves exactly one person, and it stays there until it expires or the person clears it.<\/p>\n<p>The second is a shared store: a CDN, a company proxy, anything sitting in the path and serving many people from one copy. It is the more powerful of the two, because one stored copy saves thousands of requests &#8211; and the more dangerous, because a personalised page stored there gets handed to the wrong people.<\/p>\n<p>Nearly every misunderstanding about caching comes from forgetting that the second store exists. Directives that seem to contradict each other usually address different stores.<\/p>\n<h2>no-cache and no-store are not the same word twice<\/h2>\n<p>These two look like a matched pair. They are not.<\/p>\n<p><code>no-store<\/code> means: keep nothing. No copy anywhere, not in the browser, not in a shared cache, not on disk. Every request goes back to the server. This is the one for a bank statement.<\/p>\n<p><code>no-cache<\/code> means: keep it, but ask before using it. The copy is stored quite normally; the browser simply may not serve it without checking back first. If the server answers that nothing changed, the stored copy is used and no content is transferred.<\/p>\n<p>So <code>no-cache<\/code> is not &#8220;do not cache&#8221;. It is &#8220;cache, but revalidate every time&#8221; &#8211; and it exists precisely to make caching possible for pages that change unpredictably. A short check costs a fraction of a full transfer.<\/p>\n<p>Writing <code>no-store<\/code> where <code>no-cache<\/code> was meant throws away that saving on every single request. Writing <code>no-cache<\/code> where <code>no-store<\/code> was meant leaves a copy of something confidential on a disk.<\/p>\n<h2>Two numbers for two stores<\/h2>\n<p><code>max-age<\/code> is the lifetime in seconds. <code>s-maxage<\/code> is the same thing for shared stores only, and it overrides <code>max-age<\/code> there.<\/p>\n<p>Wikipedia&#8217;s front page shows why both exist. Its header reads <code>s-maxage=86400, must-revalidate, max-age=3600<\/code>: the CDN may keep the page for a full day, a browser for one hour. The expensive store holds it long, the personal store briefly &#8211; and one line does both.<\/p>\n<p>Without <code>s-maxage<\/code>, the shared store simply follows <code>max-age<\/code>. That is the common case, and it is why a CDN sometimes holds a page far longer or shorter than intended: nobody wrote a separate number for it.<\/p>\n<p><code>must-revalidate<\/code> completes the picture. Once the lifetime has run out, the stored copy may not be used any more, not even briefly, not even if the server is unreachable. Without it, a cache is allowed some latitude with an expired copy.<\/p>\n<figure class=\"lw-illu\">\n<img decoding=\"async\" src=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/illustrationen\/illu-cache-control.webp\" width=\"1120\" height=\"580\" loading=\"lazy\" alt=\"Two shelves of very different length holding the same kind of tiles, and a single coral tile lying on the ground below both\"><br \/>\n<\/figure>\n<h2>Who is allowed to store it at all<\/h2>\n<p><code>private<\/code> and <code>public<\/code> do not describe the content. They name the store.<\/p>\n<p><code>private<\/code> means: only the browser of one person. Shared caches must not keep this response. It is the right setting for anything showing a name, a basket, an account balance &#8211; anything assembled for one visitor.<\/p>\n<p><code>public<\/code> means: shared stores may keep it too. It also overrides a few rules that would otherwise prevent caching, which is why it appears on pages that are perfectly cacheable anyway.<\/p>\n<p>The failure here is quiet and serious: a personalised page without <code>private<\/code>, behind a CDN, gets stored once and served to the next visitor complete with the first visitor&#8217;s name. Nothing crashes, nothing logs an error, and the page looks correct &#8211; to the wrong person.<\/p>\n<h2>The stale answers that are served on purpose<\/h2>\n<p>Two additions allow a cache to serve an expired copy deliberately, and both make sites feel faster than they are.<\/p>\n<p><code>stale-while-revalidate<\/code> says: if the copy has just expired, hand it over anyway and fetch a fresh one in the background. The visitor waits for nothing; the next visitor gets the new version.<\/p>\n<p><code>stale-if-error<\/code> says: if the server is unreachable, keep serving the old copy rather than an error page. A site with this setting survives a short outage without anyone noticing.<\/p>\n<p>The BBC&#8217;s front page uses both, with 30 and 90 seconds. GitHub, by contrast, sends <code>max-age=0, private, must-revalidate<\/code> &#8211; nothing is served without asking, because a repository page must never be a second out of date.<\/p>\n<p>Neither is more correct. They are different answers to the same question: what is worse here, a slow page or an old one.<\/p>\n<h2>What one header line shows<\/h2>\n<p>The line arrives with every response and reading it costs one request.<\/p>\n<p>Four questions are worth asking. Is the intent <code>no-store<\/code> or <code>no-cache<\/code> &#8211; keeping nothing, or keeping and asking. Does a personalised page carry <code>private<\/code>. Is there a separate <code>s-maxage<\/code> for the shared store, or is one number silently doing both jobs. And is the lifetime plausible for how often the content actually changes.<\/p>\n<p>The <a href=\"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/http-security-header-checker\/\">HTTP security header checker<\/a> reads the headers of any address as a browser reads them, following the redirects on the way.<\/p>\n<p>The useful answer is one sentence: whether this page is stored where it should be, for as long as it should be &#8211; and by nobody else.<\/p>\n<div class=\"lw-faq\">\n<h2>Questions and answers<\/h2>\n<h3>Why does no-cache only save a transfer when the response carries an ETag or a Last-Modified?<\/h3>\n<p>Because the check needs something to compare. The browser sends it back as <code>If-None-Match<\/code> or <code>If-Modified-Since<\/code>, and only then can the server answer 304 Not Modified without sending the content again. Without either, there is nothing to compare, and every check turns into a full transfer.<\/p>\n<h3>How does an outdated page disappear from a CDN that holds it with s-maxage=86400?<\/h3>\n<p>Not through a new header. Copies already stored carry their lifetime with them; a changed header only applies to the next copy. For the CDN, the remedy is clearing its cache through its admin interface or API, usually called a purge.<\/p>\n<p>Browsers offer no such means. A copy with max-age=3600 stays there for up to an hour, whatever the server sends in the meantime. That fits the split in the Wikipedia example: the store the operator can empty may hold the page for a long time, the one it cannot reach only briefly.<\/p>\n<p>For scripts and stylesheets the usual route is a different one: a new address per version, for example with a version number or a hash in the file name, combined with a long lifetime. A changed file then has a new address, and no old copy stands in the way.<\/p>\n<h3>Which rule does public override, and when does that become risky?<\/h3>\n<p>The most important one concerns requests carrying an Authorization header, such as those behind password protection through HTTP authentication. Under RFC 9111 a shared cache normally may not reuse the response to such a request for other requests, because it is meant for a signed-in person. public explicitly allows it, as do s-maxage and must-revalidate.<\/p>\n<p>It becomes risky when a template sets public on every page and a protected area falls under it: the CDN may then store the response and serve it to visitors who never signed in. Protected areas need private or no-store in the header, regardless of what the rest of the site sends.<\/p>\n<h3>Does stale-if-error also apply when the server responds, but with an error?<\/h3>\n<p>Yes. Under RFC 5861, the status codes 500, 502, 503 and 504 count as errors too, not only an unreachable server. Whether a cache honours the directive at all depends on the CDN and the browser, though, and an error page sent with status 200 is not recognised as an error by either.<\/p>\n<\/div>\n<div class=\"lw-quellen\">\n<h2>Sources<\/h2>\n<ul>\n<li><a href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc9111.html\" target=\"_blank\" rel=\"noopener noreferrer\">RFC 9111: HTTP Caching<\/a><\/li>\n<li><a href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc9110.html\" target=\"_blank\" rel=\"noopener noreferrer\">RFC 9110: HTTP Semantics<\/a><\/li>\n<\/ul>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>One header line decides how long a page is kept and by whom. Two of its words look interchangeable and do opposite things, and one number applies to a storage most people never think about.<\/p>\n","protected":false},"author":1,"featured_media":16121,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[158],"tags":[91099,91219,91315],"class_list":["post-13498","post","type-post","status-publish","format-standard","hentry","category-tutorials-en-web-development","tag-server-administration","tag-tutorial","tag-web-performance"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Cache-Control Explained: What no-cache, no-store, max-age and s-maxage Each Do | Lukas Wojcik<\/title>\n<meta name=\"description\" content=\"What no-cache, no-store, max-age, s-maxage and private each do, why the two that sound alike are opposites, and how to read a real Cache-Control line.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.lukaswojcik.com\/blog\/en\/web-development\/tutorials-en-web-development\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Cache-Control Explained: What no-cache, no-store, max-age and s-maxage Each Do | Lukas Wojcik\" \/>\n<meta property=\"og:description\" content=\"What no-cache, no-store, max-age, s-maxage and private each do, why the two that sound alike are opposites, and how to read a real Cache-Control line.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/en\/web-development\/tutorials-en-web-development\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-13T05:35:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-13498-cache-control-explained-no-cache-no--nz.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Lukas Wojcik\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Lukas Wojcik\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/web-development\\\/tutorials-en-web-development\\\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/web-development\\\/tutorials-en-web-development\\\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\\\/\"},\"author\":{\"name\":\"Lukas Wojcik\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"headline\":\"Cache-Control Explained: What no-cache, no-store, max-age and s-maxage Each Do\",\"datePublished\":\"2026-10-13T05:35:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/web-development\\\/tutorials-en-web-development\\\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\\\/\"},\"wordCount\":1294,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"image\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/web-development\\\/tutorials-en-web-development\\\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-13498-cache-control-explained-no-cache-no--nz.png\",\"keywords\":[\"Server Administration\",\"Tutorial\",\"Web Performance\"],\"articleSection\":[\"Tutorials\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/web-development\\\/tutorials-en-web-development\\\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/web-development\\\/tutorials-en-web-development\\\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/web-development\\\/tutorials-en-web-development\\\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\\\/\",\"name\":\"Cache-Control Explained: What no-cache, no-store, max-age and s-maxage Each Do | Lukas Wojcik\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/web-development\\\/tutorials-en-web-development\\\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/web-development\\\/tutorials-en-web-development\\\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-13498-cache-control-explained-no-cache-no--nz.png\",\"datePublished\":\"2026-10-13T05:35:00+00:00\",\"description\":\"What no-cache, no-store, max-age, s-maxage and private each do, why the two that sound alike are opposites, and how to read a real Cache-Control line.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/web-development\\\/tutorials-en-web-development\\\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/web-development\\\/tutorials-en-web-development\\\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/web-development\\\/tutorials-en-web-development\\\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-13498-cache-control-explained-no-cache-no--nz.png\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-13498-cache-control-explained-no-cache-no--nz.png\",\"width\":1200,\"height\":630,\"caption\":\"Cache-Control Explained: What no-cache, no-store, max-age and s-maxage Each Do\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/web-development\\\/tutorials-en-web-development\\\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Cache-Control Explained: What no-cache, no-store, max-age and s-maxage Each Do\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\",\"name\":\"Lukas Wojcik - Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\",\"name\":\"Lukas Wojcik\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"width\":424,\"height\":636,\"caption\":\"Lukas Wojcik\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\"},\"sameAs\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Cache-Control Explained: What no-cache, no-store, max-age and s-maxage Each Do | Lukas Wojcik","description":"What no-cache, no-store, max-age, s-maxage and private each do, why the two that sound alike are opposites, and how to read a real Cache-Control line.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.lukaswojcik.com\/blog\/en\/web-development\/tutorials-en-web-development\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\/","og_locale":"en_US","og_type":"article","og_title":"Cache-Control Explained: What no-cache, no-store, max-age and s-maxage Each Do | Lukas Wojcik","og_description":"What no-cache, no-store, max-age, s-maxage and private each do, why the two that sound alike are opposites, and how to read a real Cache-Control line.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/en\/web-development\/tutorials-en-web-development\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\/","og_site_name":"Lukas Wojcik - Blog","article_published_time":"2026-10-13T05:35:00+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-13498-cache-control-explained-no-cache-no--nz.png","type":"image\/png"}],"author":"Lukas Wojcik","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Lukas Wojcik","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/web-development\/tutorials-en-web-development\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\/#article","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/web-development\/tutorials-en-web-development\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\/"},"author":{"name":"Lukas Wojcik","@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"headline":"Cache-Control Explained: What no-cache, no-store, max-age and s-maxage Each Do","datePublished":"2026-10-13T05:35:00+00:00","mainEntityOfPage":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/web-development\/tutorials-en-web-development\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\/"},"wordCount":1294,"commentCount":0,"publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"image":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/web-development\/tutorials-en-web-development\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\/#primaryimage"},"thumbnailUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-13498-cache-control-explained-no-cache-no--nz.png","keywords":["Server Administration","Tutorial","Web Performance"],"articleSection":["Tutorials"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/web-development\/tutorials-en-web-development\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/web-development\/tutorials-en-web-development\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\/","url":"https:\/\/www.lukaswojcik.com\/blog\/en\/web-development\/tutorials-en-web-development\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\/","name":"Cache-Control Explained: What no-cache, no-store, max-age and s-maxage Each Do | Lukas Wojcik","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/web-development\/tutorials-en-web-development\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\/#primaryimage"},"image":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/web-development\/tutorials-en-web-development\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\/#primaryimage"},"thumbnailUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-13498-cache-control-explained-no-cache-no--nz.png","datePublished":"2026-10-13T05:35:00+00:00","description":"What no-cache, no-store, max-age, s-maxage and private each do, why the two that sound alike are opposites, and how to read a real Cache-Control line.","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/web-development\/tutorials-en-web-development\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/web-development\/tutorials-en-web-development\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/web-development\/tutorials-en-web-development\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\/#primaryimage","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-13498-cache-control-explained-no-cache-no--nz.png","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-13498-cache-control-explained-no-cache-no--nz.png","width":1200,"height":630,"caption":"Cache-Control Explained: What no-cache, no-store, max-age and s-maxage Each Do"},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/web-development\/tutorials-en-web-development\/cache-control-explained-what-no-cache-no-store-max-age-and-s-maxage-each-do\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Cache-Control Explained: What no-cache, no-store, max-age and s-maxage Each Do"}]},{"@type":"WebSite","@id":"https:\/\/www.lukaswojcik.com\/blog\/#website","url":"https:\/\/www.lukaswojcik.com\/blog\/","name":"Lukas Wojcik - Blog","description":"","publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.lukaswojcik.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9","name":"Lukas Wojcik","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","width":424,"height":636,"caption":"Lukas Wojcik"},"logo":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg"},"sameAs":["https:\/\/www.lukaswojcik.com\/blog"]}]}},"_links":{"self":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/13498","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/comments?post=13498"}],"version-history":[{"count":3,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/13498\/revisions"}],"predecessor-version":[{"id":22697,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/13498\/revisions\/22697"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media\/16121"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=13498"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/categories?post=13498"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=13498"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}