firevel/model-random-id

Model random ID generator for Laravel.

Maintainers

Package info

github.com/firevel/model-random-id

pkg:composer/firevel/model-random-id

Statistics

Installs: 9 861

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

0.0.4 2026-05-19 22:14 UTC

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 a saving listener so the id is assigned just before the row is written.
  • initializeHasRandomId() runs on every model instance and sets $incrementing = false.
  • generateRandomInteger() uses PHP's random_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.