JWT vs session cookies: which auth model fits?

6 min readUpdated May 24, 2026

Both keep a user logged in, but they make opposite trade-offs around state and revocation. Picking the wrong one shows up later as a security or scaling headache.

JWTStateless tokens
vs
Session cookiesServer-side sessions
JWTSession cookies
Server stateNone (self-contained)Session store required
RevocationHard (valid until exp)Easy (delete the session)
ScalingNo shared store neededNeeds shared/sticky sessions
Payload sizeLarger (sent every request)Small cookie (just an ID)
Best forAPIs, service-to-serviceClassic web apps
XSS exposureHigh if in localStorageLow with httpOnly cookie

The core trade-off: revocation

A server session can be killed instantly — delete the row and the user is logged out. A JWT is valid until it expires; you cannot easily revoke one without adding back the very server-side state JWTs were meant to avoid (a denylist).

This is why JWTs usually pair short-lived access tokens with longer-lived refresh tokens, so the blast radius of a leaked token is small.

Storage and XSS

Where you store the credential matters more than the format. A token in localStorage is readable by any injected script (XSS). An httpOnly cookie is not — which is why session cookies, or JWTs *stored in httpOnly cookies*, are safer than tokens in JS-accessible storage.

You can decode any token to inspect its claims in the JWT Decoder — but remember decoding is not verifying.

The verdict

For a single web app, server session cookies are simpler and easier to revoke. For APIs, mobile clients, or microservices, JWTs shine by removing shared state — just keep them short-lived and store them in httpOnly cookies. Inspect tokens in the JWT Decoder.

Frequently asked questions

Are JWTs more secure than sessions?
Not inherently. They make different trade-offs. Sessions are easier to revoke; JWTs avoid shared state. Security depends mostly on storage (httpOnly cookies) and short lifetimes.
Why is revoking a JWT hard?
A JWT is valid until its exp claim passes. To revoke early you must track invalidated tokens server-side — which reintroduces the state JWTs were meant to remove.
Should I store a JWT in localStorage?
Prefer an httpOnly cookie. localStorage is readable by JavaScript, so an XSS bug can steal the token.

Try it yourself

Free, in-browser tools for everything above.