Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Snowflake IDs

Mastic uses Snowflake IDs as unique identifiers for statuses and other user-generated entities. A Snowflake ID is a 64-bit unsigned integer that encodes a creation timestamp, making IDs roughly sortable by time without requiring a secondary index.

Bit Layout

A Mastic Snowflake ID is a u64 with the following structure:

BitsWidthFieldDescription
63-1648TimestampMilliseconds since the Mastic epoch
15-016SequencePer-millisecond monotonic counter (0-65 535)

Total: 48 + 16 = 64 bits.

Epoch

The Mastic epoch is 2026-01-01T00:00:00Z (Unix timestamp 1 767 225 600 000 ms).

With 48 bits of millisecond precision the timestamp space covers approximately 8 919 years, which is more than sufficient even when measured from the Unix epoch (1970). The custom Mastic epoch is therefore not strictly necessary for correctness, but subtracting it produces smaller numeric values in the early years of the platform, resulting in shorter IDs when serialised as decimal strings in URLs and JSON-LD payloads.

Generation

Each User Canister maintains its own Snowflake generator with:

  • last_timestamp_ms: the timestamp of the last generated ID.
  • sequence: a 16-bit counter, reset to 0 whenever last_timestamp_ms advances.

Algorithm

1. current_ms = ic_cdk::api::time() / 1_000_000  (nanoseconds to milliseconds)
2. timestamp  = current_ms - MASTIC_EPOCH_MS
3. if timestamp == last_timestamp_ms:
       sequence += 1
       if sequence > 0xFFFF:
           trap("Snowflake sequence overflow")
   else:
       sequence = 0
       last_timestamp_ms = timestamp
4. id = (timestamp << 16) | sequence

Properties

  • Uniqueness: guaranteed within a single canister because the sequence counter prevents collisions within the same millisecond, and the IC provides monotonic time.
  • Global uniqueness: achieved because the full ActivityPub id is a URL that includes the user handle, e.g. https://{domain}/users/{handle}/statuses/{snowflake}.
  • Sortability: IDs are monotonically increasing within a canister and roughly chronologically ordered across canisters.

No Worker Bits

Unlike the original Twitter Snowflake or Mastodon’s variant, Mastic does not include worker/node bits. Each User Canister is the sole generator of its own IDs, so there is no risk of cross-worker collision. This simplifies the layout and maximises the sequence space.

Representation

  • On-chain (Candid): nat64
  • Over ActivityPub (JSON-LD): decimal string, e.g. "116301527915219032"
  • In URLs: decimal, e.g. /users/alice/statuses/116301527915219032