MongoDB Fundamentals
How Node.js Connects to MongoDB
Connection strings, one MongoClient, the pool, and why a new client per request is a bug.
The driver lesson showed new MongoClient and findOne. This lesson is the connection itself: where the URI lives, what the client reuses, and the bug that shows up in every first Express app.
- 01Node.js application
- 02MongoDB driver
- 03MongoClient (one per process)
- 04Connection pool
- 05MongoDB server
The connection string
MONGO_URI=mongodb://localhost:27017/appmongodb:// is the protocol. localhost:27017 is host and default port. /app is the default database name. Atlas URIs look like mongodb+srv://cluster... and include credentials. Same MongoClient, different string. Read it from process.env.MONGO_URI. Never commit a password in source.
One client, a pool behind it
MongoClient opens a pool of sockets, not a single connection. Each query borrows a socket, uses it, gives it back. Creating a client is the expensive part (handshake, auth, pool setup). Running findOne on an existing client is cheap.
import { MongoClient } from "mongodb";
const uri = process.env.MONGO_URI;
if (!uri) throw new Error("MONGO_URI is not set");
const client = new MongoClient(uri);
await client.connect();
const users = client.db("app").collection("users");
// In a route handler — no new MongoClient here:
export async function getUser(email) {
return users.findOne({ email });
}app.get("/users/:email", async (req, res) => {
const client = new MongoClient(process.env.MONGO_URI);
await client.connect();
const user = await client.db("app").collection("users")
.findOne({ email: req.params.email });
await client.close();
res.json(user);
});The second snippet works on a laptop and falls over in production: handshake per request, pool created and destroyed, latency spikes, connection limits hit on the server. In a long-running Node process, create one client at startup. In serverless, cache the client on the module so warm invocations reuse it — the Next.js lesson later shows that pattern.
Interview question
Why shouldn't you create a new MongoDB connection for every API request?
MongoClient already maintains a connection pool. Connecting is the expensive handshake. A new client per request wastes that work, adds latency, and can exhaust the server's connection limit. Create one client and reuse it.
Interview question
Where should a MongoDB connection string live in a Node.js app?
In an environment variable, for example MONGO_URI. Not in source control. The app reads process.env, constructs one MongoClient, and reuses it.