Back to Blog
Lesson 17 of the Redis: Redis Essentials & Data Types course
DatabasesAugust 4, 20264 min read

Mastering INCR and DECR: Atomic Counters in Redis

Learn how to use Redis INCR and DECR commands to build thread-safe counters. Avoid race conditions and master atomic operations for your API backends.

RedisCountersAtomicityINCRDECRBackendDatabase
Vibrant closeup of a colorful molecular model illustrating abstract scientific concepts.

Previously in this course, we explored the Introduction to Atomic Operations: Redis Performance & Integrity, where we established why Redis is inherently safe for single-command operations. In this lesson, we add practical power to that concept by learning how to manipulate integers using specialized commands.

When you need to count things—like API requests, page views, or inventory stock—you often encounter the "read-modify-write" problem. If two users click a button at the exact same time, a traditional database might read the value "10," both increment it in their local application memory to "11," and write "11" back to the database. The result? You missed one click.

Redis solves this with atomic INCR and DECR commands.

Understanding Atomic Increments and Decrements

Redis stores string values that represent integers as special internal structures. Because Redis is single-threaded, when you run INCR, it performs the entire operation—fetching the value, adding one, and saving it back—as a single, uninterrupted unit of work.

The Core Commands

  • INCR key: Increments the integer value of a key by one. If the key does not exist, it is set to 0 before performing the operation.
  • DECR key: Decrements the integer value of a key by one.
  • INCRBY key increment: Increases the value by a specific integer amount.
  • DECRBY key decrement: Decreases the value by a specific integer amount.

Worked Example: Tracking API Requests

Screen displaying ChatGPT examples, capabilities, and limitations.

In our project, we need to track how many requests a specific user makes. Using INCR is the standard way to implement a basic counter for this purpose.

Using the CLI

Open your terminal and connect to your Redis instance:

Bash
# Start the count
127.0.0.1:6379> INCR user:101:request_count
(integer) 1

# Increment again
127.0.0.1:6379> INCR user:101:request_count
(integer) 2

# Decrement after a successful process
127.0.0.1:6379> DECR user:101:request_count
(integer) 1

Implementing in Node.js

Using the redis client established in our Setting Up the Backend Project Baseline with Node.js and Redis, here is how you would increment a counter within your API service:

JAVASCRIPT
const client = require(CE9178">'./redisClient'); // Assume this is your configured client

async function trackRequest(userId) {
  const key = CE9178">`user:${userId}:requests`;
  
  // Atomically increment the counter
  const currentCount = await client.incr(key);
  
  console.log(CE9178">`User ${userId} has made ${currentCount} requests.`);
  return currentCount;
}

Resetting Counters

Sometimes you need to reset a counter—perhaps when a new time window begins. Since there is no specific RESET command, you simply use DEL or SET the key to 0.

Bash
# Resetting the counter
127.0.0.1:6379> DEL user:101:request_count
(integer) 1
# The next INCR will start from 1 again

Hands-on Exercise

  1. Open your redis-cli.
  2. Create a key named app:global_counter and increment it three times.
  3. Use INCRBY to add 5 to that same key.
  4. Use DECRBY to subtract 2.
  5. Verify the final value is 6.
  6. Delete the key to reset the state.

Common Pitfalls

  • Non-integer values: If you try to run INCR on a key that stores a string like "hello", Redis will return an error (ERR value is not an integer or out of range). Always ensure your counters are initialized as integers.
  • Forgetting to handle expiration: Counters often accumulate indefinitely. In our next lessons, we will combine these counters with TTLs to prevent memory bloat.
  • Overflow: Redis integers are 64-bit signed integers. While hitting the limit is rare, be aware that you cannot exceed the range of a 64-bit signed integer.

FAQ

Q: What happens if I use INCR on a non-existent key? A: Redis automatically creates the key, treats the initial value as 0, and returns 1.

Q: Are these operations really safe? A: Yes. Because Redis executes commands atomically, no other command can run between the read and the write, effectively eliminating race conditions.

Q: Can I increment by floats? A: Use INCRBYFLOAT if you need to increment by decimal values.

Recap

Team members presenting a project in a modern office setting with a focus on collaboration.

We’ve mastered the art of atomic state management. By using INCR and DECR, we ensure our counters remain accurate even under heavy concurrent load. These commands are the building blocks for the rate-limiting and metrics tracking we will implement later in this course.

Up next: Preventing Race Conditions where we will look at how to handle more complex logic safely using transactions.

Similar Posts