JWT vs session cookies: which auth model fits?
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.
| JWT | Session cookies | |
|---|---|---|
| Server state | None (self-contained) | Session store required |
| Revocation | Hard (valid until exp) | Easy (delete the session) |
| Scaling | No shared store needed | Needs shared/sticky sessions |
| Payload size | Larger (sent every request) | Small cookie (just an ID) |
| Best for | APIs, service-to-service | Classic web apps |
| XSS exposure | High if in localStorage | Low 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.
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.