Session

Concept

The state a server keeps between requests so it still knows who a logged-in person is, instead of asking again on every screen.

Why it exists

The protocol the web runs on has no memory. When a request finishes, the server forgets who just did what. That forgetfulness is part of how one server handles enormous numbers of people at once, but it turned into a problem the moment a site was more than one page.

On early sites the trouble looked like this. You typed a username and password, moved to the next page, and were a stranger again. You put something in a cart, went to the next screen, and the cart was empty. Sites answered by putting a login box on every page, or by trailing an account identifier on the end of the address. The second option was worse: copy the address to a colleague and the colleague arrived inside your account, and the value sat in browser history and server logs for anyone to find later.

The core of it was that authentication, the act of confirming who someone is, only needs to happen once, and there was nowhere to carry the result forward. A session is that place, built on the server side. The server holds the information about the person it already checked, and the browser gets nothing but a key to it.

How it works

The server creates one record and hands the browser only a pointer to it. Five steps.

  1. When a login succeeds, the server builds a record for this person — who they are, what they're allowed to do, when they arrived.
  2. It tags that record with a random string nobody could guess. That string is the session ID.
  3. Only the ID goes back in the response, carried in a cookie: a small value the browser stores and attaches to later requests on its own.
  4. Every request after that arrives with the cookie, and the server looks up the record by ID to see who is calling.
  5. After a set period of inactivity, or when someone logs out, the server throws the record away. From that instant the same ID retrieves nothing. Most setups push the expiry time forward on every request, so the window measures idleness rather than total time since login.

Sending the ID rather than the record is the whole trick. Anything sitting in the browser can be opened and edited by the person holding it. Put "plan: free" in the browser and someone will eventually try typing "paid" over it. An ID means nothing on its own, so editing it just points at a record that doesn't exist.

That leaves the question of where the record lives. The easiest place is the server's own memory, and with one server it works fine. Two servers break it. Behind a load balancer, which spreads requests across machines, the same person's next request can land on a different server that has no record of them and treats them as a stranger. Deployments do the same damage: replace the server with new code and its memory empties, so everyone connected falls out. The fix is to keep records in shared storage outside the servers, where every server reads the same thing and it stops mattering which one answers. A database can hold them, but because sessions get read and written constantly, teams usually reach for storage that keeps data in memory for fast lookups.

Where it shows up

Staying logged in is the common case, and sessions turn up anywhere one request needs to know about the last one.

  • Login state. Someone checked once stays recognized.
  • Authorization, the check on what a caller is allowed to do. Roles and team membership sit in the record, so an admin-only screen doesn't mean another database lookup on every request.
  • Work done before signing in. Items dropped in a cart, a half-filled form. A session gets created for people without accounts too.
  • Flows split across steps. Checkout runs over three or four screens, and the later ones need the choices made on the earlier ones without passing them all through the address bar.

Some uses come from the record living on the server specifically. Delete the record and the person is cut off where they stand. Pagedeck relies on this when a contact at a business customer leaves the company: deactivating the account and clearing that person's sessions at the same time means the tab still open on their office machine hits a login screen on the next click. The JSON Web Token (JWT) approach, which hands the browser a signed value instead, can't do that directly. The server keeps no record, so it has nothing to revoke, and an issued token keeps working until it expires.

How it sounds at work

"I keep getting logged out. Is it because the session is 30 minutes?"

Asking whether the inactivity window after which the server discards the record is set too short.

"Everyone got logged out after the deploy. The sessions live in server memory."

Records are held inside the server, so every restart drops everyone connected.

"When you process an account deletion, clear the sessions too."

Blocking the account while leaving records behind means already-open screens keep working for a while.

Pagedeck ran into exactly this. Theo pushed a deploy over lunch, everyone connected at that moment was logged out, and Sofia got a wave of tickets about unsaved documents. The cause was session records held in server memory. Nobody noticed while there was one server, and it surfaced once deploys got frequent. After the records moved to shared storage outside the servers, deploys and login state stopped having anything to do with each other.

What people get wrong

Many people use "session" and "cookie" as the same word. The two always travel together and sit side by side in developer tools, so the confusion is easy. But a cookie is the vehicle carrying the key, and the session is the record on the server. The key can travel another way, and cookies can hold values that have nothing to do with sessions. Treating them as one thing leaves you with nowhere to look when something breaks, because a cookie that isn't being sent and a record that has already been discarded are fixed in completely different places.

The other one is believing a session ends when the browser closes. Closing the browser can discard the key in the cookie, depending on how that cookie was configured, and that's all it discards. The record on the server stays until its own expiry time. Walk away from a shared computer after closing the window and the record is still alive; logging out is what makes the server throw it away.

Easily confused with

TermWhat the server holdsHow it differs from a session
StatelessNothing at allEach request carries everything needed to serve it. Adding or restarting servers gets easy, but taking back something already issued gets hard

Where to go next

  • Backend

    see where sessions sit among the other pieces running on the server side

  • Stateless

    the opposite design, which makes clear what a session trades away and what it buys

Last updated 2026-09-16