Skip to content

Make Reset atomic to avoid race conditions in concurrent operations#265

Open
SurbhiAngelite wants to merge 1 commit intoulule:masterfrom
SurbhiAngelite:patch-1
Open

Make Reset atomic to avoid race conditions in concurrent operations#265
SurbhiAngelite wants to merge 1 commit intoulule:masterfrom
SurbhiAngelite:patch-1

Conversation

@SurbhiAngelite
Copy link

Previous (DEL-based) Reset
Reset: Deletes the key with DEL.
Increment: Atomically increments the key and sets TTL using a Lua script. Race Condition:
If Reset and Increment happen at the same time, the following can occur: Increment reads the key, sees it exists, increments. Reset deletes the key.
Increment writes the new value, but the key may have just been deleted, or vice versa. Result: The counter may be unexpectedly deleted or recreated, leading to inconsistent state (e.g., a request after Reset may still see a non-zero count).

Current (Lua-based) Atomic Reset
Reset: Uses a Lua script to set the key to zero and set the TTL in a single atomic operation. Increment: Still uses a Lua script to increment and set TTL atomically. Race Condition:
Both Increment and Reset are now single atomic Lua scripts. Redis guarantees that only one script runs at a time for a given key. If Increment and Reset are called concurrently, Redis will execute one script fully before the other starts. Result:
No partial state: the key will either be incremented or reset to zero, never both at the same time. The final value will be either 0 (if Reset wins) or incremented (if Increment wins), but never a corrupted or missing key.

Previous (DEL-based) Reset
Reset: Deletes the key with DEL.
Increment: Atomically increments the key and sets TTL using a Lua script.
Race Condition:
If Reset and Increment happen at the same time, the following can occur:
Increment reads the key, sees it exists, increments.
Reset deletes the key.
Increment writes the new value, but the key may have just been deleted, or vice versa.
Result: The counter may be unexpectedly deleted or recreated, leading to inconsistent state (e.g., a request after Reset may still see a non-zero count).
 
Current (Lua-based) Atomic Reset
Reset: Uses a Lua script to set the key to zero and set the TTL in a single atomic operation.
Increment: Still uses a Lua script to increment and set TTL atomically.
Race Condition:
Both Increment and Reset are now single atomic Lua scripts.
Redis guarantees that only one script runs at a time for a given key.
If Increment and Reset are called concurrently, Redis will execute one script fully before the other starts.
Result:
No partial state: the key will either be incremented or reset to zero, never both at the same time.
The final value will be either 0 (if Reset wins) or incremented (if Increment wins), but never a corrupted or missing key.
@SurbhiAngelite SurbhiAngelite changed the title Update store.go Make Reset atomic to avoid race conditions in concurrent operations Mar 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant