API & Automation·7 min read·

Session vs Token Auth for Your Web API Endpoints

Compare server-side sessions with stateless tokens across scalability, revocation, and security to choose your web API authentication model today.

NB

Netbay Engineering

Netbay Engineering

On this page

Every web API needs an answer to one question: after the client authenticates, how does the server remember it on the next request? The two dominant answers are server-side **sessions** and client-held **tokens**. They look similar from the outside but differ sharply in scalability, revocation, and the failure modes you will debug at 2am.

Server-side sessions

In the session model, authentication writes a row (often in a database or cache) keyed by a random opaque session id. The server hands the client that id in a cookie or header, and on each request the server looks it up and reads the stored state.

  • **Revocation is instant.** Delete the row and the session dies immediately.
  • **Server memory is the cost.** Every active session consumes storage, and you need a shared store once you run more than one instance.
  • **Blast radius is small.** The session id is just an opaque pointer; leaking it leaks no claims.

The catch is that "server-side" is a lie the moment you scale. Two web frontends and a batch worker need to agree on where sessions live, which usually means Redis or Postgres. That is an extra moving part and a latency hop on every request.

Stateless tokens

Token auth flips the model: the client holds a signed object (typically a JWT) that the server verifies without any lookup. Verification is pure CPU and cryptographically cheap, so it scales horizontally with no shared store.

  • **Zero server state** means trivial horizontal scaling and no session cache to flush.
  • **Revocation is hard.** A valid signed token keeps working until it expires.
  • **Claims ride along.** Scopes, roles, and expiry are embedded, so microservices can trust the token directly.

The cost is that you trade a database problem for a revocation problem, and you must encrypt or trim any claim you do not want the world to see.

The two models also differ in an everyday user-facing act: logging out. With sessions, logout is a server call that deletes the row, and the behavior is immediate and authoritative. With tokens, logout is mostly theater unless you also consult a short-lived denylist to cancel already-issued signatures before they expire — and because clients may have hoarded multiple tokens, a true sign-out often has to invalidate a whole family. Plan for this distinction explicitly, because a token-based "logout" that only clears a browser cookie leaves every previously issued token alive until expiry.

Session Token state on server instant revoke shared store needed state in client easy scale-out revocation hard kill row, kill session best for tightly coupled stack short TTL + rotation best for many independent services

When each model wins

  1. Choose **sessions** when you need immediate logout, per-device control, and a small number of trusted replica instances with a shared store.
  2. Choose **tokens** when you have many independent services or heavy read traffic that must not hit a session store every request.
  3. A common compromise: sessions managed by an auth service that then issues short-lived signed tokens downstream.
  4. For browser SPAs, push tokens into HttpOnly cookies with 'SameSite' to keep them out of JavaScript's reach.

A session store, in Go

go
type Session struct {
    ID        string
    UserID    string
    ExpiresAt int64
}

func (s *SessionStore) Create(user string) error {
    session := Session{
        ID:     randomID(),
        UserID: user,
        ExpiresAt: time.Now().Add(30 * time.Minute).Unix(),
    }
    return s.redis.Set(ctx, "sess:"+session.ID, session, 30*time.Minute)
}

Stateless token check middleware

javascript
function requireAuth(req, res, next) {
  const h = req.headers.authorization || "";
  const token = h.replace(/^Bearer /, "");
  try {
    const claims = jwt.verify(token, process.env.PUBLIC_KEY, {
      algorithms: ["RS256"],
    });
    req.user = claims;
    next();
  } catch (err) {
    res.status(401).json({ error: "invalid token" });
  }
}

Takeaway

Sessions buy you instant revocation at the cost of server state; tokens buy you scale at the cost of control. Match the model to your deployment and your tolerance for a shared store. Either pattern is an easy first experiment on a single Netbay VPS at netbayhosts.in, where you can add replicas or services as the load grows.

Keep reading

Follow along on a real VPS

Deploy Linux in under 60 seconds

These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.

Deploy an instance