CodePark/ questions / Rate limiting & counters
START PRACTICINGPRACTICE
Backend question · Redis & caching › Rate limiting & counters

You need a page-view counter shared by 10 Node instances. Why use INCR instead of reading the value, adding 1 and writing it back?

Use INCR because reading, adding and writing from the app is a race condition, and INCR is not. Example: two instances both read 41. Both add 1. Both write 42. One page view is lost. Under heavy load, many updates are lost this way.

INCR does the read, add and write inside Redis as one command. Related commands work the same way: INCRBY, INCRBYFLOAT, HINCRBY and ZINCRBY. Redis runs commands one at a time, so no increment is ever lost, however many clients send them. INCR also has two more benefits:

  • It takes one round trip instead of two.
  • It returns the new value, which is often all you need.

Sometimes the counter only needs to be correct eventually, and traffic is huge. Then you can collect increments in memory and send them with INCRBY once a second. You may lose a few counts if the app crashes, but you send far fewer commands.

  • GET then SET from the app loses updates that happen at the same time.
  • INCR is atomic inside Redis.
  • INCR takes one round trip and returns the new value.
  • Use INCRBY, HINCRBY or ZINCRBY for other data shapes.
  • For very high volume, batch counts in memory and send them with INCRBY.