Snowflake ID decoder
Paste a Discord or Twitter/X ID to see the moment it was made, to the millisecond, and the worker and sequence bits beside it. Or type a date to get the range of snowflakes from that moment.
A user, message, server or channel ID: in Discord, turn on Developer Mode and choose Copy ID. Up to 20 digits.
- Your time
- …
- Age
- …
- Unix ms
- 1462015105796
Working: shift right by 22, add the epoch
175928847299117063 >> 22 = 41944705796
41944705796 + 1420070400000 = 1462015105796
= 2016-04-30T11:18:25.796Z
Shifting right by 22 drops the low 22 bits, leaving the milliseconds since the Discord epoch, 2015-01-01T00:00:00.000Z. Adding the epoch gives Unix milliseconds.
The bits
| Field | Bits | Value |
|---|---|---|
| Milliseconds since the Discord epoch41944705796 ms after the epoch: 2016-04-30T11:18:25.796Z | 63–22 (42) | 41944705796 |
| Internal worker ID1 | 21–17 (5) | 1 |
| Internal process ID0 | 16–12 (5) | 0 |
| Increment7, goes up by one for every ID generated on that process | 11–0 (12) | 7 |
As a JavaScript number this becomes 175928847299117060, which is a different ID: numbers above 2^53 lose their last digits, which is why APIs send snowflakes as strings.
Date to snowflake
For example 2024-03-01, 2024-03-01 18:30 or 2024-03-01T18:30:00+01:00. Uses the Discord layout chosen above.
Every Discord ID made in that millisecond lies between these two: the time in the top bits, and the low 22 bits all 0 for the first and all 1 for the last. Use the first as an after value or the last as a before value to page through messages by time.
How a snowflake ID works
A snowflake is a 64-bit number that a server can make on its own, without asking a central database for the next number, and that still sorts in time order. Twitter designed it in 2010, and Discord uses the same idea. The top bits are the milliseconds since the service's epoch; below them are bits that say which machine made the ID, and a counter for IDs made by that machine in the same millisecond.
Because the time is in the top bits, a bigger ID is always a later one (to the millisecond), so sorting IDs sorts by age. The same Discord example, worked through:
175928847299117063 >> 22 = 41944705796
41944705796 + 1420070400000 = 1462015105796
= 2016-04-30T11:18:25.796Z
The same sum in code. BigInt keeps all 64 bits; a plain number would not.
// JavaScript
const snowflake = '175928847299117063';
const ms = Number(BigInt(snowflake) >> 22n) + 1420070400000;
new Date(ms).toISOString();
# Python
from datetime import datetime, timezone
snowflake = 175928847299117063
datetime.fromtimestamp(((snowflake >> 22) + 1420070400000) / 1000, tz=timezone.utc)
| Service | Epoch | Fields, top bits first (width) | Runs out |
|---|---|---|---|
| Discord | 2015-01-01T00:00:00.000Z 1420070400000 |
Milliseconds since the Discord epoch (42), Internal worker ID (5), Internal process ID (5), Increment (12) | 2154-05-15 |
| Twitter/X | 2010-11-04T01:42:54.657Z 1288834974657 |
Sign bit (1), Milliseconds since the Twitter epoch (41), Machine ID (10), Sequence (12) | 2080-07-10 |
Discord snowflakes by year
The first possible Discord ID of each year. Any ID smaller than a year's value was made before that year began, so you can date an ID roughly at a glance.
| From | First snowflake |
|---|---|
| 2015-01-01 | 0 |
| 2016-01-01 | 132271570944000000 |
| 2017-01-01 | 264905529753600000 |
| 2018-01-01 | 397177100697600000 |
| 2019-01-01 | 529448671641600000 |
| 2020-01-01 | 661720242585600000 |
| 2021-01-01 | 794354201395200000 |
| 2022-01-01 | 926625772339200000 |
| 2023-01-01 | 1058897343283200000 |
| 2024-01-01 | 1191168914227200000 |
| 2025-01-01 | 1323802873036800000 |
| 2026-01-01 | 1456074443980800000 |
| 2027-01-01 | 1588346014924800000 |
Common mistakes
- Parsing the ID as a number. In JavaScript, Number("175928847299117063") gives 175928847299117060. The last digits are gone because the value is past 253, the limit of exact integers in a double; the integer limits page lists where each type runs out. Keep IDs as strings and use BigInt for arithmetic.
- Using the wrong epoch. A Discord ID read from the Unix epoch lands in the 1970s or 1980s, and one read with Twitter's epoch comes out about four years too early. Switch the service above to see the difference.
- Dividing instead of shifting in a language with floats. id / 4194304 in floating point rounds; shift right by 22 on a 64-bit integer, or divide with integer division.
To see an ID as the 64 bits it is, paste it into the binary converter. Snowflakes are one of several IDs with a time inside; UUID version 7, ULIDs and MongoDB ObjectIds are decoded by the UUID decoder.
Questions
How do I get the date from a Discord ID?
Shift the ID right by 22 bits, which is the same as dividing by 4,194,304 and dropping the remainder, then add Discord's epoch, 1420070400000. The result is milliseconds since 1970. For 175928847299117063 that is 41944705796 + 1420070400000 = 1462015105796, which is 2016-04-30T11:18:25.796Z.
What is the Discord epoch?
2015-01-01T00:00:00.000Z, the first moment of 2015, which is 1420070400000 in Unix milliseconds. Discord IDs count from there rather than from 1970 so that the 42 timestamp bits last longer: until 2154-05-15T07:35:11.103Z.
Why are snowflake IDs sent as strings?
JavaScript numbers only hold whole numbers exactly up to 2^53, and snowflakes go past that. Read as a number, 175928847299117063 becomes 175928847299117060, a different ID. Discord's and Twitter's APIs send them as strings so nothing is lost; use BigInt to do arithmetic on them.
How do I find Discord messages from a particular date?
Turn the date into a snowflake and use it as the before or after value in Discord's API, which accepts any snowflake there, not only real message IDs. The date to snowflake box on this page gives the smallest and largest snowflake for a moment.
Can two snowflakes be the same?
Two different objects should not get the same one: each worker and process has its own ID bits, and the increment goes up for every ID that process makes. Discord's documentation notes one exception on purpose: some child objects share their parent's ID, such as a server's @everyone role, which has the server's ID. In Twitter's original design the 12-bit sequence starts again from 0 each millisecond, so one machine can make 4,096 IDs per millisecond.
Is a Twitter/X ID decoded the same way?
The same shift by 22, but with Twitter's epoch, 1288834974657 (2010-11-04T01:42:54.657Z). The 10 bits below the time are a machine ID rather than Discord's worker and process, and the top bit is kept 0 so the ID is positive as a signed 64-bit number. Tweets from before late 2010 have older, sequential IDs that hold no time.