ObjectId Is More Interesting Than You Think

ObjectId Is More Interesting Than You Think

If you've worked with MongoDB for any amount of time you've almost certainly see an ObjectId ... most likely in the form of a document's _id (the unique, primary key of any MongoDB document).

---
{
  _id: ObjectId("6a69953ebc6b2fe7951da0fe"),
  title: "Learning MongoDB"
}

This funny looking thing that some developers just refer to as a "MongoDB ID" holds some extra information, and has some surprising uses.

Actually _id and ObjectId Aren't The Same Thing

While every MongoDB document must have a _id, the _id does not need to be a ObjectId ... it just needs to be unique in that collection. You could use plain strings, or numbers or UUID/GUID like values. For example both these are valid _id values.

---
{ _id: "learn-mongodb", title: "Learning MongoDB" }

{ _id: 42, title: "The Answer" }
ObjectId is simply the type that MongoDB drivers generate for _id when you don't provide one yourself.

That said, there are a number of reasons you might want to stick with the default.

What is a ObjectId From the Inside?

Take this ObjectID as an example 6a69953ebc6b2fe7951da0fe.

The ObjectId is a 12 bytes / 24 hexadecimal characters combination of essentially three things:

6a69953e (4 bytes)
Timestamp (based on the number of seconds since the Unix epoch)
bc6b2fe795 (5 bytes)
Random value
1da0fe (3 bytes)
Incrementing counter

By combining these three things there is no need to ask a central database server what the "next" id should be, so clients (drivers, etc) can generate these ids client side before sending anything to the database itself. That is much different then a traditional "auto-incrementing" integer IDs common with SQL databases where you need the database itself to add or provide that ID.

Some database systems have a concept of GUIDs or UUIDs, one small (pun intended) nicety of ObjectIds is they are smaller than those types of IDs, so they take up less space on disk.

The Built in Timestamp

One of the most useful things about this combination is we'll always have a timestamp with a date and time that document was created. You can easily extract it yourself:

---
const id = new ObjectId("6a69953ebc6b2fe7951da0fe");

id.getTimestamp();

// 2026-07-29T05:53:02.000Z

You can, in most cases use the _id to sort your documents by creation date, without needing a createdAt field for example.

---
db.posts.find().sort({ _id: -1 }).limit(5)

Then you have all your documents sorted by the date they were added!

The exactness of the timestamp is down to the second level however so if you need it down to the microsecond level you might still want to store a separate, larger Datetime.

So next time you see an _id with an ObjectId ... know there is a little more happening under the hood!