First steps with Redis
By Flavio Copes
Take your first steps with Redis using redis-cli, learning the SET and GET commands, key expiration with SET EX and TTL, and atomic INCR and DECR operations.
When you have Redis up and running, you can start using it!
The simplest way is to use redis-cli, an application installed when you install Redis.
It’s a built-in way to write commands to Redis without having to set up an application in order to do so. When you’re ready to use Redis from your own code, see how to use Redis from Node.js.

You can connect to a remote Redis server using
redis-cli -h <host> -p <port> -a <password>
Once you’re in the Redis CLI app, you can start storing data into it.
Add a value using the structure SET <key> <value>:
SET name "Flavio"
Retrieve a value
Retrieve a value using the structure GET <key>. In redis-cli, the reply shows up on the line after the command:
127.0.0.1:6379> SET name "Flavio"
OK
127.0.0.1:6379> GET name
"Flavio"
If the key doesn’t exist, you get (nil) back.
Check if a key exists
We can also check if a key exists using EXISTS <key>:
127.0.0.1:6379> EXISTS name
(integer) 1
127.0.0.1:6379> EXISTS age
(integer) 0
The command returns either 1 (exists) or 0 (does not exist).
Set if not exists
A variation of SET allows us to only set a key if it does not exist yet, using the NX option:
SET name "Roger" NX
It returns OK if the key was set, and nil if the key already existed.
You might also see the older SETNX name "Roger". It still works, but it’s deprecated in favor of SET with NX.
Delete a key
Delete a key using DEL <key>. It returns the number of keys it removed:
127.0.0.1:6379> DEL name
(integer) 1
127.0.0.1:6379> DEL name
(integer) 0
The second call returns 0 because the key was already gone.
Listing existing keys
You can list all keys inserted using KEYS *:
127.0.0.1:6379> KEYS *
1) "name"
2) "age"
Or you can filter using a pattern like KEYS n* to only list keys starting with n:
127.0.0.1:6379> KEYS n*
1) "name"
Avoid KEYS on a production server, because it goes through every key and blocks Redis until it’s done. With millions of keys, every other client waits.
Use SCAN instead. It walks the keys a few at a time, so Redis keeps serving other clients in between:
127.0.0.1:6379> SCAN 0 MATCH n* COUNT 100
1) "0"
2) 1) "name"
The reply has two parts. The first is a cursor, the second is the keys found in this round.
You start with cursor 0. If the cursor you get back is not 0, say "1088", you call SCAN 1088 MATCH n* COUNT 100 to get the next batch, and you keep going until the cursor comes back as 0. That’s when the scan is complete. On a small database like ours, one call is enough.
Be careful with two details. The same key can show up more than once during a scan, so if you need a unique list, dedupe the results in your code. And COUNT is only a hint about how much work Redis does per call, not an exact number of keys. You can get fewer keys, more keys, or even an empty batch with a non-zero cursor.
Each value stored can hold up to 512 MB.
Expiring keys
A key can be temporarily stored, and removed automatically when the timer ends. You do this with the EX option of SET:
SET <key> <value> EX <seconds>
You’ll also see SETEX <key> <seconds> <value>. It still works, but it’s deprecated in favor of SET with EX.
You can get the time remaining for a key to be cleared using TTL <key>.
In this example I set a name key with Flavio as value, expiring in 10 seconds. Using TTL I can check how much time is left. Once the timer expires, the key is gone and GET returns (nil):
127.0.0.1:6379> SET name "Flavio" EX 10
OK
127.0.0.1:6379> TTL name
(integer) 7
127.0.0.1:6379> TTL name
(integer) 2
127.0.0.1:6379> TTL name
(integer) -2
127.0.0.1:6379> GET name
(nil)
TTL returns a positive number of seconds while the key is counting down. It also has two special values:
-1means the key exists but has no expiry, so it stays until you delete it-2means the key doesn’t exist (it expired, or it was never set)
127.0.0.1:6379> SET language "Italian"
OK
127.0.0.1:6379> TTL language
(integer) -1
You can also set an existing key to expire using EXPIRE <key> <seconds>.
Increment and decrement
A numeric value can be incremented using INCR <key> and decremented using DECR <key>. You can also use INCRBY <key> <amount> and DECRBY <key> <amount> to change a key value by a specific amount:
127.0.0.1:6379> SET visits 10
OK
127.0.0.1:6379> INCR visits
(integer) 11
127.0.0.1:6379> DECR visits
(integer) 10
127.0.0.1:6379> INCRBY visits 5
(integer) 15
127.0.0.1:6379> DECRBY visits 3
(integer) 12
Notice that each command replies with the new value. If the key doesn’t exist yet, Redis treats it as 0, so INCR on a new key returns 1.
These commands are well suited for situations where many clients update the same number at the same time, like a page view counter.
Why? Let’s see what happens without them. Say visits is 10, and two clients want to add 1. Each one does a GET, adds 1 in the app code, then calls SET:
- Client A runs
GET visitsand gets10 - Client B runs
GET visitsand also gets10 - Client A calculates 11 and runs
SET visits 11 - Client B calculates 11 and runs
SET visits 11
Two visits happened, but the counter went from 10 to 11. One update is lost, because B read the value before A wrote its new one.
INCR fixes this. The read, the +1 and the write all happen on the Redis server, in one command. Redis runs commands one at a time, so no other client can sneak in between the read and the write. Two INCR calls always give you 12.
More complex data structures
So far we’ve worked with simple data types like integers and strings.
Redis can support more complex structures. Let’s see in the next lessons how to work with:
Want me to talk about your product? You can sponsor this site.