App deployed to Vercel connects too many times to mongodb database

I have a NextJs app built with mongodb database.
I was surprised to see that I quickly almost reached the threshhold of maximum connections:
enter image description here
This app used to be built with node and react and this was never the case.
But the logic of connecting to the database has changed.
I have this function that connects to the database:

// lib/mongodb.ts
import mongoose from "mongoose";

// #TODO
// I tried putting this in types/global.d.ts
// But, I kept getting the mongoose global error
// So I brought it here
// Not sure if it makes sense to keep this here
declare global {
  var mongoose: {
    conn: any;
    promise: Promise<any> | null;
  };
}

const MONGODB_URI = process.env.MONGODB_URI;

if (!MONGODB_URI) {
  throw new Error("Please define the MONGODB_URI environment variable");
}

let cached = global.mongoose;

if (!cached) {
  // conn: The established connection
  // promise: Ongoing connection attempt
  /**
     * cached.promise: Prevents multiple concurrent connection attempts during the first request when the connection is not yet established.
       cached.conn: Efficiently returns the active connection after it has been established.
     */
  cached = global.mongoose = { conn: null, promise: null };
}

async function connectToDatabase() {
  /**
   * By storing the established connection in cached.conn, subsequent requests can
   * skip the connection process below entirely, leading to faster response times.
   */
  if (cached.conn) {
    return cached.conn;
  }

  /**
   * By checking cached.promise, we prevent redundant connection attempts.
   * If a connection attempt (promise) has already been made, we don't need to initiate
   * another one, we can reuse it, thus avoiding unnecessary load on the database.
   */
  if (!cached.promise) {
    /**
     * The connection promise is stored in cached.promise so that any subsequent requests made
     * before the connection resolves can await the same promise, preventing redundant connection
     *  attempts.
     */
    cached.promise = mongoose
      .connect(MONGODB_URI as string)
      .then((mongoose) => {
        return mongoose;
      })
      .catch((error) => {
        console.error("🚀 ~ Error connecting to MongoDB:", error);
        throw error; // Re-throw the error after logging
      });
  }

  try {
    cached.conn = await cached.promise;
  } catch (error) {
    throw error;
  }

  return cached.conn;
}

export default connectToDatabase;

And I call it with every query:

export async function GET(request: Request) {
  const searchParams = await request.json();
  await connectToDatabase();

  try {
    const results = await searchInstructors(searchParams);
    return NextResponse.json(results);
  } catch (error) {
    return NextResponse.json({ error: "Failed to fetch instructors" }, { status: 500 });
  }
}

Am I doing something wrong?

Hi @ahmedghribstranger, welcome to the Vercel Community!

Your code seems correct but I’d still recommend checking this code out for inspiration on how to implement singleton pattern for sharing the same instance: mongodb-starter/lib/mongodb.ts at main · vercel/mongodb-starter · GitHub

If that doesn’t solve your issue, I’d recommend to enable Fluid compute and set a higher function duration to ensure multiple requests are handled by same function.