okta / okta-sdk-dotnet

A .NET SDK for interacting with the Okta management API, enabling server-side code to manage Okta users, groups, applications, and more.
Other
160 stars 100 forks source link

ListUsers method is really slow (4-6 seconds) #536

Closed oyemini-fortifieddata closed 2 years ago

oyemini-fortifieddata commented 2 years ago

Current behavior

The ListUsers method takes a lot of time (4-6 seconds), I'm caching it after the first time but still, am I doing something wrong here? I would like to fetch a a list by the users emails, I also tried to remove the Where condition and had no effect.

IUser[] oktaUsers = await _oktaClient.Users.ListUsers().Where(u=>missingFromCacheList.Contains(u.Profile.Email)).ToArrayAsync();

Expected behavior

ListUsers should be returned in decent time (2-3 seconds in my opinion)

andriizhegurov-okta commented 2 years ago

Hi @oyemini-fortifieddata, your code seems correct. Could you check if this is a network/server issue by using Fiddler while running the code? Also did you try to run the ListUsers request directly from Postman as it's said in User API?

oyemini-fortifieddata commented 2 years ago

Hi @oyemini-fortifieddata, your code seems correct. Could you check if this is a network/server issue by using Fiddler while running the code? Also did you try to run the ListUsers request directly from Postman as it's said in User API?

Found the issue on Fiddler, it seems that for 1 request on my code there are multiple requests to Okta API. there is a query string named limit=10, that is the default paging. I thought I'll change it to the number of items in my missingFromCacheList list in order to work correctly like so:

IUser[] oktaUsers = await _oktaClient.Users.ListUsers(limit: missingFromCacheList.Count).Where(u=> missingFromCacheList.Contains(u.Profile.Email)).ToArrayAsync();

But it still not working as expected as it is fetches all users from the Okta API and does the filter locally. why? It forces me to define an arbitrary number like 100 on the limit property in order to minimize number of calls.

image

image

laura-rodriguez commented 2 years ago

Hi @oyemini-fortifieddata, You should use the parameters provided by the API to optimize your query. Please take a look at the List Users documentation here. Let us know if this helps.

oyemini-fortifieddata commented 2 years ago

Thanks Laura, but I haven't found any option to send a list for users to the search. the search option only allows me to search like so:

"https://${yourOktaDomain}/api/v1/users?q=eric&limit=1"

what if I want or example to also add Joe to the search?

laura-rodriguez commented 2 years ago

Hi @oyemini-fortifieddata ,

Thanks for your patience. Based on the Users APi doc I believe you can do something like this: filter=(firstName Eq "john" or firstName Eq "Joe" ...).

Let me know if this helps.

danverde commented 2 years ago

I've been trying to speed up my list users call for a while now. After running across this issue I ran some benchmarks against the following code with various page sizes:

// returns 124 users
await _oktaClient.Users.ListUsers(null, null, limit, null, @$"profile.organization_id eq ""{_organization.Code}""")
            .ToListAsync()
BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19042.1526 (20H2/October2020Update)
Intel Core i9-10885H CPU 2.40GHz, 1 CPU, 16 logical and 8 physical cores
.NET SDK=5.0.405
  [Host]     : .NET Core 3.1.22 (CoreCLR 4.700.21.56803, CoreFX 4.700.21.57101), X64 RyuJIT
  DefaultJob : .NET Core 3.1.22 (CoreCLR 4.700.21.56803, CoreFX 4.700.21.57101), X64 RyuJIT

|            Method |       Mean |   StdDev |
|------------------ |-----------:|---------:|
|  GetUsers_limit10 | 2,864.7 ms | 266.3 ms |
|  GetUsers_limit50 | 1,099.6 ms | 130.9 ms |
| GetUsers_limit100 | 1,026.7 ms | 151.1 ms |
| GetUsers_limit125 |   839.1 ms | 111.3 ms |

It seems counter-intuitive to me that increasing the page size improves performance and the best performance was achieved when no pagination was required (I imagine you can get a large enough payload where this wouldn't be the case, but I don't have that many test users). Are the paginated calls not made asynchronously?

In addition, this article puts the default page size for listing users at 25, not 10: https://support.okta.com/help/s/article/Pagination-Overview?language=en_US

oyemini-fortifieddata commented 2 years ago

Thanks for all your responses, u can close this issue from my side.