{"id":22083235,"url":"https://github.com/calebdw/laraflake","last_synced_at":"2025-07-24T16:30:58.583Z","repository":{"id":249210334,"uuid":"829604085","full_name":"calebdw/laraflake","owner":"calebdw","description":"❄️ Generate X/Twitter Snowflake identifiers in Laravel","archived":false,"fork":false,"pushed_at":"2024-08-02T03:57:29.000Z","size":263,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-11-24T19:46:13.342Z","etag":null,"topics":["distributed-id-generator","laravel","snowflake","snowflake-id","twitter","twitter-snowflake","twitter-snowflake-algorithm","unique-id","unique-id-generator"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/calebdw.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"calebdw"}},"created_at":"2024-07-16T19:11:56.000Z","updated_at":"2024-08-02T03:57:32.000Z","dependencies_parsed_at":"2024-07-22T00:43:29.009Z","dependency_job_id":null,"html_url":"https://github.com/calebdw/laraflake","commit_stats":null,"previous_names":["calebdw/laraflake"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/calebdw%2Flaraflake","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/calebdw%2Flaraflake/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/calebdw%2Flaraflake/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/calebdw%2Flaraflake/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/calebdw","download_url":"https://codeload.github.com/calebdw/laraflake/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227456782,"owners_count":17777943,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["distributed-id-generator","laravel","snowflake","snowflake-id","twitter","twitter-snowflake","twitter-snowflake-algorithm","unique-id","unique-id-generator"],"created_at":"2024-12-01T00:12:07.149Z","updated_at":"2024-12-01T00:12:07.954Z","avatar_url":"https://github.com/calebdw.png","language":"PHP","funding_links":["https://github.com/sponsors/calebdw"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cp\u003e\n    \u003cimg src=\"/art/laraflake.webp\" alt=\"Laraflake\" width=\"40%\"\u003e\n  \u003c/p\u003e\n  \u003cp\u003eGenerate X/Twitter \u003ca href=\"https://en.wikipedia.org/wiki/Snowflake_ID\"\u003eSnowflake identifiers\u003c/a\u003e in Laravel.\u003c/p\u003e\n  \u003cp\u003e\n    \u003ca href=\"https://github.com/calebdw/laraflake/actions/workflows/tests.yml\"\u003e\u003cimg src=\"https://github.com/calebdw/laraflake/actions/workflows/tests.yml/badge.svg\" alt=\"Test Results\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://codecov.io/github/calebdw/laraflake\"\u003e\u003cimg src=\"https://codecov.io/github/calebdw/laraflake/graph/badge.svg?token=RPLQKWDM5G\" alt=\"Code Coverage\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/calebdw/laraflake\"\u003e\u003cimg src=\"https://img.shields.io/github/license/calebdw/laraflake\" alt=\"License\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://packagist.org/packages/calebdw/laraflake\"\u003e\u003cimg src=\"https://img.shields.io/packagist/v/calebdw/laraflake.svg\" alt=\"Packagist Version\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://packagist.org/packages/calebdw/laraflake\"\u003e\u003cimg src=\"https://img.shields.io/packagist/dt/calebdw/laraflake.svg\" alt=\"Total Downloads\"\u003e\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\n## What are Snowflakes?\n\nSnowflakes are a form of unique identifier [devised by X/Twitter](https://blog.x.com/engineering/en_us/a/2010/announcing-snowflake) and are used by many companies, including Instagram and Discord, to generate unique IDs for their entities.\n\nSome of the benefits of using Snowflakes (over alternatives such as UUID/ULID) include:\n\n- **Timestamp Component:** Extract creation time directly from the ID.\n- **Uniqueness Across Distributed Systems:** Ensures unique IDs without coordination.\n- **Orderability:** Roughly ordered by creation time for easy sorting.\n- **Compactness:** 64-bit size, more compact than 128-bit UUIDs.\n- **Performance:** Faster and less resource-intensive generation.\n- **Configurability:** Flexible bit allocation for specific needs.\n- **Storage Efficiency:** More efficient storage compared to larger identifiers.\n- **Database Indexing:** Faster indexing and query performance.\n- **Human Readability:** More compact and readable than longer identifiers.\n\n## Installation\n\nFirst pull in the package using Composer:\n\n```bash\ncomposer require calebdw/laraflake\n```\n\nAnd then publish the package's configuration file:\n\n```bash\nphp artisan vendor:publish --provider=\"CalebDW\\Laraflake\\ServiceProvider\"\n```\n\n## Configuration\n\n### Snowflake Type\n\nThe Snowflake type determines the class used to generate Snowflakes.\n\nThe default Snowflake type is `Godruoyi\\Snowflake\\Snowflake` which uses 41 bits for the epoch, 5 bits for the data center ID, 5 bits for the worker ID, and 12 bits for the sequence.\nThis allows for up to `1024` workers and `4096` unique IDs per worker per millisecond.\n\nYou can change the Snowflake type to `Godruoyi\\Snowflake\\Sonyflake` which uses 39 bits for the epoch, 16 bits for the machine ID, and 8 bits for the sequence.\nThis allows for up to `65535` machines and `256` unique IDs per worker per *10 milliseconds*.\n\n### Epoch\n\nThe timestamp encoded in the Snowflake is the difference between the time of creation and a given starting epoch/timestamp.\nSnowflakes use 41 bits and can generate IDs for up to 69 years past the given epoch.\nSonyflakes use 39 bits and can generate IDs for up to 174 years past the given epoch.\n\nIn most cases you should set this value to the current date using a format of `YYYY-MM-DD`.\n\n\u003e **Note**:\n\u003e Future dates will throw an error and you should avoid using a date far in the past (such as the Unix epoch `1970-01-01`)\nas that may reduce the number of years for which you can generate timestamps.\n\n### Data Center \u0026 Worker IDs\n\n\u003e **Note**: This is only used for the `Snowflake` type.\n\nYou can set the data center and worker IDs that the application should use when generating Snowflakes.\nThese are used to ensure that each worker generates unique Snowflakes and can range from `0` to `31` (up to `1024` unique workers).\n\n### Machine ID\n\n\u003e **Note**: This is only used for the `Sonyflake` type.\n\nYou can set the machine ID that the application should use when generating Sonyflakes.\nThis is used to ensure that each machine generates unique Sonyflakes and can range from `0` to `65535`.\n\n## Usage\n\n\u003e **WARNING**: Do not create new instances of the Snowflake generator (as this could cause collisions), always use the Snowflake singleton from the container.\n\nYou can generate a Snowflake by resolving the singleton from the container and calling its `id` method:\n\n```php\nuse Godruoyi\\Snowflake\\Snowflake;\n\nresolve('snowflake')-\u003eid();      // (string) \"5585066784854016\"\nresolve(Snowflake::class)-\u003eid(); // (string) \"5585066784854016\"\n```\n\nThis package also provides a `snowflake` helper function, a `Snowflake` facade, and a `Str::snowflakeId` macro for convenience:\n\n```php\nuse CalebDW\\Laraflake\\Facades\\Snowflake;\nuse Illuminate\\Support\\Str;\n\nsnowflake()-\u003eid();  // (string) \"5585066784854016\"\nSnowflake::id();    // (string) \"5585066784854016\"\nStr::snowflakeId(); // (string) \"5585066784854016\"\n```\n\n### Eloquent Integration\n\n#### Migrations\n\nThis package provides a set of migration macros to make it easier to work with Snowflakes in your database schema.\n\nHere's an example:\n\n```php\nreturn new class extends Migration\n{\n    public function up(): void\n    {\n        Schema::create('comments', function(Blueprint $table) {\n            $table-\u003esnowflake()-\u003eprimary();\n            $table-\u003eforeignSnowflake('user_id')-\u003econstrained()-\u003ecascadeOnDelete();\n            $table-\u003eforeignSnowflakeFor(Post::class)-\u003econstrained();\n        });\n    }\n}\n```\n\n#### Models\n\nNext, add the package's `HasSnowflakes` trait to your Eloquent models:\n\n```php\nnamespace App\\Models;\n\nuse CalebDW\\Laraflake\\Concerns\\HasSnowflakes;\n\nclass Post extends Model\n{\n    use HasSnowflakes;\n}\n```\n\nThe trait provides several features for the model's Snowflake columns:\n\n- the generation of Snowflakes for new records\n- route model binding\n- automatic casting from database integers to strings which prevents truncation in languages that do not support 64-bit integers (such as JavaScript).\n\nBy default, the trait assumes that the model's primary key is a Snowflake.\nIf you have other unique columns that should be treated as Snowflakes, you can override the `uniqueIds` method to specify them:\n\n```php\n\nnamespace App\\Models;\n\nuse CalebDW\\Laraflake\\Concerns\\HasSnowflakes;\n\nclass Post extends Model\n{\n    use HasSnowflakes;\n\n    /** @inheritDoc */\n    public function uniqueIds(): array\n    {\n        return [$this-\u003egetKeyName(), 'slug'];\n    }\n}\n```\n\nIf necessary, you can explicitly cast the model's Snowflake columns using the `AsSnowflake` cast:\n\n```php\nnamespace App\\Models;\n\nuse CalebDW\\Laraflake\\Casts\\AsSnowflake;\nuse CalebDW\\Laraflake\\Concerns\\HasSnowflakes;\n\nclass Post extends Model\n{\n    use HasSnowflakes;\n\n    protected $casts = [\n        'id'      =\u003e AsSnowflake::class,\n        'user_id' =\u003e AsSnowflake::class,\n    ];\n}\n```\n\n### Validation\n\nIf you need to validate Snowflakes in your application, you can use the `Snowflake` rule or the `Rule::snowflake` macro provided by this package:\n\n```php\nuse CalebDW\\Laraflake\\Rules\\Snowflake;\nuse Illuminate\\Validation\\Rule;\n\n$request-\u003evalidate([\n    'id'      =\u003e ['required', new Snowflake()],\n    'user_id' =\u003e ['required', Rule::snowflake()],\n]);\n```\n\nYou can also just use the `Str::isSnowflake` macro to check if a value is a valid Snowflake:\n\n```php\nuse Illuminate\\Support\\Str;\n\nStr::isSnowflake('5585066784854016'); // (bool) true\n```\n\n### Sequence Resolver\n\nThe sequence resolver is responsible for generating the sequence component of the Snowflake\nto ensure that numbers generated on the same machine within the same millisecond are unique.\n\nBy default, if the application has a cache, then it uses the `LaravelSequenceResolver`\nwhich uses the Laravel cache to store the last sequence number.\nIf the application does not have a cache, then it uses the `RandomSequenceResolver` which\nhas no dependencies **but is not concurrency-safe**.\n\nYou can override the sequence resolver by binding your own implementation in a service provider:\n\n```php\nuse Godruoyi\\Snowflake\\SequenceResolver;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass AppServiceProvider extends ServiceProvider\n{\n    public function register(): void\n    {\n        $this-\u003eapp-\u003ebind(SequenceResolver::class, function() {\n            return new MySequenceResolver();\n        });\n    }\n}\n```\n\nPlease see [godruoyi/php-snowflake](https://github.com/godruoyi/php-snowflake) for more information on the available sequence resolvers and their dependencies.\n\n## Contributing\n\nThank you for considering contributing! You can read the contribution guide [here](CONTRIBUTING.md).\n\n## License\n\nLaraflake is open-sourced software licensed under the [MIT license](LICENSE).\n\n## Acknowledgments\n\nDerived from [caneara/snowflake](https://github.com/caneara/snowflake) which is no longer maintained.\nThe actual Snowflake generation is handled by the excellent [godruoyi/php-snowflake](https://github.com/godruoyi/php-snowflake) library.\n\n## Alternatives\n\n- [caneara/snowflake](https://github.com/caneara/snowflake)\n- [kra8/laravel-snowflake](https://github.com/kra8/laravel-snowflake)\n- [dive-be/laravel-snowflake](https://github.com/dive-be/laravel-snowflake)\n- [hafael/laraflake](https://github.com/hafael/laraflake)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcalebdw%2Flaraflake","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcalebdw%2Flaraflake","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcalebdw%2Flaraflake/lists"}