Skip to main content
Back to Guides
Basics5 min read

How Cookies Work: The Set-Cookie Header

A cookie is a name-value pair a server hands the browser in one HTTP header, and the browser hands back on every matching request. Here's the full round trip and every attribute that shapes it.

Strip away the tracking panic and a cookie is a small, dull thing: a name, a value, and a handful of rules about when to send it. The whole mechanism lives in two HTTP headers. A server sends Set-Cookie in a response; the browser stores what it gets and returns it in a Cookie header on future requests. That round trip is the foundation of logins, carts, and most web tracking.

HTTP is stateless. Each request stands alone with no memory of the last one. Cookies are the workaround that gives a site memory, the reason a website can tell it's still you between clicks. Here's exactly how the round trip works.

The round trip in two headers

When a server wants the browser to remember something, it includes a response header:

Set-Cookie: session_id=a3fWa

The browser stores that pair. On every later request to the same site, as long as the cookie's rules match, the browser attaches it:

Cookie: session_id=a3fWa

A server can set several cookies at once by sending multiple Set-Cookie headers, one per cookie. The browser bundles all the matching ones into a single Cookie header, separated by semicolons, on the way back. That's the core of it. Everything else is attributes that narrow down when the browser is allowed to send the pair.

The attributes that shape a cookie

After the name=value pair, a Set-Cookie header can carry a list of semicolon-separated attributes. Each one constrains the cookie in a different dimension:

  • Expires / Max-Age: how long the cookie lives. Max-Age is a number of seconds and takes precedence when both are present; a cookie with neither is a session cookie, dropped when the browser session ends. See session vs persistent cookies.
  • Domain: which hosts receive the cookie. Omit it and the cookie is host-only. Set it and subdomains are included too.
  • Path: which URL paths the cookie applies to. Path=/account means the cookie rides along on /account and everything under it, and nothing else.
  • Secure: send only over HTTPS.
  • HttpOnly: hide the cookie from JavaScript's document.cookie.
  • SameSite: control whether the cookie rides along on cross-site requests.

A fully specified cookie reads like a sentence of these: Set-Cookie: id=a3fWa; Max-Age=2592000; Domain=example.com; Path=/; Secure; HttpOnly; SameSite=Lax. Each attribute deserves its own attention, and the deep dives are linked at the end.

Set-Cookie attributes

AttributeWhat it controlsDefault when omitted
Expires / Max-AgeLifetimeSession cookie, deleted on session end
DomainWhich hosts receive itHost-only, no subdomains
PathWhich URL paths receive itThe path of the setting request
SecureHTTPS-only sendingSent over HTTP too
HttpOnlyHidden from JavaScriptReadable by document.cookie
SameSiteCross-site sendingTreated as Lax by modern browsers

Two ways a cookie gets set

The server route is the Set-Cookie header above. There's a second route: JavaScript on the page can create cookies by assigning to document.cookie. Analytics libraries do this constantly, which is how a first-party cookie can be written by a third-party script the site loaded. Cookies set this way can't be HttpOnly (JavaScript can't hide a cookie from itself), which is one reason server-set session cookies are safer than script-set ones.

This distinction matters for tracking. A third-party script running in your page can set a cookie under your domain, making it a first-party cookie by storage even though a third party controls it. For the difference that makes, see first-party vs third-party cookies.

Cookies are deliberately small. The practical ceiling is around 4KB per cookie and a few dozen cookies per domain, which is why sites store a short identifier in the cookie and keep the real data on the server. If you're tempted to stuff a lot of state into cookies, that limit is the browser telling you to use a different store, like localStorage or a server-side session.

A cookie is data, not code

Cookies can't execute anything. They're inert strings the browser stores and echoes back. The privacy concern isn't the cookie itself, it's what it enables: a stable identifier that lets a server recognize the same browser over time and build a profile. That's why a 4KB text file gets regulated. For the mechanics of identity, see how tracking cookies work.

Where consent enters

Nothing in the HTTP spec asks whether a cookie is allowed. The browser stores whatever a server or script tells it to, and the GDPR and ePrivacy rules sit entirely on top of that plumbing. Compliance is about controlling which Set-Cookie headers and document.cookie writes are allowed to happen before a visitor agrees.

That's the whole job of a consent tool. CookieBeam scans a site to enumerate every cookie and the script that sets it, sorts them by purpose, and then holds the non-essential scripts until the visitor opts in. Block the script and its Set-Cookie never fires, so the cookie is never stored, which is the technical shape of a compliant reject. CookieBeam also logs each visitor's per-purpose choice, so there's a record of what was allowed. For how that blocking works, see how to block scripts before consent.

See it yourself

Open DevTools, switch to the Network tab, and click any request. The response headers show Set-Cookie lines; the request headers show the Cookie line going back. The Application tab (Chrome) lists every stored cookie with its Domain, Path, Expires, Secure, HttpOnly, and SameSite columns broken out. It's the fastest way to learn what a site is actually storing on you.

Deep dives on the attributes: Domain and Path scoping, Secure and HttpOnly, and SameSite.

How Cookies Work: The Set-Cookie Header | CookieBeam | CookieBeam