MongoServerSelectionError on Vercel: Atlas Connection Fix
MongoServerSelectionError or 'connection timed out' on serverless? Fix Atlas IP allowlists, client caching, pool size, and DNS so MongoDB connects reliably from Vercel.
MongoServerSelectionError means the MongoDB driver could not find a reachable server within serverSelectionTimeoutMS (30 seconds by default); on serverless platforms it is usually an Atlas IP allowlist problem, a new client being created on every invocation, or a bad connection string.
Typical messages:
MongoServerSelectionError: connection <monitor> to 52.x.x.x:27017 timed out
MongooseServerSelectionError: Could not connect to any servers in your MongoDB Atlas cluster.
One common reason is that you're trying to access the database from an IP that isn't whitelisted.
Cause 1: Atlas Network Access Blocks Your Host
Serverless functions run from changing IP addresses, so a fixed allowlist rarely works. Your options:
| Option | Trade-off |
|---|---|
Allow 0.0.0.0/0 |
Simple, but the database is reachable from anywhere. Requires strong credentials, TLS, and least-privilege users |
| Private networking or VPC peering | Safest, needs a plan and host that support it |
| Static outbound IP add-on from your host | Allowlist a stable IP, check availability for your plan |
If you use 0.0.0.0/0, rotate passwords, never reuse admin credentials in the app, and restrict the database user to the single database it needs.
Cause 2: A New Client on Every Invocation
Creating new MongoClient() inside the handler opens a fresh pool per call. Under load you exhaust Atlas connection limits, and cold starts pay the handshake cost every time. Cache the client at module scope:
// lib/mongo.ts
import { MongoClient } from 'mongodb'
const uri = process.env.MONGODB_URI!
const globalForMongo = globalThis as unknown as { _mongo?: Promise<MongoClient> }
export const clientPromise =
globalForMongo._mongo ??
(globalForMongo._mongo = new MongoClient(uri, {
maxPoolSize: 5,
serverSelectionTimeoutMS: 5000,
}).connect())
Caching on globalThis also stops hot reload in development from creating a new connection on every file save. Reduce maxPoolSize for serverless: ten concurrent function instances times a pool of 100 is a quick way to hit your cluster's limit. This is the same mechanism described in connection pool exhaustion.
Cause 3: Fail Fast Instead of Hanging
A 30-second selection timeout is longer than most function limits, so the platform returns a 504 first. Set serverSelectionTimeoutMS to 5000 and handle the failure; see Vercel function timeouts.
Cause 4: Connection String Problems
| Symptom | Fix |
|---|---|
querySrv ENOTFOUND or ECONNREFUSED on mongodb+srv:// |
DNS SRV lookup failed; check the hostname, try the standard mongodb:// string from Atlas |
bad auth / Authentication failed |
Wrong user, wrong authSource, or special characters in the password not URL-encoded |
| Works locally, fails in production | Env var missing in production; see env vars undefined |
URL-encode special characters in passwords with encodeURIComponent. An unencoded @ or / silently breaks the string.
Cause 5: Cluster Paused or Under Maintenance
Free-tier Atlas clusters pause after inactivity. Check the Atlas dashboard before debugging code.
Handle the Error Without Crashing
try {
const db = (await clientPromise).db('app')
return await db.collection('orders').find({ userId }).toArray()
} catch (e: any) {
if (e?.name === 'MongoServerSelectionError') {
logger.error({ err: e }, 'mongo unreachable')
return Response.json({ error: 'Service temporarily unavailable' }, { status: 503 })
}
throw e
}
Return a 503, not a 500, so clients and monitors know the failure is temporary. Add a single retry with backoff for cold-start failures. If you also use Redis, similar serverless connection rules apply: Redis Upstash errors.
Let Relia Find Database Outages Fast
Relia watches production continuously. When database errors start piling up, it writes the incident up in plain words: what happened, why it thinks so (with a confidence level), and one thing to do next. On request it writes a fix plan, such as client caching and timeout settings, with a "Copy for your AI assistant" button; Relia doesn't change code itself, and after you ship it checks the fix against live traffic.
FAQ
What does MongoServerSelectionError mean?
The driver tried every server for serverSelectionTimeoutMS and could not connect to any.
Why does MongoDB connect locally but not on Vercel?
Your home IP is allowlisted in Atlas; Vercel's changing IPs are not.
How big should the pool be on serverless?
Small, often 1 to 5 per instance, because many instances run in parallel.