C
C#2w ago
Juicy

API performance acting weird

I dont get why sometimes when im calling my endpoint the api is taking 20 ms but then bam the occasional 500ms or even 7600ms up to ive seen even 9000ms response for the same endpoint, just by calling the same endpoint with a few second delays. Is it something im doing wrong code-wise? For example this endpoint:
[HttpGet("{productId:guid}/all")]
public async Task<IActionResult> GetLicensesOnProduct(Guid productId)
{
var licenses = await licenseService.GetLicensesOnProduct(productId);
var response = licenses.Select(license => new LicenseResponse(
license.Id,
license.Key,
license.Duration,
license.Note,
license.DurationUnit,
license.Role,
license.CreatedByInternalUserId,
license.UserId,
license.CreatedOnUtc,
license.RedeemedOnUtc,
license.ExpirationDate,
license.Type,
license.State));

return Ok(response);
}
[HttpGet("{productId:guid}/all")]
public async Task<IActionResult> GetLicensesOnProduct(Guid productId)
{
var licenses = await licenseService.GetLicensesOnProduct(productId);
var response = licenses.Select(license => new LicenseResponse(
license.Id,
license.Key,
license.Duration,
license.Note,
license.DurationUnit,
license.Role,
license.CreatedByInternalUserId,
license.UserId,
license.CreatedOnUtc,
license.RedeemedOnUtc,
license.ExpirationDate,
license.Type,
license.State));

return Ok(response);
}
public async Task<IEnumerable<License>> GetLicensesOnProduct(Guid productId)
{
var product = await productRepository.GetByIdAsync(productId);
if (product is null)
{
throw new ProductNotFoundException(productId);
}

var licenses = await licenseRepository.GetAllAsync(productId);
return licenses;
}
public async Task<IEnumerable<License>> GetLicensesOnProduct(Guid productId)
{
var product = await productRepository.GetByIdAsync(productId);
if (product is null)
{
throw new ProductNotFoundException(productId);
}

var licenses = await licenseRepository.GetAllAsync(productId);
return licenses;
}
public async Task<IEnumerable<License>> GetAllAsync(Guid productId, CancellationToken cancellationToken = default)
{
return await dbContext.Set<License>()
.Where(l => l.ProductId == productId)
.ToListAsync(cancellationToken);
}
public async Task<IEnumerable<License>> GetAllAsync(Guid productId, CancellationToken cancellationToken = default)
{
return await dbContext.Set<License>()
.Where(l => l.ProductId == productId)
.ToListAsync(cancellationToken);
}
No description
61 Replies
Angius
Angius2w ago
Wait, you're fetching a whole-ass product, just to check if it exists, then you fetch a bunch of licenses with that product ID...?
Juicy
JuicyOP2w ago
yeah is that stupid xD?
Angius
Angius2w ago
Why not just skip the check step? If the product doesn't exist, no licenses will be found, no? Besides, .AnyAsync() will check just for the existence Instead of loading the whole-ass object
Juicy
JuicyOP2w ago
well the way I wrote my api is that I could have multiple "products" that have their own set of users and licenses so I should only get the licenses for that product
Angius
Angius2w ago
But if a product does not exist (you get a null) how can a license that references it exist? It cannot
Juicy
JuicyOP2w ago
oh yeah thats true lol
Angius
Angius2w ago
So you'll get an empty list No need for that check
Juicy
JuicyOP2w ago
fair I see what you mean now but could that really be the cause for it performing so bad?
Angius
Angius2w ago
Also, you seem to be fetching everything about the entity from the database, and only then do you pick the props you need Probably not the cause
Juicy
JuicyOP2w ago
soo basically do the select inside the GetAllAsync function
Angius
Angius2w ago
But the faster you recognize how idiotic of an idea the repository pattern on top of EF is, the better :KEKW: Whoever is pushing it may step on a LEGO with every step May his socks be always wet
Juicy
JuicyOP2w ago
hahah ive started to wonder about that actually
Angius
Angius2w ago
At most you want a service
Juicy
JuicyOP2w ago
do you have any suggestion what to follow instead?
Angius
Angius2w ago
Repositories are useless
Juicy
JuicyOP2w ago
just do the ef stuff inside my service?
Angius
Angius2w ago
EF is a repository Ye
Juicy
JuicyOP2w ago
alright but its weird according to the seq logs there are no other requests happening at the same time just me spamming the one endpoint a bit first I was thinking if there was any other calls blocking it or something.. but makes no sense to me why it would shoot up like 9000ms
Angius
Angius2w ago
You'd have to check with the profiler
Juicy
JuicyOP2w ago
I even expanded the server to 16 cores and 64 gb ram i see
Angius
Angius2w ago
Nothing here — even with the repos and all — suggests the request should take any more than, like, 200ms
Juicy
JuicyOP2w ago
could it be a server issue or something idk
Angius
Angius2w ago
Unless the amount of data you're loading is massive
Juicy
JuicyOP2w ago
Im not even sure how to profile when its on the server
Angius
Angius2w ago
And you only trim it to something sensible after fetching
Juicy
JuicyOP2w ago
i just use a windows server
Angius
Angius2w ago
So the issue doesn't happen locally?
Juicy
JuicyOP2w ago
no it doesnt actually there its like constant 20ms
Angius
Angius2w ago
Any reason to use Windows Server and pay out of the wazoo instead of just getting a random $5 Linux VPS?
Juicy
JuicyOP2w ago
but then again ive not rly tested with more than 20 licenses locally.. but on the server its not even a lot its like 100-200 licenses and performing like this uhhh just cause I have knowledge about how to use IIS cause we use IIS at work and no knowledge how to set up on linux
Angius
Angius2w ago
Try filling the local db a bit and see if you can repro the issue locally
Juicy
JuicyOP2w ago
okay ill test it
Angius
Angius2w ago
Setting it up on Linux shouldn't be hard if you just dockerize it
Juicy
JuicyOP2w ago
yea i pay like €170 for the server per 4 months lol
Angius
Angius2w ago
Or even just rawdog it and run the .dll on bare Linux, even without any reverse proxy
Juicy
JuicyOP2w ago
you got any recommendations for providers?
Angius
Angius2w ago
$vps
Juicy
JuicyOP2w ago
ah ty well i use one that is close to hetzner called avoro
Angius
Angius2w ago
I like OVH and Hetzner, personally
Juicy
JuicyOP2w ago
ill do some research on it appreciate it sooo lets say i decide to remake this shit from scratch do I use EF still or is dapper even faster and no repository pattern that time
Angius
Angius2w ago
They're about the same nowadays
Juicy
JuicyOP2w ago
ah ok i just wish there was like an easy "best practice" follow this and it will be good lol
Angius
Angius2w ago
Oh boy, best practices is another can of worms 😄
Juicy
JuicyOP2w ago
on youtube the asp.net guys ive seen on there just talk about repositories thats why i went for it
Angius
Angius2w ago
They all do lmao My theory is they learn from similar YT videos and just keep propagating the repo agenda
Juicy
JuicyOP2w ago
LOL
Angius
Angius2w ago
If you were to ask about best practices, particularly on this server, you'll no doubt be pointed to $vsa
Juicy
JuicyOP2w ago
ima go through all of that thanks man
Juicy
JuicyOP2w ago
that is super useful
Angius
Angius2w ago
But, again, not a gospel
Juicy
JuicyOP2w ago
wait I have one more question
Angius
Angius2w ago
Shoot
Juicy
JuicyOP2w ago
So in my api I have a feature thats kinda like a program builder...where it compiles something specific to the user and sends it back this takes like 30 seconds per build should I host this on a 2nd server rn im doing it on the same like my api is just a tool for authentication and mangaging your software so I was thinking how to deal with the builds taking so long time, I dont want it hogging resources
Angius
Angius2w ago
Right... I guess you could do that, yeah, to have a guaranteed amount of resources for the API itself
Juicy
JuicyOP2w ago
yeaa
Angius
Angius2w ago
Could delegate it to some sort of a CI/CD server maybe, too So you pay for the actual usage, instead of having to shell out however much for a server that might just be sitting idle 90% of the time
Juicy
JuicyOP2w ago
oh yea true, those requests dont happen often yeah im definitely gonna be rewriting things watching one of those videos on that VSA structure, i love it its way way cleaner than what im doing rn
Lyrcaxis
Lyrcaxis2w ago
In case it wasn’t already brought up, only measure performance in release when it comes to ASP. NET Core

Did you find this page helpful?