← Blog

Engineering · June 18, 2026

Scaling Nen: one box to a global fleet

The question we get most: "I don't run one server — I run a fleet behind a gateway. Does this even work?" Short answer: yes, with zero new code.It's the same stateless-app-tier + shared-store design you already run for every other stateful thing in your stack.

The one-sentence mental model

A Nen session is between the browser and a logical backend — a keypair plus a shared session store — not a specific server process. Once that lands, everything else falls out: scale the backend any way you like, and as long as every instance that handles a request can reach the same session store, any instance can serve any request in any session.

Where the keys live

The hybrid X25519 + ML-KEM handshake runs once, and both sides derive the encryption key (ChaCha20) and the auth key (HMAC) locally — under NEN-PROTOCOL-V3 nothing secret is transmitted. The server stores { encKey, macKey, usedNonces } under a sid in a pluggable SessionStore. Every later request carries X-Nen-Session: <sid> plus an HMAC signature; the server looks the session up by sid, verifies, and decrypts. The store is the entire scaling story.

InMemorySessionStore   → single instance only (dev). Pod A's session
                         is invisible to pod B → ISO-2002 on reroute.
RedisSessionStore      → any number of Node/serverless instances,
                         one shared Redis. Any pod sees any session.
UpstashSessionStore    → same, over REST — works in Edge runtimes
                         (Cloudflare Workers, Vercel Edge).

Point every instance at a shared Redis/Upstash store and the app tier stays stateless: no sticky sessions, an instance can be killed mid-session, and the next request lands on another instance and just works.

                       ┌────────── pod 1 ─┐
  Browser ─▶ CDN ─▶ LB ─┼────────── pod 2 ─┤──▶ Redis (shared sessions + nonces)
                       └────────── pod …12┘

Gateways, CDNs, and proxies in front

Nen ciphertext is opaque bytes, so caching layers and proxies pass it through fine. Three rules keep a gateway from breaking a session:

1. Don't rewrite the path. The per-request HMAC signs a canonical string that includes the pathname. If the gateway rewrites /api/x to /x, the signature won't verify (ISO-3002). 2. Pass the X-Nen-* headers through (session, nonce, timestamp, signature) — don't strip them. 3. Don't transform the body. Any recompression or re-encoding of the ciphertext fails the AEAD tag (ISO-4001) — which is exactly the integrity guarantee working as designed.

Multiple backends

A client handshakes per origin. If you split a monolith into services on different origins, each service that terminates a Nen session runs the handshake route and shares a store (its own, or a common one). Within one logical backend, all the replicas share onestore — that's the fleet case above.

Where multi-recipient fits (and where it doesn't)

One subtlety worth naming: N load-balanced replicas of your service are still one recipient — they share a single identity and key material. That scales horizontally with the shared store, today, no new code.

What's different is serving content to N independent organizations that each hold their own key— that's a multi-recipient envelope, a separate design we've deliberately deferreduntil a design partner needs it (it requires a key directory). Don't conflate the two: a big fleet is easy; many distinct key-holders is the harder, later problem.

Bottom line

A 1:1 Nen deployment scales like any stateless web service. The session store is the only shared state, and it's the same choice you already made for sessions, JWTs with a shared key, or any server-side state. No sticky sessions, no special routing — point the fleet at one store and grow.

Read the protocol spec for the wire detail, or the architecture guide for the session-store internals.