Atomic Counters

1. What exactly is Atomic Counters?

Your ASP.NET Core API enforces a limit on a shared resource, how many of something can be active at once. It reads the current count from a Redis key, checks whether it's under the limit, and only then writes the count back up by one. That's two separate round trips to Redis, a read and a write.

So what happens when two requests hit this at the same time? Both can read the count while it's still below the limit, before either one has written anything back. Both pass the check. Both write the count up by one. Your final count ends up higher than the limit allows.

Reading and writing as two separate steps lets two requests both pass the same check before either one updates the count. That's exactly what an atomic counter prevents.

2. How would you fix it in .NET/Azure?

An atomic counter collapses that into one step: replace the separate read and write with Redis's INCR command, which increases the value and returns the new result in a single atomic operation. Check the returned value against the limit immediately after incrementing, and if it's over, decrement the count back down and reject the request, otherwise let it proceed.

Use: StackExchange.Redis (StringIncrementAsync)

Increment and check as one atomic step, so two requests can never both act on the same stale count.

3. How can you visualize it in everyday terms?

A turnstile at a venue only lets one person through at a time, and its counter increases as part of that same motion, not as a separate step afterward.

Two people can't both look at the counter, see it's below the limit, and squeeze through at once; the turnstile only ever lets through as many people as its counter allows, one physical click at a time.

Counting and letting through happen as one motion, not two, so nothing slips through the gap.