Comparison

JWT vs Session Cookies

A session cookie holds a meaningless identifier and the server looks up the real state. A JWT carries the claims themselves, signed so the server can trust them without a lookup. Sessions are trivial to revoke but need shared storage. JWTs scale across services but cannot be withdrawn before they expire. Most single applications are better served by sessions.

JWT Decoder

Read a JSON Web Token header, payload and expiry.

Open the tool

This is usually presented as old versus modern, which is the wrong frame. It is a straight trade: sessions keep state on the server and get instant revocation; JWTs move state to the client and get statelessness. Neither is free.

The question that settles it in practice is what happens when you need to log someone out immediately — a compromised account, a sacked employee, a withdrawn permission. Sessions handle that in one delete. JWTs, by design, do not.

How each one works

  • Session cookie: the cookie holds a random opaque ID. Every request looks the session up in shared storage to find who the user is.
  • JWT: the token holds the claims — user ID, roles, expiry — signed with a key. The server verifies the signature and trusts the contents without a lookup.

Revocation, the deciding factor

A session is revoked by deleting it: the next request fails immediately. A JWT stays valid until it expires, because verification is a signature check with nothing to consult. The usual answer is short-lived access tokens plus a refresh token — but that means a lookup on refresh, which is server state again, arrived at by a longer route. If you need immediate revocation and are not building across services, sessions do it more simply.

Where JWTs genuinely win

When several independent services must authenticate the same user without sharing a session store. Each verifies the signature with a public key and needs no network call and no shared database. That is the problem JWTs were designed for, and for it they are the right answer.

  • Multiple services or teams that cannot share session storage.
  • Third-party API access, where OpenID Connect issues tokens anyway.
  • Short-lived, single-purpose tokens such as a signed download link.
  • Server-to-server authentication with no browser involved.

Where sessions genuinely win

A single application with one datastore — which describes most software. Sessions are simpler, revocation is instant, the cookie carries no data worth stealing, and changing a user's permissions takes effect on the next request rather than on the next token refresh. The storage cost is a Redis key.

Storage, and the mistake that matters

Whichever you choose, keep the credential in an HttpOnly, Secure, SameSite cookie. Storing a JWT in localStorage is the most common security mistake in this area: any injected script can read it, and unlike a session cookie it carries its own authority wherever it is replayed. A JWT in a cookie is fine. A JWT in localStorage turns every XSS into a full account takeover.

Frequently asked questions

Can I revoke a JWT?
Not without giving up statelessness. The workarounds — a denylist, a token version checked per request, very short expiry plus refresh — all reintroduce a lookup. If immediate revocation matters, that is a strong argument for sessions.
Are JWTs more scalable than sessions?
Marginally, and rarely decisively. A session lookup is a single key read from Redis, measured in microseconds. Unless you are operating across services that cannot share storage, session lookup is almost never the bottleneck it is assumed to be.
Where should I store a JWT in a browser?
In an HttpOnly, Secure, SameSite cookie — the same place as a session ID. localStorage is readable by any script on the page, so a single XSS hands over a token that authenticates on its own.
Is a JWT encrypted?
No. A standard JWT is signed, not encrypted, and anyone holding it can read every claim. Never put anything confidential in the payload. JWE exists for encrypted tokens and is far less commonly used.
Can I use both?
Yes, and many systems do. Sessions for the browser-facing application, where revocation matters, and short-lived JWTs for service-to-service calls behind it. They solve different problems and mixing them deliberately is reasonable.

Tools used in this guide

All tools →
All guides →

Last reviewed .