How to Use This Tool
Paste an ID. The format is detected from its shape and the timestamp is extracted with the right arithmetic for that format.
The four formats
- Snowflake — a 64-bit integer, usually 18 or 19 digits. The top 41 bits are milliseconds since a platform-specific epoch, then 10 bits identify the machine that generated it and 12 bits are a per-millisecond counter. Used by Twitter/X, Discord, Instagram and many internal systems.
- MongoDB ObjectId — 24 hex characters. The first 8 are seconds since 1970, so the resolution is one second, not one millisecond. The rest is a random value plus a counter.
- ULID — 26 characters in Crockford base32. The first 10 encode milliseconds since 1970 and the remaining 16 are random. Sorts chronologically as text, which is the point.
- UUIDv7 — a standard UUID whose first 48 bits are milliseconds since 1970.
Identifiable by the version digit
7at the start of the third group.
The epoch trap
Snowflake IDs do not store an absolute time. They store a count from a starting point each platform chose, and those differ:
- Twitter/X — 4 November 2010
- Discord — 1 January 2015
Apply Twitter's epoch to a Discord ID and every date lands about four years early. Nothing errors, nothing looks impossible, and you get a plausible date that is simply wrong — the same failure pattern as reading milliseconds as seconds. If a decoded date is suspiciously close to some other significant date, check which epoch you used first.
What this is good for, and what it is not
It is genuinely useful for dating a record when you have the ID and not the row, checking whether two records were created around the same time, and sanity-checking imported data. It is also how you can tell roughly when a Discord account or a tweet was created from its link.
What it is not is authoritative. The timestamp is set by whichever machine generated the ID, from that
machine's clock, so a skewed server produces skewed IDs. It also records when the ID was made,
which is not always when the record was saved — an ID generated in advance and used later will
read early. For anything that matters, the stored created_at column is the source of truth
and this is a convenience.
Why IDs carry timestamps at all
Sortability. A distributed system cannot use an auto-incrementing counter without a central authority to hand out numbers, which becomes a bottleneck. Putting the time at the top of the ID means IDs generated on different machines still sort roughly chronologically, and roughly is enough for indexes to stay efficient. That is also why ULIDs and UUIDv7 exist — a random UUIDv4 scatters writes across a B-tree index, while a time-ordered one appends.
