dev3 ·
In development I see 'MongoServerError: too many connections' and warnings about many listeners. I call mongoose.connect() inside my route handlers. What is the right pattern for Next.js hot reload and serverless?
0
DEV3 Developer Forum
Every post is reviewed first. Usually reviewed within 24 hours.
In development I see 'MongoServerError: too many connections' and warnings about many listeners. I call mongoose.connect() inside my route handlers. What is the right pattern for Next.js hot reload and serverless?
Module reloads in dev and separate serverless instances each re-run your connect code. Cache the connection promise on globalThis so it survives hot reload.
// lib/mongoose.ts
import mongoose from "mongoose";
const uri = process.env.MONGODB_URI;
if (!uri) throw new Error("MONGODB_URI is not set");
type Cache = { conn: typeof mongoose | null; promise: Promise<typeof mongoose> | null };
const g = globalThis as unknown as { _mongoose?: Cache };
const cache: Cache = (g._mongoose ??= { conn: null, promise: null });
export async function connectDB() {
if (cache.conn) return cache.conn;
cache.promise ??= mongoose.connect(uri!, {
bufferCommands: false,
maxPoolSize: 10,
});
try {
cache.conn = await cache.promise;
} catch (e) {
cache.promise = null; // allow retry
throw e;
}
return cache.conn;
}
Use it:
import { connectDB } from "@/lib/mongoose";
import { User } from "@/models/User";
export async function GET() {
await connectDB();
return Response.json(await User.find().lean());
}
Hot reload also causes OverwriteModelError. Guard it:
export const User = mongoose.models.User || mongoose.model("User", schema);
maxPoolSize small (5 to 10) because every concurrent function instance opens its own pool.mongodb driver, the same idea applies: cache the MongoClient promise on globalThis in development.Pitfall: calling mongoose.connect at module top level without caching still works in production but causes the duplicate connections in dev.