Why Build a UUIDv7 Generator in Pure PHP?
Most PHP projects use ramsey/uuid, but:
- It’s heavy if you’re only using UUIDv7
- Requires Composer and dependencies
- Not ideal for pure or minimal PHP projects
This guide shows how to build a fast, sequential, and cryptographically safe UUIDv7 generator in PHP without any dependencies.
What Is UUIDv7?
UUIDv7 is part of the new UUID draft specification. It offers:
- Time-ordering (great for database indexing)
- Collision safety
- Better sort performance than UUIDv4
- A 48-bit millisecond timestamp + 80 bits randomness
Final UUIDv7 Generator in PHP
function uuid7(): string
{
static $lastUnixMs = null;
static $sequence = 0;
// get current time in milliseconds
$unixMs = (int)(microtime(true) * 1000);
// compensate for same-ms collisions
if ($unixMs === $lastUnixMs) {
$sequence++;
$sequence &= 0x3FFF; // keep within the 14-bit sequence range
if ($sequence === 0) {
$unixMs++; // bump time slightly to avoid collision
}
} else {
$sequence = random_int(0, 0x3FFF); // random start per ms
$lastUnixMs = $unixMs;
}
$time_high = ($unixMs >> 16) & 0xFFFFFFFF;
$time_low = $unixMs & 0xFFFF;
$time_hi_and_version = ($time_low & 0x0FFF) | (0x7 << 12);
$clock_seq_hi_and_reserved = ($sequence & 0x3FFF) | 0x8000;
// generate 6 bytes (48 bits) of randomness
$randBytes = random_bytes(6);
$randHex = bin2hex($randBytes);
return sprintf(
'%08x-%04x-%04x-%04x-%012s',
$time_high,
$time_low,
$time_hi_and_version,
$clock_seq_hi_and_reserved,
$randHex
);
}
How It Works
- 48-bit Timestamp →
microtime(true) * 1000
gives milliseconds since Unix epoch - 14-bit Sequence → prevents collisions within the same millisecond
- 80 bits of randomness → secure and unique
- UUIDv7 Version and Variant bits → correctly set via bit masking
Pros
- No Composer or Dependencies
- Time-ordered for index efficiency
- Safe and fast random bytes
- Collisions handled even at high throughput
- Compatible with modern UUIDv7 spec
Cons
- Not interoperable with ramsey/uuid object model
- Requires PHP 7.0+ for
random_bytes()
, PHP 7.1+ recommended
Use Cases
- Laravel or PHP apps needing sequential UUIDs for database IDs
- APIs that require consistent ordering without timestamp fields
- Microservices or pure-PHP tools where minimal dependencies are ideal
Bonus: Laravel Integration
You can register it like this in AppServiceProvider
:
use Illuminate\Support\Str;
Str::macro('uuid7', function () {
return uuid7();
});
Then use like:
Str::uuid7();
Final Thoughts
If you want the fastest, simplest, and spec-compliant UUIDv7 generator — this is it. You can now remove ramsey/uuid
and have full control, minimal overhead, and predictable ordering.