skip to content

How much data can you actually store in a single HTTP cookie, roughly how many cookies will a browser keep per domain, and what happens when you exceed those limits?

level: juniorimportance: should knowfreq 45%

answer

  1. ~4096 bytes per cookie, name+value+attributes
  2. ≥50 per domain by RFC; Chrome ~180
  3. over the limit = silent drop, no error
  4. eviction: expired first, then least recently used
  5. total Cookie header hits proxy 8 KB limits first

basics

~20 s

Roughly 4096 bytes for the whole Set-Cookie name plus value (attributes count in modern browsers), and at least 50 cookies per domain — Chrome allows about 180. Over the limit the browser silently ignores the Set-Cookie or evicts old cookies; you get no error.

solid answer

~50 s

RFC 6265 says a browser must support at least 4096 bytes per cookie (name + value + attributes), at least 50 cookies per domain, and at least 3000 cookies total. Real browsers land near that: ~4096 bytes per cookie, Chrome ~180 cookies per domain with a per-domain byte cap, plus a global cap in the low thousands. The failure mode is what matters in interviews: it is **silent**. An oversized `Set-Cookie` is simply not stored — no exception, no console error in most engines, and `document.cookie` just does not change. When the per-domain count is exceeded the browser evicts cookies, typically the least recently used or already-expired ones, so an unrelated cookie disappears. Practical consequence: cookies are for small identifiers, not payloads. Store an opaque session id and keep the data server-side, or use localStorage/IndexedDB for non-credential client state. Every cookie is also re-sent on every matching request, so size is a bandwidth and latency cost too.

code

http · 6 lines
http
HTTP/1.1 200 OK
Set-Cookie: blob=AAAA...(5000 bytes)...; Path=/

GET /next HTTP/1.1
Host: app.example.com
Cookie: theme=dark

go deeper

for a junior

Say ~4 KB per cookie and dozens per domain, and that oversized cookies are silently dropped — then note cookies are for ids, not data.

for a middle

Add that name, value and attributes all count, that eviction removes other cookies when the per-domain count is exceeded, and contrast with localStorage.

for a senior

Connect browser limits to server and proxy header limits, cookieless asset domains, and the fact that silent failure means you must measure header size in production.

for a principal

Treat the total per-request cookie budget as a platform constraint you allocate across teams — who is allowed to set cookies on the apex domain, and what the enforcement is.

## The numbers RFC 6265 sets *minimums* a user agent should support, not hard maxima: - at least **4096 bytes** per cookie, counting name, value and attributes together; - at least **50 cookies per domain**; - at least **3000 cookies total**. Browsers implement close to this. Treat 4096 bytes as the practical per-cookie ceiling. Chrome additionally enforces roughly 180 cookies per domain and a per-domain byte budget; Firefox and Safari have comparable caps. None of this is worth memorising precisely — what interviewers want is the order of magnitude (kilobytes, not megabytes) and the awareness that the limit is per cookie *and* per domain. A subtlety: the byte count is of the serialised cookie, and cookie values are typically percent-encoded or base64. A 3000-byte JWT becomes noticeably larger once encoded, and a UTF-8 name or value costs more than one byte per character. ## What failure looks like This is the part candidates get wrong. Exceeding limits does **not** raise an error. - **Oversized single cookie**: the browser drops the `Set-Cookie` header. The response still succeeds with its original status; the cookie simply never appears in the jar. If it was the session cookie, the next request is unauthenticated and the user bounces back to login — a confusing bug that looks like an auth failure. - **Too many cookies for the domain**: the browser makes room by evicting, usually expired cookies first, then least-recently-used ones. A cookie you set an hour ago can vanish because an unrelated feature wrote 40 new ones. - **Too much total data sent**: even if the browser stores everything, it concatenates all matching cookies into one `Cookie` request header. Servers and proxies cap total header size (commonly 8 KB per header block), so the request itself starts failing — typically `431 Request Header Fields Too Large`, or a `400` from an edge proxy — before any browser limit is hit. ## Design consequences **Cookies are identifiers, not storage.** The canonical design is a short opaque session id (tens of bytes) with state in a server-side store. That keeps the request header small and lets you revoke server-side. **Self-contained tokens are the usual bloat source.** A JWT with roles, permissions and profile claims can reach 2–4 KB, and it is re-sent on every request to the domain — including static assets, unless those live on a cookieless host. Two such cookies plus analytics cookies will exceed a proxy's header limit. **Prefer other storage for non-credentials.** `localStorage` (~5 MB per origin) and IndexedDB exist for client state that the server does not need on every request. The trade-off is that they are readable by JavaScript, so they are wrong for session credentials — which is exactly why credentials stay in an `HttpOnly` cookie and everything else does not go into cookies at all. **Serve static assets from a cookieless domain** (or a separate host that never receives your cookies) so kilobytes of cookies are not attached to every image request. **Do not shard a large value across several cookies.** Splitting a 12 KB token into three cookies defeats the per-cookie limit but multiplies request-header cost and creates a partial-write failure mode where one shard is evicted and the value becomes unreconstructable. **Instrument it.** Because failures are silent, teams catch cookie bloat late. Log total `Cookie` header size at the edge, alert on the p99, and after setting a critical cookie verify it round-trips rather than assuming the `Set-Cookie` took effect.

  • Your app must keep 20 KB of user preferences on the client. Where do you put it and why not a cookie?
    Use localStorage or IndexedDB, keyed by the user, and let the server read it only when it needs to. A cookie cannot hold 20 KB at all, and even if split it would be re-sent on every single request to the domain, wasting bandwidth on every asset fetch and risking proxy header limits.

A cookie is a luggage tag, not the suitcase. Write the claim number on the tag and leave the contents at the desk.

saying these in an interview costs you the question

  • Thinking a too-large Set-Cookie throws an error or returns a non-2xx status
  • Quoting 4096 bytes as a per-domain rather than per-cookie limit
  • Assuming attributes like Path and Expires do not count toward the size
  • Splitting a large token across many cookies as a normal solution
  • Believing cookies are a reasonable general-purpose client storage mechanism

context