MongoDB โ The _id Field & ObjectId Mechanics
Explore the 12-byte binary structure of MongoDB ObjectIds, extract creation timestamps, and learn when to use custom _id values vs auto-generated ObjectIds.
In MongoDB, every document stored in a collection MUST contain a unique _id field that acts as its primary key. If you insert a document without an _id field, MongoDB automatically generates a 12-byte ObjectId for you.
An ObjectId (e.g. 65d8f1e2a9b3c4d5e6f7a8b9) is represented as a 24-character hexadecimal string, but internally it consists of 12 raw binary bytes divided into three parts:
4 Bytes: Unix Timestamp (seconds since epoch)
+ 5 Bytes: Random Value (unique per process/machine)
+ 3 Bytes: Incrementing Counter (initialized to random value)
-----------------------------------------------------------
= 12 Bytes total globally unique ID!
Because the first 4 bytes of an ObjectId encode a Unix timestamp, you can extract the exact document creation time without storing a separate createdAt field!
// Extract creation time from an ObjectId
const id = ObjectId("65d8f1e2a9b3c4d5e6f7a8b9");
console.log(id.getTimestamp());
// Output: 2024-02-23T19:30:10.000Z
You can supply custom _id values (e.g., strings, integers, UUIDs) when inserting documents:
// Custom string _id (e.g. SKU or Email)
db.products.insertOne({ _id: "SKU-9921", title: "Wireless Mouse", price: 29.99 });
// Custom integer _id
db.categories.insertOne({ _id: 101, name: "Electronics" });