A race condition when using Redis command incr and expire

David Hsu picture David Hsu · Dec 22, 2013 · Viewed 10.5k times · Source

Based on the redis document: http://redis.io/commands/incr

In the paragraph Pattern: Rate Limiter 2 A shorter version code:

value = INCR(ip)

IF value == 1 THEN
  EXPIRE(ip, 1)

It's claimed there's a race condition to make EXPIRE never executes. Which means the value of ip can bounces from 0 to 2 some way.

However in my thoughts, since Redis is single thread and INCR is a primitive command, it shouldn't be atomic itself? Even if 2 clients do the INCR at almost the same time, how could them both retrieve 0 or both retrieve 2?

Answer

misterion picture misterion · Dec 22, 2013

Imagine that you drop connection to redis server after INCR command was already executed but before EXPIRE was executed. In this case you never execute EXPIRE becouse as next call of code gives your value > 1. In redis documentation the term race condition used. But it is not successful term. A more correct term is imperfect algorithm. So this case not about race condition between 2 or more clients but about special cases in real world. Server connection loss for example.