UUID in MongoDB — UUID vs ObjectId Explained
- MongoDB defaults to ObjectId for _id — a 12-byte time-ordered identifier, not a UUID.
- You can use UUID as the _id field, but it must be stored as Binary (BSON type) for efficiency.
- UUID v4 stored as a string (VARCHAR-style) in MongoDB wastes space vs Binary UUID — 36 bytes vs 16 bytes.
- Use UUID when you need to share IDs with other systems that use UUID; use ObjectId when MongoDB-only.
- Mongoose supports UUID _id with a custom schema type or via the uuid package.
Table of Contents
MongoDB uses ObjectId as its default _id type — a 12-byte binary value that encodes a timestamp, machine ID, process ID, and counter. It is not a UUID. This guide explains when to use UUID instead of ObjectId, how to store it efficiently, and the trade-offs.
ObjectId vs UUID — The Key Differences
| Property | ObjectId | UUID v4 |
|---|---|---|
| Size | 12 bytes | 16 bytes (binary) / 36 bytes (string) |
| Time-ordered | Yes (4-byte timestamp) | No (v4 is random); Yes (v7) |
| Cross-system compatible | MongoDB-specific | Universal standard |
| Human-readable format | 24-char hex string | 36-char hyphenated string |
| Generated by | MongoDB driver | Application or database |
| RFC standard | No | RFC 4122 |
Use ObjectId when: MongoDB is your only database, you do not share IDs with external systems, and you want automatic time-ordering of documents.
Use UUID when: You share IDs between MongoDB and a SQL database, a REST API, or another service that uses UUID; or when you need RFC 4122 compliance for integration reasons.
Store UUID as BSON Binary — Not as a String
// BAD — storing UUID as a string wastes 36 bytes vs 16:
db.orders.insertOne({
_id: "550e8400-e29b-41d4-a716-446655440000", // string, 36 bytes
status: "pending"
});
// GOOD — store as BSON Binary UUID (16 bytes):
const { Binary, UUID: MongoUUID } = require('mongodb');
const id = new MongoUUID(); // generates UUID v4 as BSON Binary
db.orders.insertOne({
_id: id,
status: "pending"
});
// Or from a UUID string:
const id = new MongoUUID("550e8400-e29b-41d4-a716-446655440000");
db.orders.insertOne({ _id: id, status: "pending" });
// Query by UUID:
const result = await db.orders.findOne({
_id: new MongoUUID("550e8400-e29b-41d4-a716-446655440000")
});
BSON Binary subtype 3 or 4 is the standard for UUID storage in MongoDB. The Node.js MongoDB driver's UUID class handles the conversion automatically.
UUID in the Node.js MongoDB Driver
import { MongoClient, UUID } from 'mongodb';
const client = new MongoClient(process.env.MONGO_URI);
const db = client.db('myapp');
const orders = db.collection('orders');
// Insert with UUID _id:
const id = new UUID(); // generates v4 UUID
await orders.insertOne({
_id: id,
status: 'pending',
createdAt: new Date(),
});
// Query by UUID from a string:
const order = await orders.findOne({
_id: new UUID('550e8400-e29b-41d4-a716-446655440000')
});
// Return UUID as string in API responses:
console.log(order._id.toString()); // "550e8400-e29b-41d4-a716-446655440000"
// Configure driver to return UUID as string automatically:
const client = new MongoClient(uri, {
pkFactory: { createPk: () => new UUID() }
});
UUID in Mongoose — Schema and Model Setup
import mongoose from 'mongoose';
import { UUID } from 'mongodb';
// Option 1: UUID _id with mongoose-uuid-parse (package):
// npm install mongoose-uuid-parse
const mongooseUUID = require('mongoose-uuid-parse');
mongooseUUID(mongoose);
const OrderSchema = new mongoose.Schema({
_id: { type: 'UUID', default: () => new UUID() },
status: String,
}, { _id: false });
// Option 2: Use String type and generate UUID v4 manually:
import crypto from 'crypto';
const OrderSchema = new mongoose.Schema({
_id: { type: String, default: () => crypto.randomUUID() },
status: String,
}, { _id: false });
const Order = mongoose.model('Order', OrderSchema);
// Create:
const order = new Order({ status: 'pending' });
await order.save();
console.log(order._id); // "550e8400-e29b-41d4-a716-446655440000"
Storing UUID as a String in Mongoose is simpler to set up but uses 36 bytes. For high-volume collections, use Binary UUID via the mongodb driver directly or a UUID-aware Mongoose plugin.
UUID in PyMongo
from pymongo import MongoClient
from bson.binary import Binary, UuidRepresentation
from bson.codec_options import CodecOptions
import uuid
# Configure codec to handle Python UUIDs as BSON Binary subtype 4:
codec_opts = CodecOptions(uuid_representation=UuidRepresentation.STANDARD)
client = MongoClient("mongodb://localhost:27017")
db = client.get_database("myapp", codec_options=codec_opts)
orders = db.get_collection("orders", codec_options=codec_opts)
# Insert with UUID _id:
new_id = uuid.uuid4()
orders.insert_one({"_id": new_id, "status": "pending"})
# Query:
result = orders.find_one({"_id": uuid.UUID("550e8400-e29b-41d4-a716-446655440000")})
print(result["_id"]) # UUID('550e8400-e29b-41d4-a716-446655440000')
The UuidRepresentation.STANDARD codec option ensures Python's uuid.UUID objects are stored as BSON Binary subtype 4 — the standard representation. Without this option, PyMongo uses legacy subtype 3.
Generate UUIDs for MongoDB Testing
Get 1 or 10 RFC-compliant UUID v4 values from the Cheetah UUID Generator — paste into MongoDB shell commands, seed scripts, or API test bodies.
Open Free UUID GeneratorFrequently Asked Questions
Should I use UUID or ObjectId in MongoDB?
ObjectId for MongoDB-only systems — it is smaller (12 bytes vs 16), time-ordered by default, and requires no configuration. UUID when you share IDs with other systems (REST APIs, SQL databases, external services) that use UUID as the standard identifier format.
Can I store UUID as a string in MongoDB?
Yes, but it wastes space (36 bytes vs 16 bytes as Binary) and is slower to index. For small collections this does not matter. For collections with millions of documents, use BSON Binary UUID.
How do I query a UUID _id in MongoDB?
Create a UUID object from the string using your driver's UUID class. In Node.js: new UUID("550e8400-..."). In Python: uuid.UUID("550e8400-..."). Do not pass the raw string — it will not match a Binary UUID field.
Does MongoDB generate UUID _id automatically?
No. MongoDB generates ObjectId by default. To use UUID automatically, configure a pkFactory in the driver options: { pkFactory: { createPk: () => new UUID() } } in Node.js.
Is UUID v7 better than UUID v4 in MongoDB?
Yes, if you need time-ordered documents. UUID v7 inserts sequentially into MongoDB indexes (like ObjectId) while still being a standard UUID. UUID v4 inserts randomly. For MongoDB specifically, ObjectId is already time-ordered and smaller — UUID v7 is only worth it if you need UUID format compatibility.

