By AndyPublished

JWT Size Limit: How Big Can a JWT Be Before Something Breaks?

RFC 7519 does not set a maximum size for a JWT. The practical limit comes from the HTTP infrastructure the token travels through: nginx and Apache reject a single header over about 8 KB by default, Node.js rejects requests whose headers total more than 16 KiB, and browsers are only required to store cookies of about 4 KB. Keep access tokens under roughly 4 KB and they will fit everywhere; past 8 KB, expect failures somewhere.

The rest of this page lists the defaults for common servers, proxies and AWS services, shows how to calculate a token's size before you issue it, and covers the techniques that keep tokens small, from dropping claims to Entra ID's groups overage and opaque reference tokens.

Is There a JWT Size Limit in the Specification?

No. RFC 7519 (JWT) and RFC 7515 (JWS) define the structure and encoding but say nothing about maximum length. A JWT with a megabyte of claims is perfectly valid. The standards also give you no compression for signed tokens: the zip header parameter exists only for encrypted tokens (JWE, RFC 7516), and RFC 8725 advises against compressing data before encryption anyway.

The limits you hit are imposed by every system between the client and your code: the browser's cookie jar, CDNs, load balancers, API gateways, reverse proxies and the application server. The smallest of those is your real JWT token size limit.

JWT Token Size Limits by Server and Proxy

These are the defaults as documented by each project or service. Most self-hosted servers can be raised; the AWS limits listed are fixed quotas. Remember that the header carrying the token includes Authorization: Bearer (22 bytes), and total-header limits also count cookies, user agent and everything else in the request.

ComponentDefault limitApplies toTypical failure
nginx8 KB per header line (large_client_header_buffers 4 8k)One header field400 Bad Request
Apache httpd8190 bytes (LimitRequestFieldSize)One header field, name included400 Bad Request
Node.js http16 KiB (--max-http-header-size)All headers together431 Request Header Fields Too Large
Apache Tomcat8192 bytes (maxHttpHeaderSize)Request line plus all headers400, "Request header is too large"
ASP.NET Core Kestrel32,768 bytes (MaxRequestHeadersTotalSize)All headers together431
AWS Application Load Balancer16 K single header, 64 K all request headersPer header and totalRejected at the load balancer
Amazon API Gateway REST API20,480 bytes (8,000 for private APIs)All header names and valuesRejected at the gateway
Amazon API Gateway HTTP API10,240 bytesRequest line plus header valuesRejected at the gateway
Amazon CloudFront32,768 bytesRequest line, headers and query stringRejected at the edge

The nginx and Apache numbers are the ones most teams meet first, because they sit in front of everything else. nginx returns 400 when a single header field does not fit in one large_client_header_buffers buffer; the fix is large_client_header_buffers 4 16k; in the http or server block. Apache's equivalent is LimitRequestFieldSize. In Node.js, start the process with --max-http-header-size=32768 or pass maxHeaderSize to http.createServer. A quick test against a default Node.js 22 server returned 200 for an 8,000-byte Authorization header and 431 for a 17,000-byte one.

⚠
Raising one limit only moves the failure. A token that passes your nginx may still be rejected by a corporate proxy, a WAF, a CDN or a partner's gateway you do not control. Treat large tokens as a design problem, not a configuration problem.

RFC 6265 §6.1 asks browsers to support "at least 4096 bytes per cookie (as measured by the sum of the length of the cookie's name, value, and attributes)", at least 50 cookies per domain and at least 3000 cookies in total. Browsers treat roughly 4 KB per cookie as the working ceiling, and the name, Path, Domain, Expires and SameSite attributes all count against it. A cookie over the limit is typically dropped silently, so the symptom is a login that appears to succeed and then behaves as if no one signed in.

Some frameworks work around this by splitting a large value across numbered cookies, and ASP.NET Core's cookie authentication and Auth.js both do so. That keeps each cookie under 4 KB but not the request: every chunk is sent on every request to that domain and still counts towards the server's header limits. The storage guide covers the wider trade-offs of cookies versus other storage.

JWT Size Calculator: Working Out the Length

A compact JWS is BASE64URL(header) . BASE64URL(payload) . BASE64URL(signature). Base64url produces 4 characters for every 3 bytes and JWT drops the padding, so each part is ceil(bytes × 4 / 3) characters:

token length = ceil(4/3 × header JSON bytes)
             + ceil(4/3 × payload JSON bytes)
             + ceil(4/3 × signature bytes)
             + 2 (the dots)

The JSON is measured as UTF-8 bytes after serialisation, so whitespace and non-ASCII characters matter. The signature part depends only on the algorithm and key size:

AlgorithmSignature bytesBase64url characters
HS2563243
HS3844864
HS5126486
ES2566486
ES38496128
ES512 (P-521)132176
EdDSA / Ed255196486
RS256 / PS256, 2048-bit key256342
RS256 / PS256, 3072-bit key384512
RS256 / PS256, 4096-bit key512683

