← Back to list

How to Set Up a Production-Ready Mongoose Connection in Next.js (TypeScript)

When building scalable applications with Next.js and MongoDB, one of the most common mistakes developers make is creating multiple database…

Ali · 2026-04-28 10:11 · 0 claps · 2.2 min read
#mongodb-conn #mongoose #mongodb #mongodb-atlas #connection-mongodb
Open on Medium ↗
Wiki topics: 🌐 · Web Development

How to Set Up a Production-Ready Mongoose Connection in Next.js (TypeScript)

When building scalable applications with Next.js and MongoDB, one of the most common mistakes developers make is creating multiple database connections.

This might work in development — but in production, it can quickly crash your app due to connection overload.

In this guide, you’ll learn how to create a production-ready Mongoose connection that is:

  • Efficient
  • Scalable
  • Safe for serverless environments (like Vercel)
  • Optimized for development & production

The Problem

In Next.js (especially with the App Router), your code can run multiple times due to:

  • Hot reload in development
  • Serverless function executions
  • Multiple API calls

If you do this:

mongoose.connect(MONGODB_URI);

A new connection is created every time Result: Too many connections → app crashes

The Solution: Connection Caching

We solve this by:

  • Reusing an existing connection if it exists
  • Storing the connection globally
  • Preventing duplicate connections

Production-Ready Setup

db.ts:

Here’s the full working implementation:

import mongoose from "mongoose";

const MONGODB_URI = process.env.MONGODB_URI;

if (!MONGODB_URI) {
  throw new Error("mongodb variables didnot find.");
}

declare global {
  var mongoose: {
    conn: mongoose.Mongoose | null;
    promise: Promise<mongoose.Mongoose> | null;
  };
}

let cached = global.mongoose;

if (!cached) {
  cached = global.mongoose = {
    conn: null,
    promise: null,
  };
}

export async function dbConnect() {
  console.log(" dbConnect called");
  // 1. If connection already exists → reuse it

  if (cached.conn) {
    console.log("♻️ Using cached connection");
    return cached.conn;
  }

  // 2. If no promise exists → create one
  if (!cached.promise) {
    console.log("⏳ Connecting to MongoDB...");
    cached.promise = mongoose.connect(MONGODB_URI as string).then((mongoose) => {
      return mongoose;
    });
  }

  try {
    // 3. Wait for connection
    cached.conn = await cached.promise;
    console.log("MongoDB connected");
  } catch (error) {
    // 4. Reset promise if failed
    cached.promise = null;
    throw error;
  }
  return cached.conn;
}

How This Works

Global Cache:

let cached = global.mongoose;
  • Stores connection across hot reloads
  • Prevents reconnecting every time in development

Reuse Existing Connection

if (cached.conn) return cached.conn;
  • If already connected → reuse it
  • Saves resources and improves performance

Store Connection Promise

if (!cached.promise) {
  cached.promise = mongoose.connect(...);
}
  • Prevents multiple simultaneous connections
  • Ensures only one connection attempt at a time

Error Handling

cached.promise = null;
  • If connection fails → reset promise
  • Allows retry on next request

Why This is Production-Ready

Handles Serverless Environments

  • Works perfectly with Vercel / AWS Lambda

Prevents Connection Explosion

  • Only one connection is reused

Optimized for Dev + Prod

  • Handles hot reload without reconnecting

Safe Async Handling

  • Uses promise caching to avoid race conditions

How to Use It

In your API route or server action:

import { dbConnect } from "@/lib/db";

export async function GET() {
  await dbConnect();
  // your DB logic here
}

Common Mistakes to Avoid

1- Calling mongoose.connect() in every API route. 2- Not caching connection globally. 3- Ignoring failed connections. 4- Using different connections for each request.

Pro Tips

  • Keep your DB logic separate from routes
  • Use environment variables for connection strings
  • Add logging only in development (avoid noisy production logs)

Final Thoughts

A proper database connection setup is critical for scalability.

With this pattern, you:

  • Avoid performance issues.
  • Prevent crashes.
  • Build a solid backend foundation.

메타데이터
post_id
4cfedfaeb50c
slug
how-to-set-up-a-production-ready-mongoose-connection-in-next-js-typescript-4cfedfaeb50c
url
https://medium.com/@aliairf92/how-to-set-up-a-production-ready-mongoose-connection-in-next-js-typescript-4cfedfaeb50c
canonical_url
https://medium.com/@aliairf92/how-to-set-up-a-production-ready-mongoose-connection-in-next-js-typescript-4cfedfaeb50c
author_url
https://medium.com/@aliairf92
status
ok
fetched_at
2026-06-23 17:05:31