Distributed Locking
Your ASP.NET Core API runs on multiple instances behind a load balancer. Two different instances each handle a request claiming the same shared resource, a delivery driver, say, and each does it the same way: check whether it's free, then update it as assigned, as two separate steps.
Under load, both instances can read the resource as free within milliseconds of each other, before either one finishes the update. The same driver ends up assigned to two different requests at once.
A check-then-act race across multiple servers hands out the same thing twice. That's exactly what distributed locking prevents.
Distributed locking gives only one instance a real claim: use a single atomic command in Redis, such as SET key value NX EX seconds, to attempt it. Only the instance whose SET actually succeeds owns the resource, every other instance's SET fails immediately and moves on, and a short expiry on the claim means a crashed instance's claim releases on its own instead of locking the resource forever.
Use: StackExchange.Redis, RedLock.net
One atomic claim, checked by every instance against the same place, replaces a check-then-act race with a single winner.
A ticket counter hands out a single numbered token for the next available window. Two customers reaching for it at the same time does not create two number sevens, only one hand actually closes around the token, and the other customer sees it is already gone and waits for the next one.
Nobody needs to ask the whole line to slow down. The token itself decides who goes next.
Whoever grabs it first gets it; everyone else immediately knows to look elsewhere.