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

Souuid Laravel Package

fab2s/souuid

fab2s/souuid generates sortable, time-ordered UUIDs for Laravel and PHP. These UUID-compatible IDs sort chronologically, improving database index locality and making them practical, efficient primary keys.

Deep Wiki
Context7

Getting Started

Install with Composer:

composer require fab2s/souuid

The package is deliberately small — one generator class plus (likely) a value object. Before writing any app code, open src/ and the README and confirm three things: the exact class/method name for generation (e.g. Souuid::generate()), the return type (raw string vs. an object with __toString()), and the byte layout of the produced UUID (how many bits are timestamp, random, counter). That last point determines whether you store it as char(36), char(32), or binary(16).

Minimal first use — generate an ordered ID and use it as a string primary key:

use Fab2s\Souuid\Souuid; // confirm name in src/

$id = (string) Souuid::generate();
// e.g. used as: $post->id = $id;

The first real use case is a new table where you want globally unique IDs that still sort chronologically — replacing $table->id() because you need IDs generated client-side (before insert), stable across shards, or safe to expose in URLs, while keeping insert locality good enough that your B-tree index doesn't fragment the way random UUIDv4 does.

If you just need to verify behaviour, generate a loop of 1,000 IDs and sort() them lexicographically alongside their creation order — they should match. That five-line sanity check tells you more about the package than the docs will.

Implementation Patterns

Model trait. Wrap generation in a reusable trait so every model behaves identically:

trait HasSouuid
{
    protected static function bootHasSouuid(): void
    {
        static::creating(function ($model) {
            $model->{$model->getKeyName()} ??= (string) Souuid::generate();
        });
    }

    public function getIncrementing(): bool { return false; }
    public function getKeyType(): string { return 'string'; }
}

The ??= matters: it lets you inject a pre-generated ID (useful for outbox/event-sourcing patterns and for tests) without the trait overwriting it.

Migration. Match the column to your storage choice. For string storage:

$table->char('id', 36)->primary();

If the package emits a compact/hex form, size the column to the actual output and keep the collation binary (->collation('utf8mb4_bin') on MySQL) so ordering is byte-wise and not case-folded. Ordering correctness is the whole point of the package — a case-insensitive collation can silently reorder IDs.

Route model binding works out of the box once getKeyType() returns string; no getRouteKeyName() override needed. Guard against enumeration by keeping authorization policies on the model rather than relying on ID opacity.

Relationships and foreign keys need the same column definition on the child table. If you're using foreignId() elsewhere in the codebase, use foreignUuid()-equivalent (char(36)) here instead, and add the index explicitly — Laravel won't infer it for a non-standard type.

Bulk inserts should call the generator once per row before the query builder runs; skip Eloquent events for throughput but retain ordering by generating in loop order (the sortable prefix does the rest).

Where to use it vs. Str::uuid(): use this package for anything that becomes a primary key or a sort key (posts, orders, ledger entries, job payload IDs you'll ORDER BY). Keep plain UUIDv4 for opaque tokens and correlation IDs where ordering is irrelevant — the ordered prefix leaks a coarse creation timestamp.

Gotchas and Tips

  • Don't mix generators. Laravel's built-in HasUuids/HasUniqueStringIds traits emit v4 (unordered) and will happily collide conceptually with this package's format. Pick one strategy per table and remove the other trait.
  • Collation is the silent killer. On MySQL, a default utf8mb4_unicode_ci column will sort hex UUIDs differently than you expect. Test ORDER BY id against insertion order after your first real migration, not in a unit test with SQLite.
  • Time leakage. Ordered UUIDs encode a timestamp prefix. If IDs are public (URLs, APIs), treat creation time as public knowledge; if that's unacceptable, this package is the wrong tool.
  • Same-millisecond generation. Check in src/ whether a monotonic counter or sub-millisecond precision is used. If not, generating many IDs in a tight loop within one millisecond may produce ties or non-monotonic output — benchmark your actual seeding/bulk-import path rather than assuming.
  • Clock skew across app servers. Ordering is only as good as your NTP. In multi-node deployments, IDs from a lagging node can appear "older." Usually harmless; matters if you rely on ID ordering for event sequencing.
  • Testing. Freeze time (Carbon setTestNow) if you assert on sortability, and never assert on exact ID values. Assert on format, length, and monotonicity instead.
  • JSON/serialization. If the generator returns an object rather than a string, add a cast or __toString() call site consistently — an object assigned to $model->id will fail char(36) inserts in confusing ways.
  • Extension points are thin by design. A ~one-class package won't offer much configuration. If you need a different byte layout (e.g. pure RFC 9562 UUIDv7), don't fork it — it's small enough to wrap: create your own IdGenerator interface, bind this package's implementation behind it, and swap later without touching models. That indirection is the highest-value thing you can add on day one.
  • Pin the version. With 12 stars and a single maintainer, lock the minor version in composer.json and add a test that asserts the ID format, so a silent format change on upgrade fails CI rather than production inserts.
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/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
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route