Developer Guide

Snowflake IDs: The Hidden Timestamp in Every ID

Look up any Discord user, and its ID alone can tell you the day it was created — no API call, no lookup table. Same for a tweet, a Discord message, or an X post. Here's the trick.

Updated July 2026

Grab any Discord user ID — say, one you copied with Developer Mode turned on — and it looks like a meaningless string of digits: 175928847299117063. It isn't meaningless. Buried in that number is the exact millisecond the account, message, server, or channel was created. Twitter/X IDs work the same way. This is called a snowflake ID, and once you know the trick, decoding one takes about three lines of code.

Where the name comes from

Twitter built the original snowflake ID generator around 2010 to solve a real infrastructure problem: how do you hand out unique, roughly time-ordered IDs across many database servers at once, without a single shared counter becoming a bottleneck? The answer was to bake a timestamp, a machine identifier, and a per-millisecond sequence number into one 64-bit integer, generated independently on each machine. Discord adopted the same design years later for exactly the same reason. "Snowflake," because no two are supposed to be alike — and because, like a real snowflake, most of its structure is invisible until you look closely.

How the 64 bits are laid out

Both platforms use the same basic shape, differing only in the epoch (the zero-point date) and minor details of the low bits:

Because the timestamp occupies the highest bits, larger ID number always means later creation time — which is why sorting a list of Discord message IDs numerically also sorts them chronologically, with no separate created_at column required.

Decoding a Discord ID

Discord's epoch is midnight UTC on January 1, 2015. To recover the timestamp: right-shift the ID by 22 bits (dropping the worker, process, and sequence bits), then add the epoch in milliseconds.

JavaScript
const DISCORD_EPOCH = 1420070400000n; // 2015-01-01T00:00:00.000Z

function discordIdToDate(id) {
  const ms = (BigInt(id) >> 22n) + DISCORD_EPOCH;
  return new Date(Number(ms));
}

discordIdToDate('175928847299117063');
// -> 2016-04-30T11:18:25.796Z

Note the BigInt: Discord IDs regularly exceed Number.MAX_SAFE_INTEGER, so plain JavaScript numbers will silently lose precision in the low bits and give you a slightly wrong ID back if you convert to a number too early. Do the bit-shifting in BigInt, and only convert to a regular number at the very end, once you're working with a millisecond count small enough to be safe.

Python

Python
from datetime import datetime, timezone

DISCORD_EPOCH = 1420070400000

def discord_id_to_date(snowflake: int) -> datetime:
    ms = (snowflake >> 22) + DISCORD_EPOCH
    return datetime.fromtimestamp(ms / 1000, tz=timezone.utc)

discord_id_to_date(175928847299117063)
# -> 2016-04-30 11:18:25.796000+00:00

Python's integers don't have a precision ceiling, so there's no BigInt-style gotcha to worry about here.

Decoding a Twitter/X ID

Same formula, different epoch: November 4, 2010, 01:42:54.657 UTC — the exact moment Twitter's original Snowflake service went live and replaced the old sequential numeric IDs.

JavaScript
const TWITTER_EPOCH = 1288834974657n;

function twitterIdToDate(id) {
  const ms = (BigInt(id) >> 22n) + TWITTER_EPOCH;
  return new Date(Number(ms));
}

This works identically whether the ID belongs to a post, a reply, or a user account — account IDs are minted the same way, so a user's ID quietly reveals the day they signed up.

What this is actually useful for

A few concrete cases where this comes up in practice: figuring out how old a Discord server or account is when the platform's UI doesn't show it directly; sorting or bucketing scraped data by creation time when you only have IDs, not timestamps; spotting freshly-created bot accounts in a moderation pipeline, since a burst of consecutive IDs created within seconds of each other is a strong signal; and reconstructing a rough timeline of events from log data that recorded only an ID.

Don't want to write the bit-shifting yourself? Paste the ID into the Snowflake ID Decoder and it handles Discord, Twitter/X, or a custom epoch instantly.

Related

Related tools & reading