ObjectId, Date and Timestamp
Every document you insert without an _id gets an ObjectId, and every "when did this happen?" question needs a Date. They look alike in the shell, both mention time, and a third type called Timestamp muddies it further. One rule sorts them out.
The rule
ObjectId identifies, Date records when, Timestamp is MongoDB's own business.
ObjectId is a 12-byte value, shown as 24 hexadecimal characters:
ObjectId("6650a1f2c3b4d5e6f7a8b9c0")- The first 4 bytes are a timestamp in seconds, so
ObjectId(...).getTimestamp()returns when it was generated. - The next 5 bytes are random per process, and the last 3 bytes are a counter.
- It is unique in practice without asking the server, which is why drivers can create it themselves. Sorting by
_idgives roughly creation order, but only to the second.
Date is a signed 64-bit count of milliseconds since 1 January 1970, UTC. Use it for every application time: order placed, user joined, book released.
db.orders.insertOne({ bookId: 3, qty: 1, placedAt: new Date() })
db.orders.find({ placedAt: { $gte: ISODate("2025-01-01") } })mongosh shows Dates as ISODate("..."), always in UTC. Convert to local time in your app, not in the database.
Timestamp is a separate BSON type: 32 bits of seconds plus a 32-bit counter. MongoDB uses it internally, for example in the replication log. The official advice is not to use it in your own documents; use Date.
The shortcut
Ask "Am I naming a document or recording a moment?" Naming → ObjectId. Moment → Date. Timestamp → almost never.
Name it
No
_idsupplied, so MongoDB adds an ObjectId. It identifies the order.
The trap: placedAt: Date() without new. In JavaScript that returns a string, so the field is text, not a Date. Always write new Date() or ISODate(...).
Drills
Answer fast — trust the rule.
How many hexadecimal characters does an ObjectId show?
What do the first 4 bytes of an ObjectId hold?
Which is the right way to store when a customer joined?
In what time zone does MongoDB store Dates?
When should your application use the BSON Timestamp type?
Remember
- ObjectId identifies, Date records when, Timestamp is MongoDB's own business.
- Shortcut: naming a document → ObjectId; recording a moment →
new Date(). - Trap:
Date()withoutnewstores a string, not a date.
