Fluxer uses Snowflake IDs - a distributed, time-ordered identifier system based on Twitter’s Snowflake format. Every resource in Fluxer (users, guilds, channels, messages, etc.) is assigned a unique 64-bit unsigned integer ID.
A Snowflake ID is composed of three parts:
64 bits total :
├─ Timestamp ( 42 bits ) - Milliseconds since Fluxer epoch
├─ Worker ID ( 10 bits ) - Process / instance identifier
└─ Sequence ( 12 bits ) - Incremental counter per millisecond
Bit Allocation
Component Bits Maximum Value Description Timestamp 42 ~69 years Milliseconds since Fluxer epoch (January 1, 2015 00:00:00 UTC) Worker ID 10 1,023 Unique identifier for the generating worker/process Sequence 12 4,095 Per-millisecond counter to handle high-frequency generation
The Fluxer epoch is 1420070400000 (January 1, 2015 00:00:00 UTC). This epoch allows for approximately 69 years of unique IDs before overflow.
Generation
Basic Usage
import { generateSnowflake } from '@fluxer/snowflake' ;
// Generate with default worker ID (0)
const id = generateSnowflake ();
console . log ( id ); // 175928847299117063n
// Generate with specific worker ID
const id2 = generateSnowflake ( 42 );
Generator Instance
For high-throughput scenarios, use a persistent generator:
import { SnowflakeGenerator } from '@fluxer/snowflake' ;
const generator = new SnowflakeGenerator ({
workerId: 5 ,
now : () => Date . now () // Optional: custom time source
});
const id1 = generator . generate ();
const id2 = generator . generate ();
const id3 = generator . generate ();
Each worker must have a unique Worker ID (0-1023) to prevent ID collisions across distributed systems.
Custom Snowflakes
Create snowflakes with specific components:
import { createSnowflake } from '@fluxer/snowflake' ;
const customId = createSnowflake ({
timestamp: Date . now (),
workerId: 7 ,
sequence: 42
});
// Create from timestamp only
const timestampId = createSnowflakeFromTimestamp ( Date . now ());
Parsing and Utilities
import { snowflakeToDate , parseSnowflake , extractTimestamp } from '@fluxer/snowflake' ;
const id = 175928847299117063 n ;
// Get Date object
const date = snowflakeToDate ( id );
console . log ( date ); // 2020-01-15T14:23:45.678Z
// Parse all components
const parts = parseSnowflake ( id );
console . log ( parts );
// {
// timestamp: Date(2020-01-15T14:23:45.678Z),
// workerId: 3,
// sequence: 1234
// }
// Extract timestamp from string ID
const timestamp = extractTimestamp ( '175928847299117063' );
Comparison and Sorting
import { compare , sortBySnowflakeDesc } from '@fluxer/snowflake' ;
// Compare two snowflakes
const result = compare ( '123456789' , '987654321' );
// Returns: -1 (first is older), 0 (equal), or 1 (first is newer)
// Sort messages by ID (newest first)
const messages = [
{ id: '100' , content: 'Old' },
{ id: '300' , content: 'New' },
{ id: '200' , content: 'Middle' }
];
const sorted = sortBySnowflakeDesc ( messages );
// [{ id: '300', ... }, { id: '200', ... }, { id: '100', ... }]
Validation
import { isValidSnowflake } from '@fluxer/snowflake' ;
// Validate snowflake
const valid = isValidSnowflake ( 175928847299117063 n );
console . log ( valid ); // true
// Invalid cases:
isValidSnowflake ( - 1 n ); // false - negative
isValidSnowflake ( 'invalid' ); // false - not a bigint
isValidSnowflake ( future ); // false - timestamp too far in future
Time-Based Operations
Age Calculation
import { age , ageBigInt } from '@fluxer/snowflake' ;
const messageId = '175928847299117063' ;
const ageMs = age ( messageId );
console . log ( `Message is ${ ageMs } ms old` );
// With BigInt
const ageBigIntMs = ageBigInt ( 175928847299117063 n );
Timestamp Navigation
import {
atNextMillisecond ,
atPreviousMillisecond ,
fromTimestamp
} from '@fluxer/snowflake' ;
// Get ID for next millisecond boundary
const nextId = atNextMillisecond ( '175928847299117063' );
// Get ID for previous millisecond
const prevId = atPreviousMillisecond ( '175928847299117063' );
// Create ID from specific timestamp
const id = fromTimestamp ( Date . now ());
Bucketing System
Fluxer uses buckets to partition snowflakes for efficient querying:
import { makeBucket , makeBuckets } from '@fluxer/snowflake' ;
// Get bucket for a single snowflake
const bucket = makeBucket ( 175928847299117063 n );
console . log ( bucket ); // 203
// Get range of buckets between two IDs
const buckets = makeBuckets (
startId , // Start snowflake
endId // End snowflake
);
console . log ( buckets ); // [203, 204, 205]
Each bucket represents a 10-day time window. Buckets are used internally for database partitioning and efficient range queries.
Bucket Size
import { SNOWFLAKE_BUCKET_SIZE_MS } from '@fluxer/snowflake' ;
console . log ( SNOWFLAKE_BUCKET_SIZE_MS ); // 864000000 (10 days in ms)
Sequence Management
For advanced use cases requiring manual sequence control:
import { SnowflakeSequence } from '@fluxer/snowflake' ;
const sequence = new SnowflakeSequence ({ initialValue: 0 });
// Get next sequence number
const seq1 = sequence . next (); // 0
const seq2 = sequence . next (); // 1
// Check current value
const current = sequence . peek (); // 2
// Check for overflow
if ( sequence . willOverflowNext ()) {
sequence . reset (); // Reset to 0
}
Best Practices
Use BigInt Always use BigInt (n suffix) for snowflakes in TypeScript/JavaScript to prevent precision loss with large integers.
Unique Worker IDs Assign unique Worker IDs (0-1023) to each process/instance in distributed deployments to prevent ID collisions.
Time-Based Ordering Snowflakes are naturally time-ordered. Use this property for efficient range queries and pagination.
Avoid Hardcoding Never hardcode snowflake IDs. They are instance-specific and will differ across environments.
API Reference
Constants
Constant Type Value Description FLUXER_EPOCHbigint1420070400000nFluxer epoch in milliseconds WORKER_ID_BITSbigint10nBits allocated for worker ID SEQUENCE_BITSbigint12nBits allocated for sequence MAX_WORKER_IDbigint1023nMaximum worker ID value MAX_SEQUENCEbigint4095nMaximum sequence value TIMESTAMP_SHIFTbigint22nBit shift for timestamp
Functions
Generate a new snowflake ID Parameters:
workerIdOrOptions?: number | SnowflakeGeneratorOptions
Returns: bigint
Create a snowflake from components Parameters:
options: CreateSnowflakeOptions
Returns: bigint
Parse snowflake into components Parameters: Returns: SnowflakeParts
Validate a snowflake ID Parameters: Returns: boolean