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.

BySourav Mishra2 min read

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:

  1. No Node.js APIs: You can't use fs or native modules.
  2. Lightweight: It needs to be fast.
  3. 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: proxy is for routing and basic auth validation.
  • Move data fetching: Do actual data checks in layout.tsx or 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.

Share this post

Cover image for Why Your Next.js Proxy (ex-Middleware) is Slow

You might also like

See all