User Storage SPI - Latency on login

We have setup a User Storage SPI in order to get user data from an external API.
The problem is that we are facing latency on login to Keycloak. The user must wait about 5 sec on the login.
This latency is caused by the combination of:
• brute force detection on
• cluster mode
• cache-policy: no-cache
If we set brute force off, or cache on then login time is less than a second.
The reason behind not using cache is that we want the user data to be in sync with users from the external API. When turning on cache, updated user data (email or changed role etc.) is not updated in Keycloak.
Evict daily” will be too long to wait for user changes.

So do you have any suggestions for solving this latency?

Thanks!
Kjetil

Turn cache back on for starters and redesign your user storage SPI.
You only need to invalidate a user when data has been changed so you could start with that.
From what I understand you import user data and roles from an external API? Move as much as you can to Keycloak itself.

Thanks for the answer!

Your right, we do import the user data and roles, we need that for back word compatibility.

How do I know when the user has been changed when the SPI is not calling the API?

You could implement this in a lot of ways depending on your current architecture and number of users.
Here are a few possibilities.

  • don’t use a storage SPI and retrieve the user data & roles directly from your API in the application you want it, merge roles there until you have migrated everything to Keycloak.
  • evict a user through the Keycloak REST API when something changes on your API’s side, check in your storage SPI if a user is in cache and use that if not retrieve it.
  • create a shared cache between your storage SPI and your API and set a flag for a user when something has changed, if no flag is set you don’t need to retrieve anything and can use cached user
  • set a user attribute (flag) through the Keycloak REST API when something changes on your API’s side, in your storage SPI check if the user needs to be updated

Depending on your current architecture you can go a lot of ways.

1 Like