After three weeks of internal production validation without surfacing new bugs, scabarcas/laravel-permissions-redis ships its first stable 4.x release today. The codebase is identical to v4.0.0-beta.2. What changed is the commitment.
Why "no code changes" is the point
Stable doesn't mean "we added features." Stable means "we stop changing this." For three weeks I ran the beta in my own production workloads, expecting to find something — an edge case, a race condition, a missed invalidation. Nothing surfaced. The Redis contract test suite stayed green, the in-memory test fake matched the real Redis implementation, and the resolver behaved consistently across queue workers, Octane lifecycles, and multi-user-model setups.
When a beta runs long enough to stop producing new bug reports, the right thing is to stop labeling it beta. Three weeks felt like enough.
What you get if you're coming from v3 or earlier
The 4.x line has been collecting features since late March. If you haven't followed the beta releases, the short list:
-
Permission group metadata in Redis — group names survive the cache layer, so
PermissionResolver::getAllPermissions()returns enriched DTOs without falling back to the database. -
Multi-user-model support —
user_modelconfig accepts an array,Gate::beforeiterates over every configured type. -
Queue-backed warming —
WarmUserCacheJobplus--queueflag on warm commands. No more synchronous bulk warming under load. -
Guard parameter on every Blade directive —
@role('admin', 'api'),@permission('users.read', 'api'), all six directives. - LRU eviction + warm cooldown in the in-memory resolver caches. Long-running workers no longer grow unbounded.
- Atomic permission groups + Redis SCAN/HSET fixes — every mutation goes through MULTI/EXEC with consistent rollback semantics.
-
Migration command from Spatie —
php artisan permissions-redis:migrate-from-spatiereads your existingmodel_has_roles,model_has_permissions, androle_has_permissionstables and warms the equivalent Redis state in one shot.
The full audit-and-fix list is in the CHANGELOG.
Benchmark recap
For new readers — the differentiator stays the same:
| Workload | spatie p50 | redis p50 | Speedup |
|---|---|---|---|
| 1 authorization-heavy request | 13.76 ms | 1.26 ms | 10.94x |
| 10 iterations | 138.87 ms | 13.01 ms | 10.68x |
| 50 iterations | 696.73 ms | 63.79 ms | 10.92x |
Methodology: 5 warm-up runs + 30 measurement runs per scenario, GC reset between runs, predis client, SQLite + local Redis on Apple Silicon. Reproducible with one Docker command from the benchmark repo.
The 10x is not from a smarter algorithm — it's from doing less work. Spatie hydrates the user-to-roles-to-permissions chain on every request via Eloquent (4 DB queries per authorization-heavy endpoint). This package keeps that chain in Redis SETs and checks membership with SISMEMBER (O(1)). The DB query left is the users lookup itself.
Semver promise from here
Breaking changes will only ship in v5.0.0. The 4.x line gets:
- Non-breaking features
- Bug fixes
- Documentation improvements
Your composer.json constraint ^4.0 is safe to commit. If your test suite passes against v4.0.0, it will keep passing across every 4.x release.
When this package fits
It's not a Spatie replacement for every Laravel app. Use this when:
- You make many authorization checks per request (
hasPermissionTo,hasRole, Blade directives,Gate::allows) - Redis is already a production dependency (sessions, queues, cache)
- The 4 DB queries per request from Spatie's relation hydration show up in your traces
- You can absorb the eventual-consistency window of cache invalidation (events trigger rewarming within milliseconds, but it's not strictly synchronous)
Spatie remains the right default for the 95% of apps where authorization isn't on the hot path. Don't switch unless the latency math actually moves your numbers.
Install
composer require scabarcas/laravel-permissions-redis:^4.0
Full README with setup steps · Migrate from Spatie in one command · Benchmark methodology
Top comments (0)