spatie / laravel-permission

Associate users with roles and permissions
https://spatie.be/docs/laravel-permission
MIT License
12.14k stars 1.78k forks source link

Issues with boot() gate policy perf #295

Closed derekmd closed 7 years ago

derekmd commented 7 years ago

An issue has popped with this package reading large serialized binary from Redis for every request, making the Redis instance a bottleneck when a sudden blast of traffic comes in.

From looking at the service provider, the stack looks something like:

So even when the database query is avoided, the cache will unserialize the Collection of Permission models (with eager-loaded Role items on each instance.)

For over 220 permissions on production:

>>> strlen(serialize(Cache::get('spatie.permission.cache')))
=> 1833802

That's a fairly sizeable payload to fetch from Redis per request, making database query avoidance redundant as volume and frequency of traffic increases.

I have a feeling this app has more granular permissions than most so this a statie/laravel-permission use case outlier.

Does anyone have ideas how to improve performance?

morloderex commented 7 years ago

I have a question for you! Why is it that your redis cache does not hit all the time after the first request?

derekmd commented 7 years ago

It is hit.

The problem is a serialized Eloquent Collection object in the Redis store is a 1.8mb string. That is fetched from Redis by each request. With sufficient traffic, that becomes its own bottleneck as it affects Redis hits (even outside permissions) for all other requests.

I managed to lower the role/permission Collection memory footprint but 1.2mb is still excessive. I'll have to rethink the permission scheme as one-to-one Permission-to-route name isn't feasible for hundreds of routes.

freekmurze commented 7 years ago

Hi, I'm going to close this as your question is about an edge case problem where most users won't run into. If you find a good solution for this, I'd appreciate you posting it here, as it may prove helpful for users hitting the same problem.

derekmd commented 7 years ago

My quick fix has been to lower the memory footprint of the serialized Collection.

Eventually I want to: