Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Snowflake Laravel Package

kra8/laravel-snowflake

Generate distributed, time-ordered Snowflake IDs in Laravel with kra8/laravel-snowflake. It offers configurable worker and datacenter IDs, sequence handling, and an Eloquent trait, giving models unique 64-bit IDs without extra services or coordination.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install

    composer require kra8/laravel-snowflake
    

    Laravel 11/12/13 auto-discovers the SnowflakeServiceProvider — no manual registration needed. Publishing the config is optional but recommended:

    php artisan vendor:publish --tag=snowflake-config
    
  2. Where to look first

    • config/snowflake.php — the four knobs that matter: epoch, datacenter_id, worker_id, sequence (with SNOWFLAKE_* env fallbacks).
    • The Snowflake service class and the snowflake_id() helper — the two entry points you'll actually call.
    • The bundled artisan commands (snowflake:generate / snowflake:id) — handy for smoke-testing that your epoch and worker setup produce sane, monotonic IDs.
  3. First use case Generate a 64-bit, time-ordered ID in place of an auto-increment primary key:

    use Kra8\Snowflake\Snowflake;
    
    $id = app(Snowflake::class)->next();   // e.g. 1234567890123456789
    // or the helper:
    $id = snowflake_id();
    

    Wire it into a model's creating hook (see patterns below) and you have a distributed, sortable PK in minutes. This release (v2.5.0) adds Laravel 13.x compatibility via #60, so the package is safe on current LTS/stable stacks; the rest is dependency hygiene (Carbon, CommonMark).

Implementation Patterns

As a model primary key (most common)

protected $keyType = 'int';
public $incrementing = false;

protected static function booted(): void
{
    static::creating(function ($model) {
        $model->{$model->getKeyName()} ??= snowflake_id();
    });
}

Assign only when unset (??=) so factories and manual overrides still work, and leave $keyType as int server-side — it's only the JSON boundary that needs care (see Gotchas).

In migrations

Schema::create('orders', function (Blueprint $table) {
    $table->unsignedBigInteger('id')->primary(); // not ->id()
    // ...
});

Snowflake values fit unsigned 64-bit; avoid $table->id() which assumes auto-increment.

Distributed deployment topology Assign a unique (datacenter_id, worker_id) pair per node — that's the entire point of the algorithm. Typical setups:

  • Kubernetes StatefulSet → derive both from the ordinal index.
  • Nomad/ECS → pass via SNOWFLAKE_DATACENTER_ID / SNOWFLAKE_WORKER_ID env per task definition.
  • Single-box dev → leave defaults.

Keep the pair stable across restarts; changing it mid-run risks collision only if the same pair is reused, but stability keeps ID ordering sane.

Batch generation / bulk inserts Sequences are cheap — a tight loop is fine:

$ids = collect(range(1, 1000))->map(fn () => snowflake_id());

Don't parallelize across processes sharing a worker ID; the sequence counter isn't shared memory.

As route keys / API identifiers Because IDs are time-ordered, ORDER BY id is effectively ORDER BY created_at. Use whereIn(snowflake_id()) sparingly — for lookups prefer the natural key or a hash so you don't leak creation timestamps (Snowflake IDs are trivially time-decodable).

Gotchas and Tips

  • JavaScript will silently corrupt your IDs. 64-bit integers exceed Number.MAX_SAFE_INTEGER; cast to string in API resources ((string) $model->id) and in any JSON serialization. This is the #1 bug report for every Snowflake package.
  • Never change epoch once you have data. Existing IDs encode the old epoch; shifting it produces overlapping/duplicate value ranges. Pick it once and document it (default is the Twitter epoch).
  • Clock skew is unhandled territory. If the host clock jumps backwards, the generator can emit duplicate or out-of-order IDs. NTP drift is usually fine; container clock rollback (VM pause/resume) is not. Pin timestamps in tests rather than mocking now() globally.
  • Don't assume the sequence resets. It's per-millisecond; two IDs in the same millisecond share a timestamp but differ in sequence — monotonic within a worker, not guaranteed globally across workers in the same millisecond. If you need strict global ordering, sort by (id) only within a single worker.
  • Config caching. If you publish config and later add env vars, run php artisan config:cache again — stale cached config silently uses the old datacenter_id/worker_id.
  • $incrementing = false matters — forgetting it makes Eloquent try to read insertGetId() on a manually-assigned PK and throws at insert time.
  • Upgrade path is safe. v2.5.0 is a non-breaking release (dependency bumps + Laravel 13 support). Nothing to change on upgrade from 2.4.x beyond your usual composer update. If you're pinned to Laravel 11/12, staying on 2.4.1 is also fine — v2.5.0 only widens the constraint.
  • Extension points are minimal — no events or middleware ship with the package. If you need a custom ID strategy (e.g. prefixed/encoded IDs), wrap the Snowflake service in your own class rather than forking; the underlying generator is not designed to be subclassed.
  • Testing tip: fake the generator in your container binding ($this->app->instance(Snowflake::class, $fake)) so feature tests produce deterministic IDs; it's cleaner than intercepting the helper.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin