PHPackages                             itransport/snowflake - 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. [Database &amp; ORM](/categories/database)
4. /
5. itransport/snowflake

ActiveLibrary[Database &amp; ORM](/categories/database)

itransport/snowflake
====================

A package to create Twitter Snowflake identifiers

1.0.0(3y ago)046MITPHPPHP ^8.0

Since Jun 3Pushed 3y ago1 watchersCompare

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

READMEChangelog (1)Dependencies (3)Versions (2)Used By (0)

Snowflake
=========

[](#snowflake)

This package enables a Laravel application to create Twitter Snowflake identifiers. It is a very thin wrapper around the excellent [Snowflake PHP](https://github.com/godruoyi/php-snowflake) library created by Godruoyi.

What are Snowflakes?
--------------------

[](#what-are-snowflakes)

Snowflakes are a form of unique identifier devised by Twitter. In this respect, they are similar to other unique identifier algorithms such as UUID or ULID.

Why should I use them?
----------------------

[](#why-should-i-use-them)

I've written an [article](https://itnext.io/choosing-the-right-data-type-means-of-generating-unique-primary-keys-d7aac92968c6) exploring the benefits of Snowflakes over other unique identifiers. However, in short:

- They consists entirely of integers.
- They uses less space (16 characters, so it fits in a `BIGINT`).
- Indexing of integers is much faster than indexing a string.
- Keys begin with a timestamp, so are sortable.
- Keys end with a random number, so guessing table size is not possible.
- Databases handle integers more efficiently than strings.
- Generation of new keys is faster (less than 1 ms).

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

[](#installation)

Pull in the package using Composer:

```
composer require itransport/snowflake
```

Configuration
-------------

[](#configuration)

Snowflake includes a configuration file with several settings that you can use to initialize the Snowflake service. You should begin by publishing this configuration file:

```
php artisan vendor:publish
```

### Distributed architecture

[](#distributed-architecture)

The service allows for the use of a distributed architectural setup involving data centers and worker nodes that are each responsible for generating Snowflakes according to their own designated identifiers. For maximum flexibility, as well as backward compatibility, this is the default configuration.

If you do not intend to run a distributed architectural setup, then your first step should be to set the corresponding configuration value to `false`.

### Data centers and worker nodes

[](#data-centers-and-worker-nodes)

When using a distributed architectural setup, you'll need to set the data center and worker node that the application should use when generating Snowflakes. These are both set to `1` by default, as that is a good starting point, but you are free to increase these numbers as you add more centers and nodes.

The maximums for each of these configuration values is `31`. This gives you up to 31 nodes per data center, and 31 data centers in total. Therefore, you can have up `961` worker nodes each generating unique Snowflakes.

> If you have disabled distributed architecture, then you can skip the data center and worker node values as they will be ignored by the service.

### Starting timestamp

[](#starting-timestamp)

The service compares the Unix Epoch with the given starting timestamp as part of the process in generating a unique Snowflake. As a result, Snowflakes can be generated for up to 69 years using any given starting timestamp.

In most cases, you should set this value to the current date using a format of `YYYY-MM-DD`.

> Do not set the timestamp to a date in the future, as that won't achieve anything. You should also avoid using a date in the past, as that may reduce the number of years for which you can generate timestamps.

### Sequence resolver

[](#sequence-resolver)

In order to handle the generation of unique keys within the same millisecond, the service uses a sequence resolver. There are several to choose from, however they each have dependencies, such as Redis. You are free to use any of them, however the default option is a good choice, as it **doesn't** have any dependencies.

Usage
-----

[](#usage)

You can generate a Snowflake by resolving the service out of the container and calling its `id` method:

```
resolve('snowflake')->id(); // (string) "5585066784854016"
```

> **WARNING**: Do not create instances of the Snowflake service, as doing so risks generating matching keys / introducing collisions. Instead, always resolve the Snowflake singleton out of the container. You can also use the global helper method (see below).

Since this is a little cumbersome, the package also registers a global `snowflake()` helper method that you can use anywhere.

```
snowflake(); // (string) "5585066784854016"
```

Databases
---------

[](#databases)

If you want to use Snowflakes in your database e.g. for primary and foreign keys, then you'll need to perform a couple of steps.

First, modify your migrations so that they use the Snowflake migration methods e.g.

```
// Before
$table->id();
$table->foreignId('user_id');
$table->foreignIdFor(User::class);

// After
$table->snowflake()->primary();
$table->foreignSnowflake('user_id');
$table->foreignSnowflakeFor(User::class);
```

Here's an example:

```
class CreatePostsTable extends Migration
{
    public function up()
    {
        Schema::create('posts', function(Blueprint $table) {
            $table->snowflake()->primary();
            $table->foreignSnowflake('user_id')->constrained()->cascadeOnDelete();
            $table->string('title', 100);
            $table->timestamps();
        });
    }
}
```

Next, if you're using Eloquent, add the package's `Snowflakes` trait to your Eloquent models:

```
