Jordium.Snowflake.NET 1.2.1

Prefix Reserved
There is a newer version of this package available.
See the version list below for details.
dotnet add package Jordium.Snowflake.NET --version 1.2.1
                    
NuGet\Install-Package Jordium.Snowflake.NET -Version 1.2.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Jordium.Snowflake.NET" Version="1.2.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Jordium.Snowflake.NET" Version="1.2.1" />
                    
Directory.Packages.props
<PackageReference Include="Jordium.Snowflake.NET" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Jordium.Snowflake.NET --version 1.2.1
                    
#r "nuget: Jordium.Snowflake.NET, 1.2.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Jordium.Snowflake.NET@1.2.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Jordium.Snowflake.NET&version=1.2.1
                    
Install as a Cake Addin
#tool nuget:?package=Jordium.Snowflake.NET&version=1.2.1
                    
Install as a Cake Tool

Jordium.Snowflake.NET

English | 简体中文

NuGet NuGet Downloads .NET Framework .NET .NET Standard License

High-performance distributed ID generator based on Twitter's Snowflake algorithm for .NET. Supports three implementation methods for different scenarios.

Features

  • Globally Unique: Supports multi-datacenter, multi-machine deployment
  • 📈 Trend Increasing: IDs increase by timestamp, optimized for database indexing
  • High Performance: 2 million - 20 million IDs/second per machine (actual results may vary depending on test environment)
  • 🔧 Multiple Implementations: Drift algorithm, Traditional algorithm, Lock-free algorithm
  • Clock Rollback Handling: Automatic handling of system time rollback
  • 🎯 Flexible Configuration: Customizable bit allocation

ID Structure

Standard 64-bit Snowflake ID

┌─────────────────┬─────────────┬─────────────┬──────────────┐
│ Timestamp(41bit)│ DC ID (5bit)│ Worker(5bit)│ Sequence(12) │
└─────────────────┴─────────────┴─────────────┴──────────────┘
  ~69 years        32 DCs        32 Workers   4096/ms

Bit Allocation Examples

Config Worker Bits DC Bits Seq Bits Capacity
Standard 5 5 12 32 DC × 32 Worker × 4096/ms
Multi-DC 4 6 12 64 DC × 16 Worker × 4096/ms
Multi-Worker 6 4 12 16 DC × 64 Worker × 4096/ms
Low Concurrency 5 5 10 32 DC × 32 Worker × 1024/ms

Constraints:

  • Worker bits + DC bits + Seq bits ≤ 22
  • Seq bits ≤ 12

Installation

NuGet CLI

Install-Package Jordium.Snowflake.NET

.NET CLI

dotnet add package Jordium.Snowflake.NET

PackageReference

<PackageReference Include="Jordium.Snowflake.NET" Version="1.2.0" />

Getting Started (v1.2.0)

Client Application

1. Import Namespace
using Jordium.Snowflake.NET;
2. Create Instance Using Factory Pattern
// Method 1: Create instance using WorkerId and DataCenterId
var generator1 = JordiumSnowflakeIDGeneratorFactory.Create(workerId: 1, dataCenterId: 1);
System.Console.WriteLine($"Generator 1 (WorkerId=1, DataCenterId=1): {generator1.NewLong()}");
// Method 2: Create instance using IDGeneratorOption object
var options = new IDGeneratorOptions(workerId: 2, dataCenterId: 1)
{
    Method = 1
};
var generator2 = JordiumSnowflakeIDGeneratorFactory.Create(options);
System.Console.WriteLine($"Generator 2 (WorkerId=2, DataCenterId=1): {generator2.NewLong()}");
// Method 3: Create instance using configuration delegate
var generator3 = JordiumSnowflakeIDGeneratorFactory.Create(opt =>
{
    opt.WorkerId = 3;
    opt.DataCenterId = 1;
    opt.Method = 1;
    opt.BaseTime = new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc);
});
System.Console.WriteLine($"Generator 3 (WorkerId=3, DataCenterId=1): {generator3.NewLong()}");
3. Singleton Pattern - Use global default instance
// Check if default instance is initialized
if (!JordiumSnowflakeIDGeneratorFactory.IsDefaultInitialized)
{
    System.Console.WriteLine("Default instance not initialized. Initializing now...");

    // Initialize the default singleton instance
    JordiumSnowflakeIDGeneratorFactory.InitializeDefault(workerId: 10, dataCenterId: 2);
    System.Console.WriteLine("> Default instance initialized successfully!");
}

