Skip to content

Axoneo/snowflake-id-go

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Snowflake ID Generator for Go

A high-performance, thread-safe Snowflake ID generator implementation in Go. Snowflake IDs are unique 64-bit integers that are sortable by time, making them ideal for distributed systems.

Features

  • Thread-safe: Safely generate IDs from multiple goroutines
  • High performance: Capable of generating millions of IDs per second
  • Customizable: Configure worker ID, datacenter ID, and custom epoch
  • Time-sortable: IDs are roughly sortable by creation time
  • No dependencies: Uses only Go standard library

Installation

go get github.com/axoneo/snowflake-id-go

Quick Start

package main

import (
    "fmt"
    "log"
    
    "github.com/axoneo/snowflake-id-go"
)

func main() {
    // Create a new generator
    gen, err := snowflake.NewGenerator(snowflake.Config{
        WorkerID:     1,
        DatacenterID: 1,
    })
    if err != nil {
        log.Fatal(err)
    }
    
    // Generate IDs
    id, err := gen.NextID()
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Printf("Generated ID: %d\n", id)
}

Snowflake ID Structure

A Snowflake ID is a 64-bit integer composed of:

| 1 bit (unused) | 41 bits (timestamp) | 5 bits (datacenter) | 5 bits (worker) | 12 bits (sequence) |
  • 1 bit: Unused (always 0)
  • 41 bits: Milliseconds since custom epoch (default: January 1, 2024)
  • 5 bits: Datacenter ID (0-31)
  • 5 bits: Worker ID (0-31)
  • 12 bits: Sequence number (0-4095)

This allows for:

  • 32 datacenters
  • 32 workers per datacenter
  • 4096 IDs per millisecond per worker
  • ~69 years of IDs (from the epoch)

Usage Examples

Basic Usage

gen, err := snowflake.NewGenerator(snowflake.Config{
    WorkerID:     1,
    DatacenterID: 1,
})
if err != nil {
    log.Fatal(err)
}

id, err := gen.NextID()
if err != nil {
    log.Fatal(err)
}

fmt.Println(id) // Output: 123456789012345678

Custom Epoch

// Use a custom epoch (January 1, 2020)
gen, err := snowflake.NewGenerator(snowflake.Config{
    WorkerID:     1,
    DatacenterID: 1,
    Epoch:        1577836800000, // milliseconds
})

Parsing IDs

id := int64(123456789012345678)

// Parse all components
timestamp, datacenterID, workerID, sequence := snowflake.ParseID(id)
fmt.Printf("Timestamp: %d, Datacenter: %d, Worker: %d, Sequence: %d\n",
    timestamp, datacenterID, workerID, sequence)

// Get just the timestamp as time.Time
t := snowflake.GetTimestamp(id)
fmt.Printf("Created at: %s\n", t.Format(time.RFC3339))

Concurrent Usage

The generator is thread-safe and can be used from multiple goroutines:

gen, _ := snowflake.NewGenerator(snowflake.Config{
    WorkerID:     1,
    DatacenterID: 1,
})

var wg sync.WaitGroup
for i := 0; i < 10; i++ {
    wg.Add(1)
    go func() {
        defer wg.Done()
        id, _ := gen.NextID()
        fmt.Println(id)
    }()
}
wg.Wait()

Configuration

Config Structure

type Config struct {
    Epoch        int64 // Custom epoch in milliseconds (optional, uses default if 0)
    WorkerID     int64 // Worker ID (0-31)
    DatacenterID int64 // Datacenter ID (0-31)
}

Constraints

  • WorkerID: Must be between 0 and 31
  • DatacenterID: Must be between 0 and 31
  • Epoch: Custom epoch in milliseconds (optional)

Performance

The generator is highly optimized for performance. Real-world benchmark results with multiple goroutines sharing a single generator:

100 goroutines for 5 seconds:  ~3.1 million IDs/second
50 goroutines for 3 seconds:   ~3.3 million IDs/second

The generator can handle:

  • 3+ million IDs per second with high concurrency
  • Linear scalability across multiple goroutines
  • Minimal contention even with 100+ concurrent workers

Run your own benchmarks:

cd benchmark
go run main.go -d 5s -g 100  # 100 goroutines for 5 seconds

Error Handling

The library returns errors in the following cases:

  • ErrInvalidWorkerID: Worker ID is not between 0 and 31
  • ErrInvalidDatacenterID: Datacenter ID is not between 0 and 31
  • ErrInvalidEpoch: Epoch value is in future

Testing

Run the test suite:

go test -v

Benchmarking

A comprehensive benchmarking tool is included in the benchmark/ directory:

cd benchmark
go run main.go -d 5s -g 100   # 100 goroutines for 5 seconds
go run main.go -d 10s -g 200  # 200 goroutines for 10 seconds
go run main.go -g 50          # Default 5 seconds with 50 goroutines

Flags:

  • -d: Duration to run (e.g., 5s, 10s, 1m)
  • -g: Number of goroutines (default: 100)

Use Cases

Snowflake IDs are perfect for:

  • Distributed systems requiring unique IDs
  • Database primary keys
  • Event IDs in event sourcing
  • Message IDs in message queues
  • Order IDs in e-commerce systems
  • Any scenario requiring sortable, unique identifiers

License

This is free and unencumbered software released into the public domain.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages