PHPackages                             erikwang2013/snowflake-php - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. erikwang2013/snowflake-php

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

erikwang2013/snowflake-php
==========================

A distributed unique ID generator based on Twitter's Snowflake algorithm, compatible with Laravel, Webman, ThinkPHP, and Hyperf.

v2.0.0(3w ago)1160↓100%MITPHPPHP &gt;=8.0

Since May 14Pushed 3w agoCompare

[ Source](https://github.com/erikwang2013/snowflake-php)[ Packagist](https://packagist.org/packages/erikwang2013/snowflake-php)[ RSS](/packages/erikwang2013-snowflake-php/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (5)Dependencies (1)Versions (6)Used By (0)

Snowflake PHP
=============

[](#snowflake-php)

A distributed unique ID generator based on Twitter's Snowflake algorithm, compatible with Laravel, Webman, ThinkPHP, and Hyperf.

> 中文文档请参阅 [README.zh-CN.md](README.zh-CN.md)

About
-----

[](#about)

Snowflake PHP generates 64-bit, k-ordered, globally unique IDs without requiring a central coordinator. Each ID is composed of a timestamp, datacenter ID, worker ID, and sequence number — allowing tens of thousands of IDs per second per node with no database round-trips.

Key features:

- **Pure PHP, zero dependencies** — no extensions or external services required
- **Pluggable sequence resolvers** — built-in sequential and random strategies, or bring your own
- **Flexible bit allocation** — adjust timestamp/worker/datacenter/sequence bits to fit your scale
- **Clock drift tolerance** — configurable tolerance window for NTP adjustments
- **Framework agnostic** with first-class adapters for Laravel, ThinkPHP, Webman, and Hyperf
- **ID parsing** — decompose generated IDs back into timestamp, node, and sequence components

Requirements
------------

[](#requirements)

- PHP &gt;= 8.0
- 64-bit system (required for native 64-bit integer operations)

Installation
------------

[](#installation)

```
composer require erikwang2013/snowflake-php
```

Quick Start
-----------

[](#quick-start)

```
use Snowflake\Snowflake;

$snowflake = new Snowflake();
$id = $snowflake->id();          // e.g. 508047278033704960
$id = $snowflake->nextId();      // alias for id()
```

With custom worker and datacenter IDs:

```
$snowflake = new Snowflake(workerId: 5, datacenterId: 3);
$id = $snowflake->id();
```

Configuration Reference
-----------------------

[](#configuration-reference)

KeyTypeDefaultDescription`epoch`int`1704067200000`Custom epoch in ms (default: 2024-01-01 UTC)`worker_id`int`0`Worker/node identifier`datacenter_id`int`0`Datacenter identifier`worker_bits`int`5`Bits for worker ID`datacenter_bits`int`5`Bits for datacenter ID`sequence_bits`int`12`Bits for sequence number`sequence_resolver`string`SequentialSequenceResolver`FQCN of SequenceResolver`clock_tolerance_ms`int`0`Max backward clock drift (0 = strict)### Bit Layout

[](#bit-layout)

Default layout (63 data bits + 1 sign bit = 64 bits total):

```
| reserved(1) |  timestamp(41)   | datacenter(5) | worker(5) | sequence(12) |

```

Maximum lifespan with default epoch: ~69 years (until ~2093).

### Using Configuration Array

[](#using-configuration-array)

```
$snowflake = Snowflake::fromConfig([
    'worker_id' => 1,
    'datacenter_id' => 2,
    'epoch' => 1704067200000,
]);
$id = $snowflake->id();
```

Framework Integration
---------------------

[](#framework-integration)

### Laravel

[](#laravel)

The package supports Laravel auto-discovery. After installation:

1. Publish the config (optional):

```
php artisan vendor:publish --tag=snowflake-config
```

2. Configure environment variables in `.env`:

```
SNOWFLAKE_WORKER_ID=1
SNOWFLAKE_DATACENTER_ID=1
```

3. Use the Facade or dependency injection:

```
// Facade
use Snowflake;
$id = Snowflake::id();

// Dependency injection
use Snowflake\Snowflake;

class OrderController
{
    public function store(Snowflake $snowflake)
    {
        $orderId = $snowflake->id();
    }
}

// Container access
$id = app('snowflake')->id();
$id = app(Snowflake::class)->id();
```

### Webman

[](#webman)

1. Copy the plugin config to your project:

```
cp vendor/erikwang2013/snowflake-php/src/Adapters/Webman/config/app.php \
   config/plugin/erikwang2013/snowflake-php/app.php
```

2. Register a singleton in `process.php` or bootstrap:

```
use Snowflake\Snowflake;

Worker::$container->add(Snowflake::class, function () {
    return Snowflake::fromConfig(
        config('plugin.erikwang2013.snowflake-php.app.snowflake')
    );
});
```

3. Usage:

```
$id = Worker::$container->get(Snowflake::class)->id();
```

### ThinkPHP 6+

[](#thinkphp-6)

1. Copy the config file to your project:

```
cp vendor/erikwang2013/snowflake-php/src/Adapters/ThinkPHP/config/snowflake.php \
   config/snowflake.php
```

2. Register the service in `app/service.php`:

```
return [
    \Snowflake\Adapters\ThinkPHP\Service::class,
];
```

3. Usage:

```
// Container
$id = app('snowflake')->id();

// Dependency injection
use Snowflake\Snowflake;

class IndexController
{
    public function index(Snowflake $snowflake)
    {
        $id = $snowflake->id();
    }
}

// Facade
use Snowflake\Adapters\ThinkPHP\Facade;
$id = Facade::id();
```

### Hyperf

[](#hyperf)

1. Publish the config:

```
php bin/hyperf.php vendor:publish erikwang2013/snowflake-php
```

2. Register the DI binding in `config/autoload/dependencies.php`:

```
use Snowflake\Snowflake;

return [
    Snowflake::class => function () {
        return Snowflake::fromConfig(config('snowflake'));
    },
];
```

3. Usage via constructor injection:

```
use Snowflake\Snowflake;

class OrderService
{
    public function __construct(private Snowflake $snowflake) {}

    public function create(): int
    {
        return $this->snowflake->id();
    }
}
```

ID Parsing
----------

[](#id-parsing)

Decompose a Snowflake ID into its components:

```
$id = $snowflake->id();

// Using the instance (respects custom bit layout)
$parsed = $snowflake->parseId($id);
// [
//     'timestamp_ms' => 1736380800123,
//     'datetime'     => '2025-01-09 00:00:00.123',
//     'worker_id'    => 5,
//     'datacenter_id' => 3,
//     'sequence'     => 42,
// ]

// Static method (uses default bit layout)
$parsed = Snowflake::parse($id, $epoch);
```

Sequence Resolvers
------------------

[](#sequence-resolvers)

Two built-in implementations:

### SequentialSequenceResolver (default)

[](#sequentialsequenceresolver-default)

Classic Snowflake behavior. Sequence starts at 0 each millisecond and increments sequentially. Guarantees monotonically increasing IDs within a single node.

```
use Snowflake\Resolvers\SequentialSequenceResolver;

$snowflake = new Snowflake(
    sequenceResolver: new SequentialSequenceResolver()
);
```

### RandomSequenceResolver

[](#randomsequenceresolver)

Starts each millisecond with a random sequence number. Makes IDs less predictable (prevents enumeration) but IDs within the same millisecond are not monotonic.

```
use Snowflake\Resolvers\RandomSequenceResolver;

$snowflake = new Snowflake(
    sequenceResolver: new RandomSequenceResolver()
);
```

### Custom Resolver

[](#custom-resolver)

Implement `Snowflake\Contracts\SequenceResolver`:

```
use Snowflake\Contracts\SequenceResolver;

class RedisSequenceResolver implements SequenceResolver
{
    public function next(int $timestamp, int $maxSequence): ?int
    {
        $key = "snowflake:seq:{$timestamp}";
        $seq = redis()->incr($key);
        redis()->expire($key, 1);

        if ($seq > $maxSequence) {
            return null;
        }

        return $seq - 1;
    }
}
```

Exception Handling
------------------

[](#exception-handling)

ExceptionWhen`InvalidWorkerIdException`Worker ID exceeds `2^worker_bits - 1``InvalidDatacenterIdException`Datacenter ID exceeds `2^datacenter_bits - 1``ClockDriftException`System clock moved backwards beyond tolerance`TimestampOverflowException`Epoch has been exhausted (lifespan ended)`SnowflakeException`Base exception for all package exceptionsDistributed Deployment
----------------------

[](#distributed-deployment)

When running across multiple servers or processes, ensure each instance uses a unique `(datacenter_id, worker_id)` pair:

```
// Read from environment, hostname hash, or service discovery
$workerId = (int) getenv('WORKER_ID');
$datacenterId = (int) getenv('DC_ID');

$snowflake = new Snowflake(
    workerId: $workerId,
    datacenterId: $datacenterId
);
```

With the default 5+5 bit layout, you can support up to 32 datacenters × 32 workers = 1024 unique nodes.

To support more workers, adjust bit allocation:

```
// 10 worker bits = 1024 workers, 0 datacenter bits = single DC
$snowflake = new Snowflake(
    workerId: $workerId,
    workerBits: 10,
    datacenterBits: 0
);
```

Performance
-----------

[](#performance)

Typical throughput on modern hardware: **~500,000 IDs/second** (single process).

IDs are generated purely in-process with no external dependencies. The primary bottleneck is PHP's `microtime()` call and integer bit operations, both of which are O(1).

开源不易，欢迎支持
---------

[](#开源不易欢迎支持)

微信支付宝[![微信](./docs/weixinpay.png "微信")](./docs/weixinpay.png)[![支付宝](./docs/alipay.png "支付宝")](./docs/alipay.png)---

License
-------

[](#license)

MIT — Copyright (c) 2026 erik  —

###  Health Score

42

—

FairBetter than 88% of packages

Maintenance95

Actively maintained with recent releases

Popularity17

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity42

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

5

Last Release

23d ago

Major Versions

v1.0.4 → v2.0.02026-05-17

### Community

Maintainers

![](https://www.gravatar.com/avatar/b7cb25ea34934de7bca95e93e6042aa82444572de7b80bca88acfdb306e6bb85?d=identicon)[erikwang2013](/maintainers/erikwang2013)

---

Top Contributors

[![erikwang2013](https://avatars.githubusercontent.com/u/9014941?v=4)](https://github.com/erikwang2013 "erikwang2013 (7 commits)")

---

Tags

unique-iddistributedsnowflakeid-generator

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/erikwang2013-snowflake-php/health.svg)

```
[![Health](https://phpackages.com/badges/erikwang2013-snowflake-php/health.svg)](https://phpackages.com/packages/erikwang2013-snowflake-php)
```

###  Alternatives

[godruoyi/php-snowflake

An ID Generator for PHP based on Snowflake Algorithm (Twitter announced).

8632.5M65](/packages/godruoyi-php-snowflake)[kra8/laravel-snowflake

Snowflake for Laravel and Lumen.

186434.9k8](/packages/kra8-laravel-snowflake)[hyperf/snowflake

A snowflake library

25837.9k67](/packages/hyperf-snowflake)[identifier/identifier

Common Interfaces and Factories for Identifiers

3231.4k1](/packages/identifier-identifier)[omaressaouaf/laravel-id-generator

Generate custom incremental unique ids for Laravel

577.1k](/packages/omaressaouaf-laravel-id-generator)[ramsey/identifier

A PHP library for generating and working with identifiers, including UUIDs, ULIDs, and Snowflakes

605.2k2](/packages/ramsey-identifier)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
