Skip to content

Redis - Strings

Redis Strings are the simplest data type, but they are incredibly powerful and versatile. They are binary-safe, meaning a string value can hold any kind of data, from a UTF-8 string to a JPEG image or a serialized object, up to a maximum size of 512MB. This section covers the modern commands and best practices for managing string values in Redis.

1. Core Commands: SET, GET, and Expiration

Section titled “1. Core Commands: SET, GET, and Expiration”

The fundamental operations are setting a value, retrieving it, and managing its lifecycle. Modern Redis centralizes many options into the SET command for efficiency.

Instead of separate commands like SETEX or SETNX, the modern SET command includes options to handle these cases in a single, atomic operation, which reduces network latency.

SET key value [EX seconds | PX milliseconds | EXAT unix-time-seconds | PXAT unix-time-milliseconds] [NX | XX] [GET]
  • EX seconds: Set an expire time in seconds.
  • PX milliseconds: Set an expire time in milliseconds.
  • NX: Only set the key if it does not already exist.
  • XX: Only set the key if it already exists.
  • GET: Return the old value of the key, or nil if the key did not exist.
# Set a user's session data, expiring in 1 hour (3600 seconds)
> SET session:user:123 "{...user data...}" EX 3600
OK
# Attempt to set a username only if it's not already taken
> SET username:jane_doe "unique_user_id_123" NX
OK # Succeeded because the key was new
> SET username:jane_doe "another_id_456" NX
(nil) # Failed because the key already exists
# Retrieve the value
> GET session:user:123
"{...user data...}"

Redis provides atomic commands for incrementing or decrementing integer and float values. ‘Atomic’ means the operation completes fully without interruption, which is crucial for preventing race conditions in concurrent applications (e.g., multiple clients trying to update the same counter).

  • INCR key: Increments the integer value of a key by one.
  • DECR key: Decrements the integer value of a key by one.
  • INCRBY key increment: Increments the integer value by a given amount.
  • DECRBY key decrement: Decrements the integer value by a given amount.
  • INCRBYFLOAT key increment: Increments the float value by a given amount.
# A user makes a request. Increment their request counter.
> INCR api_limit:user:123:minute
(integer) 1
# Set an expiration on the key the first time to reset the count after a minute
> EXPIRE api_limit:user:123:minute 60
(integer) 1
# A better, atomic way to do this is with SET and INCR in a transaction or a Lua script.
# Another request from the same user
> INCR api_limit:user:123:minute
(integer) 2
# Check the current count
> GET api_limit:user:123:minute
"2"

To reduce network round-trips, use MSET and MGET to set or get multiple keys at once. MSETNX is a variant that sets keys only if none of them already exist.

> MSET user:1:name "Alice" user:2:name "Bob" user:1:plan "premium"
OK
> MGET user:1:name user:2:name user:3:name
1) "Alice"
2) "Bob"
3) (nil) # user:3:name was not set

Bitmaps allow you to treat a string as an array of bits. This is extremely memory-efficient for tracking boolean information (e.g., active/inactive) for a large number of entities.

  • SETBIT key offset value: Sets or clears the bit at offset (0 or 1).
  • GETBIT key offset: Returns the bit at offset.
  • BITCOUNT key [start end]: Counts the number of set bits (1s).
  • BITPOS key bit [start end]: Find the first bit set to 0 or 1.
# User with ID 5 logs in on 2023-10-27
> SETBIT daily_active_users:2023-10-27 5 1
(integer) 0 # The bit was previously 0
# User 100 also logs in
> SETBIT daily_active_users:2023-10-27 100 1
(integer) 0
# Did user 5 log in today?
> GETBIT daily_active_users:2023-10-27 5
(integer) 1
# How many unique users logged in today?
> BITCOUNT daily_active_users:2023-10-27
(integer) 2

These commands perform an action and retrieve a value in a single atomic step.

  • GETSET key value: Sets a new value and returns the old one. Useful for scenarios like rotating secrets or tokens.
  • GETDEL key: Retrieves the value of a key and then deletes it. Perfect for implementing reliable, single-use message queues or locks.
  • APPEND key value: Appends the value to the end of the string. Returns the new length of the string.
# A task is stored in a temporary key
> SET task:job:987 "Process video upload"
OK
# A worker atomically fetches the task details and deletes the key
# This ensures no other worker can grab the same job.
> GETDEL task:job:987
"Process video upload"
  • Key Naming: Use a clear, hierarchical naming convention, like object:id:field (e.g., user:1001:profile_pic). This improves readability and prevents key collisions.
  • Caching: Store API responses, rendered HTML fragments, or complex computation results. Always use EX to set an expiration to prevent stale data.
  • Session Storage: Store user session data. The EX option is perfect for automatically logging users out after a period of inactivity.
  • Rate Limiting: Use INCR on a key with an EX to track actions within a time window.
  • Feature Flags: A simple GET feature:new_dashboard:enabled can determine if a feature is active for a user or a group.
  • Avoid Large Payloads: While strings can hold 512MB, it’s often an anti-pattern. Storing large JSON documents is better handled by Redis’s native JSON data type (RedisJSON module) or by splitting the data into a Redis Hash.