MongoDB
import { Render, PackageManagers, Tabs, TabItem, TypeScriptExample, WranglerConfig, } from "~/components";
MongoDB is a document-oriented database. You can run MongoDB yourself, use MongoDB Atlas (a fully managed cloud service), or use any other MongoDB-compatible host.
:::note
Hyperdrive does not support MongoDB. Hyperdrive only supports PostgreSQL and MySQL wire protocols. To reduce connection latency, use a Durable Object to persist connections between requests, as shown below.
:::
Use this approach for low-traffic use cases where a ~300 ms connection overhead per request is acceptable. Each Worker invocation creates a new TCP and TLS connection to your MongoDB cluster.
Set up a direct connection
To connect to MongoDB directly from a Worker:
-
You need an existing MongoDB cluster and connection string. If you do not have one, create an Atlas cluster and copy your connection string from the Atlas console.
-
Enable Node.js compatibility for your Worker:
-
Install the MongoDB Node.js driver:
-
Add your MongoDB connection string as a secret to your Worker:
npx wrangler secret put MONGODB_URI # When prompted, paste your MongoDB connection string -
The following example shows how to query a MongoDB database from a Worker:
```ts import { MongoClient } from "mongodb";export interface Env { MONGODB_URI: string; }
export default { async fetch(request, env, ctx): Promise { const client = new MongoClient(env.MONGODB_URI); await client.connect();
const movie = await client .db("sample_mflix") .collection("movies") .findOne( { title: "The Room" }, { projection: { _id: 0, title: 1, imdb: 1 } }, ); return Response.json({ movie });}, } satisfies ExportedHandler;
</TypeScriptExample> The MongoDB driver uses the `node:net` and `node:tls` modules, which are available in Workers when `nodejs_compat` is enabled with a compatibility date of `2025-03-20` or later. -
Deploy your Worker:
npx wrangler deploy
Use this approach for latency-sensitive applications. Workers cannot reuse I/O objects across requests, so connection pooling does not work in a plain Worker. Placing the MongoClient inside a Durable Object persists the connection between requests, reducing query latency from ~300 ms to ~35 ms on warm requests.
Set up a connection using a Durable Object
To connect to MongoDB using a Durable Object:
-
You need an existing MongoDB cluster and connection string. If you do not have one, create an Atlas cluster and copy your connection string from the Atlas console.
-
Enable Node.js compatibility for your Worker:
-
Install the MongoDB Node.js driver:
-
Add your MongoDB connection string as a secret to your Worker:
npx wrangler secret put MONGODB_URI # When prompted, paste your MongoDB connection string -
Create a Durable Object class that holds the
```ts title="src/MongoDBConnection.ts" import { DurableObject, DurableObjectState } from "cloudflare:workers"; import { MongoClient } from "mongodb";MongoClientinstance:interface Env { MONGODB_URI: string; }
export class MongoDBConnection extends DurableObject { private client: MongoClient;
constructor(state: DurableObjectState, env: Env) { super(state, env); this.client = new MongoClient(env.MONGODB_URI, { maxPoolSize: 1, minPoolSize: 0, serverSelectionTimeoutMS: 5000, maxIdleTimeMS: 20_000, }); }
async getMovie() { const start = Date.now(); await this.client.connect(); const movie = await this.client .db("sample_mflix") .collection("movies") .findOne( { title: "The Room" }, { projection: { _id: 0, title: 1, imdb: 1 } }, ); return { movie, queryTime: Date.now() - start }; } }
</TypeScriptExample> Creating the `MongoClient` in the constructor and calling `connect()` in the request handler allows the Durable Object to reuse an existing connection across requests. -
Update your Worker entry point to route requests to the Durable Object:
import { MongoDBConnection } from "./MongoDBConnection"; interface Env { MONGODB_URI: string; MONGODB_CONNECTION: DurableObjectNamespace<MongoDBConnection>; } export default { async fetch(request: Request, env: Env): Promise<Response> { const id = env.MONGODB_CONNECTION.idFromName("mongodb-connection"); const stub = env.MONGODB_CONNECTION.get(id, { locationHint: "enam" }); const result = await stub.getMovie(); return Response.json(result); }, } satisfies ExportedHandler<Env>; export { MongoDBConnection };Use the
locationHintoption to place the Durable Object close to your MongoDB cluster. Available hints includewnam,enam,sam,weur,eeur,apac,oc,afr, andme. Match the hint to the region of your MongoDB cluster. -
Configure the Durable Object binding and migration in your Wrangler file:
name = "workers-mongodb-demo" main = "src/index.ts" compatibility_date = "$today" compatibility_flags = ["nodejs_compat"] [[durable_objects.bindings]] name = "MONGODB_CONNECTION" class_name = "MongoDBConnection" [[migrations]] tag = "v1" new_classes = ["MongoDBConnection"] -
Deploy your Worker:
npx wrangler deploy
Durable Object lifecycle considerations
- The Durable Object evicts after roughly 70–140 seconds of no incoming requests. The next request pays the cold start cost again.
- TCP connections do not survive hibernation.
- You cannot pass
MongoClient,Db, orCollectionobjects back to the calling Worker via RPC. Run all database logic inside the Durable Object. - A single Durable Object instance has a soft limit of roughly 1,000 requests per second.
Use Mongoose
Mongoose version 9 and later works on Workers with Node.js compatibility enabled. Earlier versions loaded the browser bundle instead of the Node.js entry point and required a manual patch to the package.json exports map. This is no longer necessary.
The following example shows a Mongoose Durable Object:
import { DurableObject } from "cloudflare:workers";
import mongoose, { Schema, Model } from "mongoose";
interface Env {
MONGODB_URI: string;
}
const movieSchema = new Schema({
title: String,
imdb: { rating: Number, votes: Number, id: Number },
});
export class MongoDBConnection extends DurableObject<Env> {
private Movie: Model<any>;
constructor(state: DurableObjectState, env: Env) {
super(state, env);
this.Movie = mongoose.model("Movie", movieSchema, "movies");
}
async getMovie() {
if (mongoose.connection.readyState === 0) {
await mongoose.connect(this.env.MONGODB_URI, { dbName: "sample_mflix" });
}
return this.Movie.findOne(
{ title: "The Room" },
{ _id: 0, title: 1, imdb: 1 },
).lean();
}
}
Next steps
- Learn more about Durable Objects.
- Review the MongoDB Node.js driver documentation.
- Explore other storage options for Workers.
谢谢你的反馈!