Middleware Performance: Using JWT Sessions to Eliminate DB Round-Trips
Middleware Performance: Using JWT Sessions to Eliminate DB Round-Trips
Release: v0.1.82 · Tracking: PERF-13
Background
The sanctions screening platform protects routes using NextAuth's auth() helper, called inside src/middleware.ts on every non-public request. This is correct and necessary — unauthenticated users must never reach protected compliance data.
However, the way NextAuth resolves a session in middleware has a significant performance implication depending on the configured session strategy.
The Problem
When NextAuth is configured with database sessions (strategy: 'database'), the Drizzle adapter must perform a database lookup on every call to auth(). Because middleware.ts runs on every non-public request — including page navigations, prefetches, and API calls — this means:
- Every page load for an authenticated user hits the database at least once before the page handler runs.
- Under moderate traffic, this compounds into a significant volume of session-lookup queries.
- Edge middleware has strict CPU and latency budgets; a synchronous DB call is particularly costly in this environment.
The Recommended Fix
Switch NextAuth to JWT sessions. With JWT, the session is encoded in a signed, encrypted cookie that is verified locally in the Edge runtime — no database call is required.
// src/auth.ts (or wherever NextAuth is configured)
export const { handlers, auth, signIn, signOut } = NextAuth({
// ...providers, adapter, etc.
session: {
strategy: 'jwt', // ✅ stateless — no DB round-trip in middleware
},
});
With this change, auth() in middleware reads and verifies the JWT cookie locally, and the Drizzle adapter is only consulted during sign-in and explicit session refresh operations.
If Database Sessions Are Required
Some deployments require database sessions — for example, to support immediate session revocation. In that case, consider introducing an Edge-compatible session cache:
- Upstash Redis — A serverless Redis offering with an HTTP-based client (
@upstash/redis) that works in the Edge runtime. - Cache the session record keyed by session token with a short TTL (e.g. 60 seconds).
- Fall back to the Drizzle DB lookup on a cache miss.
This approach retains revocation capability while dramatically reducing average-case DB load.
Affected File
| File | Role |
|---|---|
src/middleware.ts | NextAuth auth() called on every protected request |
Summary
| Strategy | DB call in middleware? | Supports instant revocation? | Edge-compatible? |
|---|---|---|---|
database (current) | ✅ Yes — every request | ✅ Yes | ⚠️ Costly |
jwt (recommended) | ❌ No | ⚠️ Delayed (until JWT expiry) | ✅ Yes |
database + Edge cache | ❌ Usually not | ✅ Yes (within TTL) | ✅ Yes |
For a compliance platform where session security is critical, JWT sessions with a short expiry (e.g. 15–30 minutes) combined with refresh token rotation is the recommended approach.