MongoDB ObjectId Decoder
Paste any ObjectId to pull out the embedded timestamp, process random bytes, and counter. Or go the other
way: generate an ObjectId for a date so you can range-query on _id. Nothing leaves your browser.
ObjectId("…") call, or {"$oid":"…"}._id — e.g. find docs inserted after a specific date without a createdAt field.{ _id: { $gte: ObjectId(".../* your id */...") } }.How an ObjectId is built
Every ObjectId is exactly 12 bytes (24 hex characters), split into three fields.
Seconds since the Unix epoch (big-endian). Gives you coarse sort order and a free "created at" for every document.
Generated once per driver process. Its role is to keep ObjectIds from different machines from colliding even if their clocks tick in the same second.
Incrementing per-document counter within a process. Resolves collisions for bulk inserts in the same second from the same driver.
Why decode an ObjectId
Find when a document was created
The first 4 bytes are a Unix timestamp, so every document has an implicit creation time, even if the app never stored a createdAt field.
Range-query by time without a createdAt index
Generate an ObjectId for a date and query { _id: { $gte: ObjectId("…") } }. Uses the default _id index. No extra index needed.
Debug out-of-order writes
Two ObjectIds with the same timestamp but different counters came from the same process in the same second. Different random bytes point to different processes (or different drivers).
Sanity-check imports and migrations
Decoding an ObjectId tells you when the record was generated. Handy when you need to tell whether a batch of documents came from a recent import or from original ingestion.
Frequently asked questions
What is a MongoDB ObjectId?
ObjectId is the default value MongoDB assigns to the _id field of every document. It's a 12-byte, 24-character hex string that stays unique across a cluster without any central coordination.
What is inside an ObjectId?
Three parts. A 4-byte Unix timestamp (seconds since 1970-01-01 UTC), a 5-byte random value generated once per driver process, and a 3-byte incrementing counter initialized to a random value. Older drivers (before 3.4) encoded the 5 middle bytes as a 3-byte machine id plus a 2-byte process id, but the timestamp bytes are identical.
Can I trust the timestamp for auditing or sorting?
You can trust it for coarse time-sorting. The timestamp has 1-second resolution and comes from the machine that generated the ObjectId. Don't trust it for anything security-sensitive: clocks can be wrong, and ObjectIds are generated client-side by default. For strict ordering at the same second, the counter gives you a tiebreaker within a single process.
How do I find documents created after a specific date?
Generate an ObjectId from that date (the tool above does this) and use it in a range query: db.collection.find({ _id: { $gte: ObjectId("…") } }). Handy when a collection doesn't have an explicit createdAt field.
Does this send my ObjectId anywhere?
No. Parsing and rendering happen entirely in your browser. The ObjectId you paste never leaves your machine.
Is the generated ObjectId unique?
The timestamp bytes come from your chosen date. The remaining 8 bytes are cryptographically random (via crypto.getRandomValues). For practical purposes, collisions are infinitesimally unlikely, and MongoDB treats it as a valid ObjectId.
Work with MongoDB every day?
Monghoul is a fast desktop GUI with a schema-aware query editor, visual aggregation builder, a full explain-plan visualizer, and 70+ MCP tools. Free tier included.
Download Monghoul