// Use the default instance anywhere in your application
long id1 = JordiumSnowflakeIDGeneratorFactory.Default.NewLong();
long id2 = JordiumSnowflakeIDGeneratorFactory.Default.NewLong();
long id3 = JordiumSnowflakeIDGeneratorFactory.Default.NewLong();

ASP.NET Core Dependency Injection (v1.2.0+ Easier Registration, More Standard ASP.NET Core Approach)

1. Import Namespace
using Jordium.Snowflake.NET.Extensions;
2. Register Jordium.Snowflake.NET Service
// Program.cs OR Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    // use code-based configuration
    services.AddJordiumSnowflakeIdGenerator(options => {
        options.WorkerId = 1;
        options.DataCenterId = 1;
    });
}

// Controller
public class OrderController : ControllerBase
{
    private readonly IIDGenerator _idGenerator;

    public OrderController(IIDGenerator idGenerator)
    {
        _idGenerator = idGenerator;
    }

    [HttpPost]
    public IActionResult CreateOrder()
    {
        long orderId = _idGenerator.NewLong();
        // ID Generated
        return Ok(new { OrderId = orderId });
    }
}
3. Supports 3 Registration Methods
// Method 1: Read default "JordiumSnowflakeConfig" configuration from appsettings.json
services.AddJordiumSnowflakeIdGenerator();

// Configuration in appsettings.json:
"JordiumSnowflakeConfig": {
  "DataCenterId": 1,
  "WorkerId": 2,
  "Method": 1,
  "WorkerIdBitLength": 5,
  "DataCenterIdBitLength": 5,
  "SequenceBitLength": 12
}
// Method 2: Use custom configuration section "MyCustomSnowflakeConfigSection"
services.AddJordiumSnowflakeIdGenerator(_configuration, "MyCustomSnowflakeConfigSection");

// Configuration in appsettings.json:
"MyCustomSnowflakeConfigSection": {
  "DataCenterId": 1,
  "WorkerId": 2,
  "Method": 1,
  "WorkerIdBitLength": 5,
  "DataCenterIdBitLength": 5,
  "SequenceBitLength": 12
}
// Method 3: Code-based configuration
services.AddJordiumSnowflakeIdGenerator(options => {
    options.WorkerId = 1;
    options.DataCenterId = 1;
    ...other properties
});

IDGeneratorOptions Property Description

Property Name Type Description Default Value
Method short Calculation method (1-Drift algorithm, 2-Traditional algorithm, 3-Lock-free algorithm) 1
BaseTime DateTime Start time (UTC format), cannot exceed current system time DateTime(2020, 2, 20, 2, 20, 2, 20, DateTimeKind.Utc)
WorkerId ushort Machine code 0
DataCenterId ushort Data center identifier 0
WorkerIdBitLength byte Machine code bit length. Recommended range: 1-5 (requirement: sequence bits + data identifier + machine code bits ≤ 22). 5
DataCenterIdBitLength byte Data center identifier bit length. Recommended range: 1-5 (requirement: sequence bits + data identifier + machine code bits ≤ 22). 5
SeqBitLength byte Sequence bit length. Recommended range: 1-12 (requirement: sequence bits + machine code bits ≤ 22) 4096. 12
MaxSeqNumber int Maximum sequence number (inclusive). (Maximum value calculated by SeqBitLength) 0
MinSeqNumber int Minimum sequence number (inclusive). Default 0, not less than 0, not greater than MaxSeqNumber 0
TopOverCostCount int Maximum drift count (inclusive). Default 2000, recommended range 500-10000 (related to computing power) 2000

Supported Target Frameworks

  • .NET Framework (>= 4.6.1)
  • .NET 6
  • .NET 7
  • .NET 8
  • .NET 9
  • .NET 10
  • .NET Standard (>= 2.0)