An RSA signature is as long as the key's modulus, so a 2048-bit RS256 signature is 256 bytes and costs 342 characters, against 86 for ES256. In a test with the same header and a realistic set of ten claims (issuer URL, GUID subject, audience, scope, email, name, iat, nbf, exp, jti), the token was 560 characters with HS256, 603 with ES256 and 859 with RS256. See ES256 explained if signature size is a factor in your choice.

JWT Payload Size: What Actually Makes Tokens Big

The signature is fixed; the payload is where tokens grow. Adding a groups claim of GUIDs to the RS256 token above made it 3,474 characters with 50 groups and 11,274 characters with 200, well past the 8 KB default of nginx and Apache. The usual causes:

  • ·Group and role lists that grow with the user's tenure in an organisation.
  • ·Fine-grained permissions enumerated as strings (orders:read:region:eu) instead of a small set of scopes.
  • ·Profile data such as addresses, preferences or pictures encoded into claims.
  • ·Nested tokens or certificates, for example an x5c chain in the header, which can add several kilobytes on its own.

How to Measure a JWT's Size

A JWT is plain ASCII, so characters and bytes are the same thing:

echo -n "$TOKEN" | wc -c           # bytes in the token
printf '%s' "$TOKEN" | wc -c       # same, portable

# Size of each part
printf '%s' "$TOKEN" | awk -F. '{print length($1), length($2), length($3)}'
// Node.js: total size and the decoded payload size
const [h, p, s] = token.split('.');
console.log({
  total: token.length,
  headerJson: Buffer.from(h, 'base64url').length,
  payloadJson: Buffer.from(p, 'base64url').length,
  signature: Buffer.from(s, 'base64url').length,
});

Add a check to your issuer's test suite that fails if a token for your most privileged test user exceeds a budget, for example 4,096 bytes. That catches growth when someone adds a claim, long before a user with unusually many groups finds it in production. To see which claims are responsible, paste a token into the jwtdecode.app decoder, which decodes locally in the browser and lists every claim with a description.

How to Reduce JWT Size

Carry fewer, shorter claims

An access token needs what the API uses to authorise the request: typically iss, sub, aud, exp, iat, jti and a scope or role claim, close to the set RFC 9068 requires for JWT access tokens (which adds client_id). Profile details belong in the ID token or a userinfo call. Prefer coarse scopes and roles over enumerated permissions; the scopes vs roles guide shows how to model them, and JWT claims explained lists what each registered claim is for.

Use a groups overage pattern

Microsoft Entra ID caps the groups claim at 200 entries in a JWT (150 in SAML). Above that, it omits the list and instead emits _claim_names and _claim_sources, an overage claim telling the application to fetch group membership from Microsoft Graph. You can apply the same idea to your own issuer: include memberships up to a limit, and past it include a flag that makes the API look them up and cache them. Emitting only application roles or groups assigned to the application, rather than every group the user belongs to, often removes the problem entirely.

Switch to reference tokens

A reference (opaque) token is a random identifier, a few dozen bytes long, that the API exchanges for the token's data through token introspection (RFC 7662) or a shared cache. Size stops being a concern and revocation becomes immediate, at the cost of a lookup per request or per cache miss. A common hybrid is the phantom token pattern: clients hold an opaque token and the API gateway swaps it for a JWT on the internal network, where header limits are under your control.

Choose a smaller signature

Moving from RS256 with a 2048-bit key to ES256 saves 256 characters per token. It will not rescue a token with 200 groups, but it matters on tokens that sit close to a cookie limit. If you are generating new keys anyway, the OpenSSL key guide has the commands.

What About JWT Secret Size?

The secret or key does not travel in the token, so its length has no effect on token size, except that an RSA key's modulus sets the RSA signature length. For HMAC, the secret should be at least as long as the hash output (32 bytes for HS256, per RFC 7518 §3.2), and the HS256 signature is 32 bytes regardless. See the JWT secret key generator for details.

Summary

  • ·There is no JWT size limit in RFC 7519; the limit is set by the infrastructure, most often nginx or Apache's 8 KB per-header default and the 4 KB cookie minimum in RFC 6265.
  • ·Token length is roughly 4/3 of the header, payload and signature bytes combined; RS256 with a 2048-bit key adds 342 characters, ES256 adds 86.
  • ·Measure with echo -n "$TOKEN" | wc -c and enforce a size budget in tests.
  • ·Keep tokens small by carrying only authorisation claims, capping group lists with an overage pattern, or using reference tokens for large or fast-changing data.
Ready to decode a token?
Use the free JWT decoder — paste any token for instant results, entirely in your browser.
Open JWT Decoder