Projectsphp-snowflakeLaravel

PHP Snowflake

Package

Lightweight, framework-agnostic Snowflake IDs generator with first-class Laravel integration.

Upgrade Guide

Laravel integration

This package includes an optional, opt-in Laravel integration. The core Snowflake generator has no framework dependency — the Laravel classes only load when running inside a Laravel application.

Installation

The Laravel integration is bundled with the package — there is nothing extra to install:

composer require bradietilley/php-snowflake

The service provider is auto-discovered. To customise the configuration, publish the config file:

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

Preparing your schema

Your model's primary key must not auto-increment. Since $table->id(); adds auto-increment, swap it out:

-$table->id();
+$table->bigInteger('id')->unsigned()->primary();

Integrating with your models

Add the HasSnowflake trait to your models. It handles every aspect of a Snowflake ID:

  • Automatically setting the id to a Snowflake ID
  • Configuring the cast for id to string
  • Disabling increments on the model
  • Configuring the keyType to string
use BradieTilley\Snowflake\Laravel\Eloquent\HasSnowflake;
use Illuminate\Database\Eloquent\Model;

class SomeModel extends Model
{
    use HasSnowflake;
}

You're all set:

$model = SomeModel::create();
$model->id; // 9348975348573485734

Concurrency

By default the package uses an in-process MemorySequenceResolver. That is enough when each app server / queue worker has a unique snowflake.constants.worker (and optionally cluster).

For shared worker ids across processes, opt into the cache sequencer by setting config — SnowflakeGenerator auto-registers it on boot:

use BradieTilley\Snowflake\Laravel\SequenceResolvers\LaravelSequenceResolver;

'sequencing' => [
    'resolver' => LaravelSequenceResolver::class,
    'store' => env('SNOWFLAKE_CACHE_STORE'), // Redis recommended
    'prefix' => env('SNOWFLAKE_CACHE_PREFIX', ''),
],

When sequencing.resolver is null, the core memory default is left in place.

Configurable options for the cache resolver:

  • Cache store (snowflake.sequencing.store) — defaults to your app's default cache store
  • Cache prefix (snowflake.sequencing.prefix)

Redis is recommended. The resolver relies on atomic add (SET NX) and increment — no cache lock is taken. For a given microsecond key, the first caller wins add and gets sequence 0; any other callers in that same microsecond atomically increment. Callers on different microseconds never block each other.

Avoid file/array cache stores for multi-process ID generation; they do not provide the atomicity this resolver assumes.

Bit signature

Call Snowflake::configureSignature() before any ID is generated (e.g. in AppServiceProvider::register() or bootstrap/app.php). See Usage.

Testing

In tests you may want predictable, sequential IDs similar to traditional auto-incrementing IDs.

By enabling the snowflake.testing configuration setting, the standard SnowflakeIdentifierResolver is swapped with a SequentialIdentifierResolver, generating realistic-length IDs that follow a standard auto-incrementing pattern.

When in testing mode, IDs can be grouped using the $group argument. The $group is automatically set to the respective model class name, so both Product::create() and User::create() generate 9000000000000000001, then 9000000000000000002, and so on.