Built-in Algorithm Comparison (see source code provided in the open-source library)

The code blocks mentioned in this section are for unit testing, directly instantiated and demonstrated based on the underlying code, not using dependency injection or factory pattern instances.

Three Algorithms

Algorithm Implementation Use Case Performance Clock Rollback Recommended
Method 1 SnowflakeWorkerV1 Monolith app, high concurrency ⭐⭐⭐⭐ ✅ Special sequence ⭐⭐⭐⭐⭐
Method 2 SnowflakeWorkerV2 General, standard implementation ⭐⭐⭐⭐ ❌ Throws exception ⭐⭐⭐
Method 3 SnowflakeWorkerV3 Distributed cluster, microservices ⭐⭐⭐⭐⭐ ⚠️ Large rollback throws ⭐⭐⭐⭐

Detailed Description

Features:

  • ✅ Auto-handles clock rollback (uses reserved sequence 1-4)
  • ✅ Auto "drift" to future time when sequence overflows
  • ✅ Complete event callback mechanism
  • 🔒 Uses lock for synchronization

Use Cases:

  • Monolithic applications (multiple threads competing for same WorkerId)
  • Business sensitive to clock rollback
  • Systems requiring ID generation monitoring

Configuration Example:

var options = new IDGeneratorOptions
{
    WorkerId = 1,
    DataCenterId = 1,
    Method = 1,
    TopOverCostCount = 2000  // Max drift count
};

var generator = new DefaultIDGenerator(options);

// Optional: Listen to events
generator.GenIdActionAsync = arg =>
{
    if (arg.ActionType == 1) // Begin drift
    {
        Console.WriteLine($"Begin drift: WorkerId={arg.WorkerId}");
    }
};

Method 2 - Traditional Algorithm

Features:

  • ✅ Standard Snowflake implementation
  • ✅ Simple logic, easy to understand
  • ❌ Throws exception on clock rollback
  • 🔒 Uses lock for synchronization

Use Cases:

  • Learning and understanding Snowflake algorithm
  • Stable environment with rare clock rollback
  • Simple scenarios without complex features

Configuration Example:

var options = new IDGeneratorOptions
{
    WorkerId = 1,
    DataCenterId = 1,
    Method = 2
};

var generator = new DefaultIDGenerator(options);

try
{
    long id = generator.NewLong();
}
catch (Exception ex)
{
    // Throws exception on clock rollback
    Console.WriteLine($"Clock rollback error: {ex.Message}");
}

Method 3 - Lock-Free Algorithm (High Performance)

Features:

  • ✅ CAS lock-free concurrency, highest performance
  • ✅ Timestamp cached in state, reduces system calls
  • ✅ Significant performance advantage in distributed scenarios
  • ⚠️ Short rollback auto-sleeps and waits
  • ⚠️ Large rollback (> 1000ms) throws exception

Use Cases:

  • Microservice clusters (each service has independent WorkerId)
  • Kubernetes deployment (each Pod has independent WorkerId)
  • High-concurrency distributed systems
  • Scenarios pursuing extreme performance

Configuration Example:

var options = new IDGeneratorOptions
{
    WorkerId = 1,
    DataCenterId = 1,
    Method = 3
};

var generator = new DefaultIDGenerator(options);

// Lock-free performs best in multi-WorkerId scenarios
// Example: Microservice cluster
// Service 1: WorkerId = 1
// Service 2: WorkerId = 2
// Service 3: WorkerId = 3
// ...

Performance Comparison

Single WorkerId Contention (8 threads)
Algorithm Throughput Note
Method 1 6-8M IDs/sec Lock performs stable under single-machine contention
Method 2 5-7M IDs/sec Standard implementation, medium performance
Method 3 4-6M IDs/sec CAS conflict causes performance degradation

Conclusion: For single WorkerId high concurrency, recommend Method 1


Multi WorkerId Independent Scenario (8 WorkerIds)
Algorithm Throughput Note
Method 1 8-12M IDs/sec Lock has fixed overhead
Method 2 7-11M IDs/sec Standard implementation
Method 3 12-18M IDs/sec Lock-free advantage is significant ?

