Why Your Next.js Proxy (ex-Middleware) is Slow - By Sourav Mishra (@souravvmishra)
Middleware is dead. Long live proxy.ts. Learn why database calls in your proxy file are creating bottlenecks.
Next.js has officially moved from middleware.ts to proxy.ts. While the name has changed to better reflect its role as a network boundary, the specific performance pitfalls remain the same.
In this guide, I, Sourav Mishra, Co-founder of Codestam Technologies, analyze the most common performance killers I see in production proxy.ts files.
The Edge Runtime Constraint
Middleware runs on the Edge, which means:
- No Node.js APIs: You can't use
fsor native modules. - Lightweight: It needs to be fast.
- Global: By default, it intercepts everything.
Anti-Pattern #1: Database Calls
❌ BAD: Connecting to a DB in proxy.ts.
// proxy.ts
import { db } from './lib/db'; // ⚠️ Don't do this
export async function proxy(req) { // Note the renamed export
const user = await db.user.find(req.cookies.get('session'));
if (!user) return Response.redirect('/login');
}
Why?: Establishing a TCP/SSL connection to a database adds 200ms+ to every single request. At Codestam, we saw a client's TTFB drop from 600ms to 120ms just by removing a single SQL query from their middleware.
✅ GOOD: Use Stateless Auth (JWT) or minimal Redis calls (via HTTP/REST, not TCP).
Anti-Pattern #2: Missing Matchers
❌ BAD: Running middleware on static assets.
// middleware.ts
// No config export
Why?: Your middleware is running on images, CSS files, and fonts.
✅ GOOD: Filter aggressively.
export const config = {
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};
Anti-Pattern #3: Blocking for Geolocation
Don't wait for external IP lookups. Use the geo object provided by Vercel/Next.js directly in the request.
// proxy.ts
export function proxy(req) {
const country = req.geo?.country || 'US';
// Immediate logic
}
Key Takeaways
- Rename to
proxy.ts: If you haven't yet, run the codemod. - Keep it logical:
proxyis for routing and basic auth validation. - Move data fetching: Do actual data checks in
layout.tsxor Server Components. - Use Matchers: Never let middleware run on static assets.
For optimizing your CSS delivery alongside this, check out Debugging Production CSS.
This guide was written by Sourav Mishra, Co-founder of Codestam Technologies and a Full Stack Engineer.