1001Ferramentas
๐Ÿ†”Validators

Generic ObjectId Validator

Validate generic ObjectId formats used in NoSQL DBs: MongoDB (24 hex), Couchbase (UUID), Cassandra (TimeUUID).

โ€”

MongoDB ObjectId: the 12-byte, time-sortable BSON identifier behind every _id

ObjectId is the default primary key type for documents in MongoDB. Defined by the BSON specification, it is a 12-byte (96-bit) value rendered as a 24-character hexadecimal string. A canonical example is 507f191e810c19729de860ea โ€” every MongoDB document gets one assigned automatically to its _id field unless you override it.

The 12 bytes are structured into three meaningful segments, giving ObjectId its distinctive properties: roughly time-sortable, generatable on any client without coordination, and compact enough to use as a URL slug when discretion is not a concern.

Anatomy of an ObjectId โ€” 12 bytes, 3 fields

  • 4 bytes โ€” timestamp: seconds since the Unix epoch (so the granularity is seconds, not milliseconds).
  • 5 bytes โ€” random per-process value: generated once per process at startup and reused for every ObjectId created by that process.
  • 3 bytes โ€” incrementing counter: starts at a random value and increments for each new ObjectId within the process.

Before the 2018 spec revision, the middle segment was a 3-byte machine identifier + 2-byte process ID. That was replaced because the PID and machine fingerprint leaked operational information about the deploy topology. The current 5-byte random value retains time-sortability while removing the leak.

Sortability and timestamp extraction

Because the timestamp lives in the high-order bytes, ObjectIds sort lexicographically in approximate chronological order. This makes "list newest first" queries cheap even when you index only on _id. The MongoDB driver exposes new ObjectId(str).getTimestamp(), which returns a JavaScript Date built from the first 4 bytes:

const id = new ObjectId('507f191e810c19729de860ea');
id.getTimestamp(); // 2012-10-17T20:46:22.000Z

ObjectId vs UUID, UUID v7 and ULID

  • vs UUID v4: ObjectId is shorter (24 vs 36 chars) and time-sortable, but offers less entropy (96 vs 128 bits) and is not standardized outside MongoDB.
  • vs UUID v7: similar in spirit โ€” both prefix with a timestamp for sortability โ€” but UUID v7 is RFC 9562 (2024) and uses 128 bits with millisecond precision.
  • vs ULID: 128 bits encoded as 26-character Crockford Base32. Larger entropy than ObjectId, more compact than UUID, also time-sortable.
  • Clock drift: all timestamp-prefixed IDs depend on accurate system clocks. NTP synchronization is non-negotiable across a cluster.

Pitfalls, security and Brazilian production use

  • Second granularity: two ObjectIds generated in the same second can sort out of order โ€” fine for chronological grouping, not for strict event ordering.
  • Anti-fraud / IDOR: never use ObjectIds as public URLs for sensitive resources. The timestamp prefix leaks creation time and the counter leaks volume.
  • String vs BSON: ObjectIds can be stored either as native BSON or as the 24-char hex string. Mixing both representations in queries causes silent misses.
  • Brazilian e-commerce stack: companies like B2W, Magalu and iFood use MongoDB in parts of their architecture (alongside Postgres and DynamoDB), so ObjectId shows up across the BR backend ecosystem.
  • Atlas: MongoDB's managed cloud (MongoDB Atlas) generates and validates ObjectIds the same way as a self-hosted cluster โ€” no behavioral differences.

Validation regex and library helpers

A strict regex for the hex string form is ^[a-fA-F0-9]{24}$. Combine it with the official ObjectId.isValid() when accepting input from clients, because isValid() alone returns true for any 12-character ASCII string as well as for 24-hex strings.

FAQ

Is an ObjectId 12 or 24 characters long?

Both, depending on representation: 12 bytes in raw binary BSON, 24 characters when serialized to hexadecimal (each byte = 2 hex digits). The 24-hex form is what you usually see in JSON APIs and URLs.

Are ObjectIds sortable?

Yes โ€” approximately chronologically. The 4-byte timestamp is the most significant portion, so lexicographic sorting on the hex string puts older documents first. Granularity is one second, so IDs generated in the same second may not be perfectly ordered.

Can I extract the creation timestamp?

Yes. The first 4 bytes are a Unix timestamp in seconds. Drivers expose a helper such as new ObjectId(str).getTimestamp() that returns a Date object. You can also decode it manually: parseInt(hex.slice(0,8), 16) gives the Unix seconds.

Why did MongoDB drop the machine ID + PID structure?

The 2018 spec revision replaced the old 3-byte machine identifier + 2-byte process ID with a 5-byte per-process random value. The change closed an information-leak vector โ€” the original fields exposed operational details (hostnames, PIDs) that could aid an attacker.

Should I use ObjectId or UUID v7 in a new project?

If you live inside the MongoDB ecosystem, ObjectId is the path of least resistance โ€” it is the default and every driver supports it natively. For cross-database portability, millisecond precision or stronger entropy, choose UUID v7 (RFC 9562, 2024) or ULID.

Related Tools