After implementing IdentityServer4 in our company, we try to change some customization for our needs.
I was horrified by the quality of the code that is hidden inside - I guess the target of development did not even related to performance and minimize heap allocations.
Example: 30-50 concurrent token refresh requests (hybrid flow) can fully utilize 8 CPU cores (with cached results of GetProfileAsync, IsActiveAsync).
Next, i cache Jwt token by tokenType for skipping token creation again and again. and i guess, that creating token signature is most hot operation, but again we see 8-core utilization.
Especially in RequestValidators, PersistentGrant serizalizations, e.t.c.
It is possible to use IdentityServer for thousands users? We need to make server cluster especially for it?
Please, implement latest features, that helps to avoid heap allocations - ValueTasks, Memory, Span, Pipes. If not possible - try to skip Linq in hottest places or do some optimizations.
Now, we try to minimize CPU utilization for token refreshing, but it is so hard in current codebase.
Maybe start using benchmarkDotNet, or something stress testing tools?
Thank you for the product, but it's time to think about optimization.
Thank you for the product, but it's time to think about optimization.
As you know, this is an open source project - if you want to work on performance improvements, please open a PR/issue to discuss those changes.
At my side, identity server behaves very well with all my users.
If you face performance issues even with a thousands users, that means something is going wrong in your custom claim generation unless you use the code flow.
I know this may not be an actual solution for you, but if you considered switching to an implicit flow I'm totally sure you would not face such issues. With the implicit flow, the token is generated only when the user logs in. With the code flow, the token is requested to the identity server at any call to the api of the resource server. So any call to the api server may involve a new token generation, and this is a pb for the id server if you have a lot of concurrent users indeed.
The only goal of the code flow compared to the implicit flow is the fact that user could see what is in the token. If your token does not contain any sensitive information or any information the user shouldn't see, don't bother with the code flow because this will overload your authentication server. To make it simple, if you token contains user name, email address or roles, there is no pb with the implicit flow.
Otherwise indeed, if you really need the code flow with this big amount of concurrent users, maybe a native system like adfs, of even a large scale cloud based system shall be considered. But then, you will lose control over the claim generation.
@paillave We control all requests for extrernal storages (Grant, Profile) and tune it for our cases.
High CPU utilization issue related to https://github.com/aspnet/KestrelHttpServer/issues/2694
New Kestrel sockets transport increase CPU usage up to 4000% at Linux environment.
But perfromance of DefaultGrantStore is poor. For our cases we implement custom RefreshTokenStore without additional JSON serialization. It's increase token refreshing RPS x2.
Big thanks to core team for extensibility design.
@ZOXEXIVO Thanks for the info! I'm willing to use it on another project that will run on a linux server!
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
As you know, this is an open source project - if you want to work on performance improvements, please open a PR/issue to discuss those changes.