Redis Strings

Strings are the most basic Redis data type. A Redis string can hold any kind of data: text, serialized JSON, binary data like images, or even integers and floats that Redis can manipulate atomically.

Key Characteristics

• Maximum size: 512 MB per string • Binary-safe: can store any binary data • Supports atomic increment/decrement for numeric values • Perfect for caching, counters, rate limiting, and session storage

Basic Operations

# Store and retrieve strings
SET user:1:name "John Doe"              # Store a string
GET user:1:name                         # Retrieve: "John Doe"
SETNX user:1:name "Jane"                # Set only if key doesn't exist (returns 0)
SETEX session:abc123 3600 "user_data"   # Set with 1-hour expiration

# Multiple keys at once
MSET user:1:city "NYC" user:1:age "30"  # Set multiple keys atomically
MGET user:1:name user:1:city user:1:age # Get multiple values

Atomic Counters

Redis strings can store integers and provide atomic increment/decrement operations—perfect for counters, rate limiters, and sequences.

SET page:views 0
INCR page:views                         # Increment by 1 → 1
INCRBY page:views 100                   # Increment by 100 → 101
DECR page:views                         # Decrement by 1 → 100
DECRBY page:views 50                    # Decrement by 50 → 50
INCRBYFLOAT price:item1 0.99            # Floating-point increment

# Get and set atomically
GETSET counter "0"                      # Returns old value, sets new
GETDEL temp:key                         # Get value and delete key

Bit Operations

Treat strings as bit arrays for memory-efficient boolean flags, bloom filters, and user tracking.

SETBIT user:1:features 0 1              # Set bit 0 to 1 (feature enabled)
SETBIT user:1:features 1 1              # Set bit 1 to 1
GETBIT user:1:features 0                # Get bit 0 → 1
BITCOUNT user:1:features                # Count set bits → 2

# Bit operations across keys
BITOP AND result key1 key2              # Bitwise AND
BITOP OR result key1 key2               # Bitwise OR
BITOP XOR result key1 key2              # Bitwise XOR
BITOP NOT result key1                   # Bitwise NOT

BITPOS user:1:features 1                # Position of first '1' bit

String Manipulation

APPEND user:1:name " Jr."               # Append → "John Doe Jr."
STRLEN user:1:name                      # Length → 12
GETRANGE user:1:name 0 3                # Substring → "John"
SETRANGE user:1:name 5 "Smith"          # Replace at offset 5

# Get/set with expiration
SET cache:key "value" EX 3600           # Expires in 1 hour
SET cache:key "value" PX 60000          # Expires in 60 seconds
SET cache:key "value" EXAT 1707000000   # Expires at Unix timestamp
TTL cache:key                           # Check remaining TTL

Use Case: Caching

Store serialized objects, API responses, or rendered HTML with automatic expiration.

# Cache API response for 5 minutes
SET cache:api:users:page1 '{"users":[...]}' EX 300

# Check cache first, then fetch
cached = GET cache:api:users:page1
if cached:
    return json.parse(cached)
else:
    data = fetch_from_database()
    SET cache:api:users:page1 json.stringify(data) EX 300
    return data

Use Case: Rate Limiting

Implement sliding window counters with INCR and EXPIRE.

def is_rate_limited(user_id, limit=100, window=60):
    key = f"rate:{user_id}"
    current = INCR(key)

    if current == 1:
        EXPIRE(key, window)  # Set window on first request

    return current > limit

# Usage
if is_rate_limited("user:123"):
    return "429 Too Many Requests"

Use Case: Distributed Locks

Use SET NX PX for acquiring locks with automatic expiration.

def acquire_lock(resource, owner_id, ttl_ms=30000):
    key = f"lock:{resource}"
    # NX = only if not exists, PX = milliseconds TTL
    result = SET(key, owner_id, "NX", "PX", ttl_ms)
    return result == "OK"

def release_lock(resource, owner_id):
    key = f"lock:{resource}"
    # Only release if we own the lock (use Lua script for atomicity)
    if GET(key) == owner_id:
        DEL(key)
        return True
    return False

# Lua script for atomic check-and-delete
EVAL "if redis.call('get',KEYS[1])==ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end" 1 lock:resource owner_id
Knowledge is power.