Conclusion: For multi-WorkerId distributed scenarios, recommend Method 3

Performance Test Report

Test Environment

  • CPU: Intel Core i7-12700K (12 cores, 20 threads) @ 3.6GHz
  • RAM: 32GB DDR4 3200MHz
  • OS: Windows 11 Pro
  • .NET Version: .NET 8.0
  • Test Mode: Release build, no debugger

Single Machine Performance (Method 1)

Threads Throughput Avg Latency Note
1 12-15M IDs/sec 0.067-0.083 μs Single thread, no contention
2 9-12M IDs/sec 0.167-0.222 μs Light contention
4 7-9M IDs/sec 0.444-0.571 μs Medium contention
8 6-8M IDs/sec 1.000-1.333 μs Heavy contention

Distributed Performance (Method 3)

WorkerIds Count Each Total Throughput Performance Gain
2 50,000 10-13M IDs/sec +10-15%
4 25,000 12-15M IDs/sec +35-45%
8 12,500 14-18M IDs/sec +50-60%

Correctness Tests

Test Item Count Duplicates Result
Single WorkerId Concurrent 1M 0 ✅ Pass
Multi WorkerId Concurrent 1M 0 ✅ Pass
Extreme Concurrency (32 threads) 3.2M 0 ✅ Pass
Sustained Pressure (5 sec) 10M+ 0 ✅ Pass

Stability Tests

  • Million-level Test: Generate 1M IDs at once, no duplicates
  • Sustained Pressure Test: Continuous generation for 5 seconds, no duplicates
  • Multi-datacenter Test: 3 datacenters × 3 workers, no duplicates
  • Clock Rollback Test: Method 1 auto-handles, Method 2/3 correctly throw exceptions

Performance Notes

Note: Actual performance depends on multiple factors:

  • CPU model and frequency
  • Memory speed
  • OS scheduling
  • .NET runtime version
  • Debug/Release mode
  • System load

The above data are reference values from typical test environments. Real deployment environments may have ±30% variations. We recommend running benchmarks on actual hardware for accurate data.

FAQ

1. How to Choose WorkerId?

Recommended Approaches:

  • Monolithic app: Fixed value (e.g., 1)
  • Microservices: Hash service name and modulo
  • K8s: Use Pod ordinal (StatefulSet)
  • Config center: Fetch from configuration service
// Example: Get from environment variable
var workerId = Environment.GetEnvironmentVariable("WORKER_ID");
var options = new IDGeneratorOptions
{
    WorkerId = ushort.Parse(workerId ?? "1"),
    DataCenterId = 1,
    Method = 1
};

2. How to Handle Clock Rollback?

Algorithm Handling
Method 1 Uses reserved sequence 1-4, supports up to 4 rollbacks
Method 2 Throws exception directly
Method 3 Short time (< 1s) sleeps and waits, long time throws exception

3. How to Ensure Distributed Uniqueness?

Ensure each machine has a unique WorkerId and DataCenterId combination:

// Wrong Example ❌
// Server 1: WorkerId=1, DataCenterId=1
// Server 2: WorkerId=1, DataCenterId=1  ← Will produce duplicate IDs

// Correct Example ✅
// Server 1: WorkerId=1, DataCenterId=1
// Server 2: WorkerId=2, DataCenterId=1
// Server 3: WorkerId=1, DataCenterId=2

4. What if Performance is Below Expectations?

Checklist:

  • ✅ Use singleton pattern (AddSingleton)
  • ✅ Avoid frequent creation of DefaultIDGenerator instances
  • ✅ Choose Method 1 for single-machine high concurrency
  • ✅ Choose Method 3 for distributed scenarios
  • ✅ Check for duplicate WorkerIds
  • ✅ Use Release mode build
  • ✅ Ensure stable system clock

License

MIT License @ 2025 JORDIUM.COM

Contact Us

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 is compatible.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 is compatible.  net48 is compatible.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.2 458 11/19/2025
1.2.1 407 11/19/2025
1.2.0 363 11/17/2025
1.0.2 256 11/16/2025
1.0.1 191 11/15/2025
1.0.0 196 11/15/2025

v1.2.1: Added Symbol package