State is the Enemy of Scale: Pragmatic Stateless Architecture
How pushing state exclusively to Postgres and Redis allowed us to scale horizontally with zero downtime.

What "Stateless" Actually Means
A stateless service does not store any persistent data about a client session in local memory. Every request is self-contained — the service reads state from an external source (a database, a cache), performs work, and returns a response. It does not remember the previous request.
This sounds obvious, but it's violated constantly in practice. Common violations include:
req.session in Express backed by MemoryStore)Why Statefulness Kills Horizontal Scale
Suppose you have 3 instances of a service and a user's session is stored in memory on Instance 1. If you route their next request to Instance 2, their session is gone. The two common "fixes" are sticky sessions or session replication — both are architectural debt that compounds over time.
Sticky sessions defeat the purpose of horizontal scaling. If one instance dies, every user pinned to it loses their session.
Session replication is expensive network overhead that grows quadratically with instance count.
The Pure Stateless Pattern
Push all state external. Full stop.
// ❌ Stateful: breaks horizontal scaling
const sessions = new Map<string, SessionData>();
app.get('/dashboard', (req, res) => {
const session = sessions.get(req.headers['session-id']);
if (!session) return res.status(401).send();
res.json(session.user);
});
// ✅ Stateless: any instance can handle any request
app.get('/dashboard', async (req, res) => {
const sessionId = req.headers['session-id'] as string;
const session = await redis.get(`session:${sessionId}`);
if (!session) return res.status(401).send();
res.json(JSON.parse(session).user);
});What We Put Where
| Data type | Storage | Why |
|---|---|---|
| Auth sessions | Redis (TTL) | Fast lookup, expiry is free |
| User/account data | PostgreSQL | ACID guarantees, long-lived |
| Computed aggregates | Redis | Expensive to recompute per-request |
| Messages, events | PostgreSQL + Kafka | Durable, replayable |
The Deployment Benefit
With fully stateless services, a deployment is trivial. Kubernetes can terminate old pods and start new ones in any order. Traffic shifts to new pods immediately. Zero downtime, zero session loss, zero user impact. We went from deployments requiring 2am maintenance windows to fully automated continuous delivery with 0 complaints.

