Redis - Strings
Redis - Modern String Operations
Section titled “Redis - Modern String Operations”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.
The Modern SET Command
Section titled “The Modern SET Command”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.
Example: Caching an API Response
Section titled “Example: Caching an API Response”# Set a user's session data, expiring in 1 hour (3600 seconds)> SET session:user:123 "{...user data...}" EX 3600OK
# Attempt to set a username only if it's not already taken> SET username:jane_doe "unique_user_id_123" NXOK # 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...}"2. Atomic Counters and Numeric Operations
Section titled “2. Atomic Counters and Numeric Operations”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.
Example: Rate Limiting an API Endpoint
Section titled “Example: Rate Limiting an API Endpoint”# 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"3. Batch Operations
Section titled “3. Batch Operations”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:name1) "Alice"2) "Bob"3) (nil) # user:3:name was not set4. Bit-level Operations (Bitmaps)
Section titled “4. Bit-level Operations (Bitmaps)”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 atoffset(0 or 1).GETBIT key offset: Returns the bit atoffset.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.
Example: Tracking Daily Active Users
Section titled “Example: Tracking Daily Active Users”# 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) 25. Advanced Atomic Operations
Section titled “5. Advanced Atomic Operations”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.
Example: Processing a Task
Section titled “Example: Processing a Task”# 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"Best Practices & Common Use Cases
Section titled “Best Practices & Common Use Cases”- 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
EXto set an expiration to prevent stale data. - Session Storage: Store user session data. The
EXoption is perfect for automatically logging users out after a period of inactivity. - Rate Limiting: Use
INCRon a key with anEXto track actions within a time window. - Feature Flags: A simple
GET feature:new_dashboard:enabledcan 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.