Cookie

List of cookies attached to a request.

Fastly reads this header from requests. It is defined by an external standard.

Cookies are one of the most important mechanisms for authentication, personalization, and tracking on the web, but can also present challenges to efficient caching and security. Fastly parses the Cookie header in the same way as other HTTP headers and presents it in VCL as req.http.Cookie. Like all headers that are formatted as comma-delimited key-value pairs, individual fields within the Cookie header can be accessed using subfield syntax:

if (req.http.cookie:logged_in == "true") {
// ...
}

Limits

Cookie headers are subject to a maximum length of 32KB (including all cookie keys and values, as serialized), which is lower than other headers. If a request is received with a Cookie header longer than that, it will be stripped and Fastly-Cookie-Overflow will be set.

Best practices

Cookies can lead to undesirable outcomes. At worst, if a cookie header is forwarded to your backend server, the backend uses the cookie value to generate personalized content, and that content is then cached by Fastly, a user may end up receiving content intended for someone else. A theoretical solution to this, adding a Vary: Cookie header to the response, leads to another bad outcome: the response is most likely not cacheable at all, and Fastly will forward all requests to your backend.

Consider the following best practices to avoid these problems when working with cookies:

Parse cookies into custom headers

In VCL, parse and validate cookies, then move the resulting cleaned data to new custom headers. A simple approach would be to move individual cookies to custom headers without parsing the cookie values:

set req.http.Session = req.http.Cookie:session;
set req.http.Opt-In = req.http.Cookie:opt_in;

Even better, consider parsing individual cookie values and creating further separation between discrete data properties. For example, you could parse req.http.Cookie:session into req.http.User-Name and req.http.User-Role. This reduces the granularity of the data that is sent to the backend and allows for more effective use of Vary.

Learn more about parsing cookies with our example JSON Web Tokens tutorial.

One effective way to ensure that backend servers do not use a Cookie in an undesirable way is to remove the header entirely from the request before forwarding the request to the backend. Combined with extracting relevant data from cookies and creating custom headers, this is an excellent way to ensure separation of concerns.

unset req.http.Cookie;

Vary on custom headers

The Vary header can be used to tell Fastly to hold multiple variations of the same resource, based on different values of certain specified request headers. Therefore, while it can be tempting to use Vary: Cookie, this will likely be so specific as to make the response impossible to use again. Instead, if the response generated by the backend server is contingent on a value in a cookie, transfer that value to a custom header at the edge, and then Vary on that custom header in the response (e.g., Vary: User-Role).

Since custom headers are unknown downstream of Fastly, they should be removed from the Vary header in vcl_deliver and replaced with a private cache directive:

unset resp.http.Vary:User-Role;
set resp.http.Cache-Control:private = "";

The private directive still allows the response to be cached by the end-user's browser, but not by any other shared caches or CDNs that sit between the user and Fastly.

Set cookies at the edge or in dedicated requests

Responses from a backend server that include a Set-Cookie header are usually not cacheable. By default, Fastly disables caching of such responses and, for customers using custom VCL, we recommend this behavior as part of our standard VCL boilerplate.

As a result, allowing application servers to attach Set-Cookie headers to any response can result in lower cache performance and more complex behavior that can be harder to reason about at scale. Instead, consider setting cookies at the edge using VCL code in vcl_deliver, which runs after the resource has been read from cache, allowing cached content to be tweaked for the needs of individual users without affecting the cache.

Alternatively, establish a subset of URL paths that will set cookies on responses from the backend, and prevent caching of those responses entirely. This is a common pattern for login flows.