Security·July 1, 2026

Sessions vs JWTs: picking the right auth model for a web app

JWTs got popular for reasons that don't apply to most web apps. Learn when a plain, secure server-side session is still the better, simpler call to make.

JWTs became the default recommendation in a lot of tutorials, for reasons that don't apply to most web apps. This guide explains what problem JWTs actually solve, their real downsides, and when a plain server-side session is still the better call.

Key takeaways

  • JWTs solve a real problem: verifying identity without a database lookup, for multi-client or multi-domain systems.
  • A typical product with one backend and one frontend isn't that system, and a session solves the same problem more simply.
  • A JWT can't be revoked before it expires without reintroducing the database lookup it was meant to avoid.
  • The right default for a single-backend app is a server-side session with a secure, httpOnly cookie.

Why JWTs became the default recommendation

JWTs became the default recommendation in a lot of tutorials because they solve a real problem for a specific kind of system: an API serving multiple independent clients, possibly across different domains or services, where a server checking a session store on every request would add real latency and coupling.

For that shape of system, a signed token the client holds and the server can verify without a database lookup is a genuine win.

Why most apps aren't that system

Most web apps are not that system. A typical product has one backend and one frontend, both under your team's control, and a session cookie backed by a fast in-memory or database-backed session store solves the same authentication problem with less complexity and fewer footguns.

The real footguns with JWTs

The footguns are real. A JWT can't be revoked before it expires without adding a server-side blocklist, at which point the system has quietly reintroduced the database lookup it was meant to avoid, while keeping the added complexity of token signing and verification.

Short expiry times mitigate this but push the problem into refresh token handling, which has its own well-documented set of mistakes, particularly around where the refresh token gets stored and how it's protected from theft.

What sessions get you instead

Sessions, by contrast, revoke instantly since the session record simply gets deleted. They work well with standard CSRF protections when the cookie is set correctly, and don't require the client to manage token storage and refresh logic at all.

Which one to use

The right default for a single-backend web app is usually a server-side session with a secure, httpOnly cookie.

JWTs earn their place when there's a genuine multi-service or third-party API scenario: mobile clients hitting the same API as partner integrations, or a microservice architecture where services need to verify identity without a shared session store. We recommend reaching for that complexity when the problem actually requires it, not because it's the modern-sounding choice, the same question worth asking when choosing between REST and GraphQL for that same API.

Common mistakes

  • Choosing JWTs because they're the modern-sounding choice. The decision should come down to whether you actually have a multi-client or multi-service system.
  • Not planning for revocation. Revoking a JWT before it expires usually means reintroducing the database lookup it was meant to avoid.
  • Underestimating refresh token handling. Where the refresh token is stored and how it's protected from theft is its own well-documented source of mistakes.

FAQ

Why did JWTs become popular?

They solve a real problem for systems with multiple independent clients, letting a server verify identity without a database lookup.

What's the main downside of JWTs?

They can't be revoked before they expire without adding a server-side blocklist, which reintroduces the database lookup they were meant to avoid.

When should I use a session instead of a JWT?

For a typical single-backend, single-frontend app, where a session cookie solves the same problem with less complexity.

The bottom line

JWTs solve a real problem, but most web apps don't have that problem. A server-side session with a secure, httpOnly cookie is the right default for a single-backend app. Reach for JWTs when a genuine multi-service or third-party scenario actually requires them.

Building auth for a new product? Talk to our team.

Tell us what you're building.

Describe the problem in plain language. An engineer reads every message and replies within one business day.

Write to Us
Reply
Within one business day
First call
Free, no commitment
Confidentiality
NDA on request, before you share anything