Manage cache bahavior

Firebase Hosting uses a powerful global CDN to make your site as fast as
possible.

Any requested static content is automatically cached on the CDN. If you
redeploy your site's content, Firebase Hosting automatically clears all your
cached static content across the CDN until the next request.

However, because Cloud Functions and Cloud Run services generate content
dynamically, the content for a given URL can vary based on such things as user
input or the user's identity. To account for this, requests that are handled by
backend code do not cache on the CDN by default.

You can, though, configure caching behavior for dynamic content. For
example, if a function generates new content only periodically, you can speed up
your app by caching the generated content for at least a short period of time.

You can also potentially reduce function execution costs because the content is
served from the CDN rather than via a triggered function. Read more about
optimizing function execution and services in the
Cloud Functions and
Cloud Run documentation.

Set Cache-Control

The main tool that you use to manage cache for dynamic content is the
Cache-Control header. By configuring this header, you can communicate both to
the browser and the CDN how long your content can be cached. In your function,
you set Cache-Control like so:

res.set('Cache-Control', 'public, max-age=300, s-maxage=600');

In this example header, the directives do three things:

public — Marks the cache as public. This means that both the browser and
the intermediate servers (meaning the CDN for Firebase Hosting) can cache
the content.

Note: By default, Cache-Control is set to private. This means that if you
don't explicitly set Cache-Control to public, only the browser of the
requesting user is allowed to cache the content.

max-age — Tells the browser and the CDN how many seconds that they can cache
the content. When the set time expires, the browser and the CDN must
revalidate the content with the origin server. In the example header, we're
allowing the browser and the CDN to cache the content for five minutes (see
s-maxage below for specific controls for CDN caching).

s-maxage — Overrides the max-age directive for the CDN-caching only; tells
the CDN how many seconds that it can cache the content. When the set time
expires, the CDN must revalidate the content with the origin server. In the
example header, we're overriding the setting for max-agefor the CDN only
and allowing the CDN to cache the content for ten minutes.

For max-age and s-maxage, set their values to the longest amount of time
that you're comfortable with users receiving stale content. If a page changes
every few seconds, use a small time value. However, other types of content can
be safely cached for hours, days, or even months.

When is cached content served?

Vary headers

The
Vary header
determines which request headers should be used to provide an appropriate
response (whether the cached content is valid or if the content should be
revalidated with the origin server).

Most of the time, you don't need to worry about the Vary header.
Firebase Hosting automatically sets an appropriate Vary header on your
response for common situations. This includes making sure that any session
cookie or authorization header that you're using is made part of the cache key,
which prevents accidental leaks of content.

In some advanced use cases, you might have other headers that you need to affect
the cache. When that's the case, you can simply set the Vary header on your
response:

res.set('Vary', 'Accept-Encoding, X-My-Custom-Header');

With these settings, two otherwise identical requests with different
X-My-Custom-Header headers are cached separately.

Note: Only GET and HEAD requests can be cached. HTTP requests using other
methods are never cached.Note: Be careful when adding settings to the Vary header. The more settings
that you add, the less likely it is that the CDN can serve cached content.
Also remember that Vary is based on request headers, not response
headers.

Using cookies

When using Firebase Hosting together with Cloud Functions or Cloud Run,
cookies are generally stripped from incoming requests. This is necessary to
allow for efficient CDN cache behavior. Only the
specially-named __session cookie is permitted to pass through to the execution
of your app.

When present, the __session cookie is automatically made a part of the cache
key, meaning that it's impossible for two users with different cookies to
receive the other's cached response. Only use the __session cookie if your
app serves different content depending on user authorization.