All posts
·5 min read

JWT vs session auth: which to pick in 2026

The honest trade-offs between JWTs and server-side sessions for backend auth, and why session cookies still win for most SMB apps.

authJWTsessions

Sessions are not dead

JWTs took over thought leadership around 2015. By 2020, every junior engineer assumed they were the right answer. They often are not.

Here is the honest version.

What JWTs are good at

  • Stateless services — the token contains the user info, no DB lookup needed
  • Cross-domain APIs — share auth across multiple services without a shared session store
  • Mobile and SPA clients that need to send a token in headers
  • Short-lived, narrow-scope tokens — service-to-service auth, OAuth access tokens

Where JWTs hurt

  • Revocation — a JWT is valid until it expires. Logging a user out instantly requires either a blocklist (now you have state again) or very short expiries (now you have refresh-token complexity).
  • Token size — a JWT with a few claims is 500+ bytes. That is on every request.
  • The crypto footgunalg: "none" attacks, key confusion, library bugs. Get this wrong and you have a security incident.

What server-side sessions are good at

  • Standard web apps — cookie + session store is what browsers were built for
  • Instant revocation — delete the session row, the user is logged out
  • Smaller payloads — a session cookie is ~30 bytes
  • Battle-tested libraries that handle CSRF, cookie flags, and key rotation

The decision tree

  • Web app, one or a few backends, normal browser users → sessions in a cookie
  • Mobile app or SPA across many backends → JWTs
  • Service-to-service inside one company → JWTs (short-lived) or API keys

Most SMB apps fall in the first bucket. We ship session cookies for them.

Implementation in FastAPI

  • Sessions: fastapi-users with the cookie backend, sessions in Postgres or Redis
  • JWTs: fastapi-users with the JWT backend, or authlib for OAuth flows

fastapi-users does both. The choice between them is a config line, not a rewrite.

What we will not do

We will not roll our own auth. We have never seen a hand-rolled auth library that did not have a bug serious enough to require a rewrite. Use a library. fastapi-users and Authlib are both good.

If you need an identity provider rather than a library, use Auth0, Clerk, or Supabase Auth. The cost is worth it.

Got a workflow problem?

Let's talk about whether n8n, a custom backend, or a hybrid fits your case.

A 30-minute discovery call. Free, honest, you leave with a written direction either way.

Start QuizBook a Call