Sessions vs JWT: Two Ways to Keep Users Logged In

Compare server-side sessions and JSON Web Tokens: how each works, their trade-offs, and how to pick the right login approach for your app.

Share on Linkedin Share on WhatsApp

Estimated reading time: 7 minutes

Article image Sessions vs JWT: Two Ways to Keep Users Logged In

When you log in to a website and stay logged in as you click around, something in the background is remembering who you are. The web’s underlying protocol, HTTP, is stateless: each request arrives with no built-in memory of the previous one. Backend developers solve this problem in two main ways, server-side sessions and tokens such as JSON Web Tokens (JWT). This article explains both in plain language and helps you choose between them.

The problem: HTTP forgets everything

Imagine a waiter who forgets every customer the moment they walk away. Every time you want something, you would have to prove who you are again. A web server behaves similarly by default. To avoid asking for a password on every click, the server gives the client something to present in later requests, a kind of proof that the login already happened. That proof can be a session identifier or a signed token.

How server-side sessions work

With sessions, the server keeps the memory. After you log in successfully, the server creates a record containing information about you, such as your user ID, and stores it in memory, a database or a cache. It then sends the browser a random, hard-to-guess session ID, usually in a cookie. On each following request, the browser sends the cookie back, and the server looks up the matching record to know who you are.

  • The browser holds only an opaque identifier, not your data.
  • The server holds the real information and stays in control.
  • Logging a user out simply means deleting the session record.

How JWT works

A JSON Web Token flips the model. Instead of storing the user’s state on the server, the server issues a token that contains the claims itself, for example the user ID and an expiration time. The token is digitally signed, so the server can verify that nobody tampered with it. The client stores the token and sends it with each request, commonly in an Authorization header. The server checks the signature and, if it is valid and not expired, trusts the claims without looking anything up.

A JWT has three parts separated by dots: a header describing the signing algorithm, a payload with the claims, and a signature. An important detail is that the payload is encoded, not encrypted. Anyone who gets the token can read its contents, so you should never put secrets such as passwords inside it.

Strengths of sessions

Sessions are simple and well understood. Because the server owns the state, it can end a session instantly: if an account is compromised or a user logs out, deleting the record immediately invalidates access. Session data can also change on the server without the client needing a new credential. Frameworks have mature session support built in, which lowers the chance of implementation mistakes.

The cost is that the server must store and look up session data on every request. In applications running on many servers, sessions require a shared store, such as a database or an in-memory cache, so that any server can recognize the user.

Strengths of JWT

JWTs are convenient when many separate services need to verify identity without sharing a central session store. Since the token carries its own proof, any service that knows how to check the signature can authenticate the request. That is why JWTs are popular in APIs, mobile apps and microservice architectures, and in scenarios where one system issues the identity and others consume it.

The main weakness is revocation. A token that has already been issued stays valid until it expires, even if the user logs out or the account is disabled, unless you add extra machinery such as a deny list or very short lifetimes. Teams often combine short-lived access tokens with longer-lived refresh tokens to balance convenience and safety.

Side-by-side comparison

AspectServer-side sessionsJWT
Where state livesOn the serverInside the token on the client
What the client sendsAn opaque session IDA signed token with claims
Revoking accessImmediate, delete the recordHarder, needs expiry or deny lists
Server lookupsNeeded on each requestSignature check only
Typical fitTraditional web appsAPIs, mobile apps, distributed services

Where to store the credential safely

Whichever approach you choose, how the browser stores the credential matters. Cookies marked HttpOnly cannot be read by JavaScript, which reduces the damage of cross-site scripting attacks. The Secure flag ensures the cookie is sent only over HTTPS, and the SameSite attribute helps limit cross-site request forgery. Storing tokens in places that scripts can read, such as local storage, is simple but exposes them if the page has a script injection flaw. Always serve login traffic over HTTPS and apply sensible expiration times.

How to choose

  • If you are building a classic website with server-rendered pages, sessions are usually the simplest and safest default.
  • If several independent services or clients must verify identity, JWTs can reduce coupling.
  • If you need instant logout and fine control, lean toward sessions or add revocation support to tokens.
  • Prefer well-tested libraries and frameworks rather than writing your own cryptography or token handling.

A common misconception

It is common to hear that JWTs are “more modern” and therefore better. In reality, neither approach is universally superior. Many applications adopt tokens when a simple session would have worked perfectly well, inheriting extra complexity for no benefit. Choose based on your architecture and requirements, not trends.

Conclusion

Sessions and JWTs both answer the same question: how does the server know who is making this request? Sessions keep the memory on the server, while JWTs carry signed information with the client. Understanding the trade-offs puts you in a better position to design secure login systems. If you want to go deeper into backend development, explore the related programming and web development courses available on Cursa.

NTFS, exFAT, FAT32 and APFS: Choosing the Right File System for a Drive

Understand what a file system does and how NTFS, exFAT, FAT32, APFS and ext4 differ, so you can format drives without losing compatibility.

Text Encoding Explained: ASCII, Unicode and Why You Sometimes See Strange Symbols

Learn how computers store text, what ASCII and Unicode actually are, why UTF-8 became the standard, and how to fix files that display garbled characters.

Idempotency in APIs: Why Retrying a Request Should Be Safe

Learn what idempotency means in backend development, which HTTP methods provide it, and how idempotency keys prevent duplicate operations.

What Is a CDN? How Content Delivery Networks Make Websites Fast

Learn what a CDN is, how edge caching and cache headers work, what a cache hit means, and when a CDN helps — or does not.

Semantic Versioning Explained: What a Number Like 2.4.1 Actually Tells You

MAJOR.MINOR.PATCH is a promise, not decoration. Learn to read version numbers and understand dependency range symbols.

What Is a Virtual Machine? Virtualization Explained for Beginners

Learn what a virtual machine is, how hypervisors work, how VMs differ from containers, and when to use each one.

How HTTPS Works: Certificates, the TLS Handshake and What the Padlock Really Means

A beginner-friendly walkthrough of HTTPS: what TLS certificates prove, how the handshake works, and what the browser padlock does not guarantee.

Big O Notation Explained: How to Talk About Code Efficiency

A beginner-friendly guide to Big O notation: what it measures, the most common complexity classes, and how to reason about the cost of your code.