firevel / model-random-id
Model random ID generator for Laravel.
This package is auto-updated.
Last update: 2026-05-19 22:17:05 UTC
README
A Laravel trait that automatically assigns a cryptographically random integer as the primary key of an Eloquent model. Ids fit in a MySQL BIGINT column and stay within JavaScript's Number.MAX_SAFE_INTEGER, so they round-trip safely through JSON and JS clients.
Why random BIGINT?
Distributed databases such as Cloud Spanner and Firestore suffer hotspots when ids are monotonically incrementing. UUIDs avoid that problem but are long, hurt index locality, and look ugly in URLs. A random BIGINT is the middle ground — fixed-width, numeric, indexable, and collision-resistant within the 2^53 range.
Installation
Install the package via Composer:
composer require firevel/model-random-id
Usage
Make the primary key a BIGINT in your migration:
Schema::create('posts', function (Blueprint $table) { $table->bigInteger('id')->primary(); // ... other columns });
Add the trait to your model:
use Firevel\ModelRandomId\HasRandomId; class Post extends Model { use HasRandomId; }
That's it. The trait disables auto-increment for you and assigns a random id on saving if the key column is empty.
$post = Post::create(['title' => 'Hello']); $post->id; // e.g. 7193428815320495
Using a non-primary-key column
If you want to populate a column other than the primary key, set $randomIdKeyName:
class Invite extends Model { use HasRandomId; public $randomIdKeyName = 'token'; }
Customizing the range
The trait exposes two properties you can override per-model:
| Property | Default | Meaning |
|---|---|---|
$minimumRandomId |
3656158440062976 |
Lower bound. Equals "10000000000" parsed as base-36, which guarantees every id is at least 11 characters when rendered in base-36. |
$maximumRandomId |
9007199254740991 |
Upper bound. Equals Number.MAX_SAFE_INTEGER (2^53 − 1) and fits in MySQL BIGINT. |
class Order extends Model { use HasRandomId; public $minimumRandomId = 1000000000; public $maximumRandomId = 9999999999; }
You can also override generateRandomInteger() if you need a different generation strategy entirely.
How it works
bootHasRandomId()registers asavinglistener so the id is assigned just before the row is written.initializeHasRandomId()runs on every model instance and sets$incrementing = false.generateRandomInteger()uses PHP'srandom_int(), which draws from the OS CSPRNG.
Limitations
Random number generation reduces the risk of ID collisions but is not immune to them. The more rows you insert, the higher the chance of a collision due to the birthday paradox — random sampling within a finite range (here, 2^53) makes overlap increasingly likely as the table grows. For use cases involving tens of millions of rows or extremely high throughput, consider pre-generating a pool of unique ids and handing them out, or wrapping inserts in retry-on-duplicate-key logic.
License
MIT — see LICENSE.