Cache app content Stay organized with collections Save and categorize content based on your preferences.
Cloud CDN is a critical part ofApp Hosting's support for your web app. Everyrequest to your backend goes through Cloud CDN first. Content that is alreadycached in the CDN is served immediately back to the user, skipping a trip to theCloud Run service running your web app's server code. You can learn more aboutthe general benefits of CDNs atweb.dev.
Though the basic Cloud CDN configuration is set byApp Hosting and cannot bemodified, there are a number of things you can do to optimize your caching inorder to increase page load speeds, reduce billed uncached content, and minimizetraffic to Cloud Run.
Cacheable content
Cloud CDN stores responses in cache ifALL of the following conditions aretrue:
The request is a GET
The response has a status code of
200,203,204,206,300,301,302,307,308,404,405,410,421,451, or501.The response has a
Cache-Controlheader with amax-ageors-maxagedirective, or anExpiresheader with a timestamp in the future.The response has an
Ageheader or aCache-Controlheader with anexplicitpublicdirective.The response is less than or equal to 10 MiB in size.
andNONE of the following are true:
The response has a
Set-CookieheaderThe response has a
Varyheader with a value other thanAccept,Accept-Encoding,Access-Control-Request-Headers,Access-Control-Request-Method,Origin,Sec-Fetch-Dest,Sec-Fetch-Mode,Sec-Fetch-Site,X-Goog-Allowed-Resources,X-Origin,RSC,Next-Router-State-Tree,Next-Router-Prefetch, orNext-Router-Segment-Prefetch.The response has a
Cache-Controlheader with theno-storeorprivatedirective.The request has a
Cache-Controlheader with ano-storedirective.The request has an
Authorizationheader, unless the response has anexplicit cache control directive.
Vary; usenext/headers with caution.Note: Routes affected by Next.js middleware are not cached.Customize behavior with cache control directives
Next.js
Next.js sets cache-control directives implicitlybased on a number offactors. However, you canoverride these by manuallysetting the header in yournext.config.js file. For example, to ensure a page is notcached in Cloud CDN:
/** @type {import('next').NextConfig} */constnextConfig={headers:async()=>[{source:"/YOUR_PRIVATE_PAGE",headers:[{key:"Cache-Control",value:"private"}],}],};Angular
Angular SSR does not set explicit cache-control directives out of the box. Youcan add your own byspecifying cache-control headers in your serverroutes. For example, to allow Cloud CDN to cache all pages for an hour:
import{RenderMode,ServerRoute}from'@angular/ssr';exportconstserverRoutes:ServerRoute[]=[{path:'**',renderMode:RenderMode.Prerender,headers:{'Cache-Control':'public, max-age=3600',}}];Or to ensure a specific page willnot be cached:
import{RenderMode,ServerRoute}from'@angular/ssr';exportconstserverRoutes:ServerRoute[]=[// ... other routes{path:'YOUR_PRIVATE_PAGE',renderMode:RenderMode.Server,headers:{'Cache-Control':'private',}}];Respected directives
FirebaseApp Hosting's Cloud CDN instance respects the following cache controldirectives:
| Directive | Request | Response |
|---|---|---|
no-store | When present in a request, the response will not be cached. | A response withno-store isn't cached. |
no-cache | Theno-cache request directive is ignored to prevent clients from potentially initiating or forcing revalidation to the origin. | A response withno-cache is cached but must be revalidated with the origin before being served. |
public | N/A | This directive is not required for cacheability, but it is a best practice to include it for content that should be cached by proxies. |
private | N/A | A response with theprivate directive isn't cached by Cloud CDN, even if the response is otherwise considered cacheable. Clients (such as browsers) might still cache the result. Useno-store to prevent all caching of responses. |
max-age=SECONDS | Themax-age request directive is ignored. A cached response is returned as if this header was not included in the request. | A response with themax-age directive is cached up to the defined SECONDS. |
s-maxage=SECONDS | N/A | A response with thes-maxage directive is cached up to the defined SECONDS. If bothmax-age ands-maxage are present,s‑maxage is used by Cloud CDN. Responses with this directive aren't served stale.s-max-age (two hyphens) is not valid for the purposes of caching. |
max-stale=SECONDS | Themax-stale request directive dictates the maximumstaleness (in seconds) that the client is willing to accept. Cloud CDN honors this, and returns a stale cached response only if the staleness of the response is less than themax-stale directive. Otherwise, it revalidates before serving the request. | N/A |
stale-while-revalidate=SECONDS | N/A | A response withstale-while-revalidate is served to a client for up to SECONDS while revalidation takes place asynchronously. |
must-revalidate | N/A | A response withmust-revalidate is revalidated with the origin server after it expires. Responses with this directive aren't served stale. |
proxy-revalidate | A response withproxy-revalidate is revalidated with the origin server after it expires. Responses with this directive aren't served stale. | |
no-transform | N/A | No transforms are applied by Cloud CDN. |
Measure cached and uncached traffic
The "Cloud CDN - Outgoing Bandwidth" graph in theUsage tab of theApp Hosting console shows cached and uncached bytes served, and has a markfor each rollout. You can use this graph to measure the effectiveness of yourcache optimization efforts.
You can also view the cache hit rate for specific routes in your web app withRoute-based Monitoring.
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2026-02-05 UTC.