iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Strings

Strings are Redis’ simplest data type — binary-safe byte sequences up to 512 MB. Commands: SET, GET, INCR, APPEND, EXPIRE. Counters, caches, JSON blobs, rate limits — all built on strings.

SET, GET, INCR, EXPIRE, real recipes

EXAMPLE
# 1) Basic SET / GET
SET name "Ada"
GET name                                            # "Ada"
MSET k1 v1 k2 v2 k3 v3                              # multi-set
MGET k1 k2 k3                                       # multi-get

# 2) SET with options
SET cache:user:42 'Ada' EX 60                       # expires in 60 seconds
SET cache:user:42 'Ada' PX 60000                    # expires in 60000 ms
SET cache:user:42 'Ada' EXAT 1717000000             # expires at Unix timestamp
SET counter 0 NX                                    # NX = only if NOT exists
SET counter 10 XX                                   # XX = only if EXISTS
SET key value KEEPTTL                               # keep existing TTL on overwrite
SET key value GET                                   # set new, return old (atomic)

# 3) Counters (atomic)
INCR pageviews                                      # 1
INCR pageviews                                      # 2
INCRBY pageviews 10                                 # 12
DECR pageviews                                      # 11
DECRBY pageviews 5                                  # 6
INCRBYFLOAT balance 49.99                           # works with floats

# 4) TTL / EXPIRE
EXPIRE key 60                                       # 60s TTL
PEXPIRE key 60000                                   # in ms
EXPIREAT key 1717000000                             # absolute Unix time
TTL key                                             # remaining seconds (-2 = missing, -1 = no TTL)
PERSIST key                                         # remove TTL

# 5) Append + length
APPEND log 'first line\n'
APPEND log 'second line\n'
STRLEN log

# 6) Range + substring
GETRANGE key 0 9                                    # first 10 chars
SETRANGE key 6 'World'                              # overwrite from index 6

# 7) Bitops (binary-safe)
SETBIT visitors:2026-06-08 42 1                     # mark user 42 as visited
GETBIT visitors:2026-06-08 42                       # 1
BITCOUNT visitors:2026-06-08                        # count set bits = unique visitors today
BITOP AND visited:both visitors:2026-06-08 visitors:2026-06-09

# === Real recipes ===

# 8) Cache pattern — get-or-fetch
GET user:42                                         # try cache
# if (nil) → fetch from DB, SET with EXPIRE
SET user:42 '{"name":"Ada","email":"a@x.com"}' EX 300

# 9) Rate limiting (fixed window) — INCR + EXPIRE
# Per user, per minute
INCR rate:user:42:202606081430
EXPIRE rate:user:42:202606081430 60                 # only on first hit
# Reject if INCR returns > 100

# 10) Distributed lock (simple, NOT failsafe)
SET lock:resource value NX EX 30                    # acquire if not held
# work
DEL lock:resource                                   # release

# Better: use Redlock library or SET ... NX EX + token + Lua release script

# 11) Cache stampede protection (probabilistic early expiration)
# When TTL is close to expiring, randomly refresh before all clients miss simultaneously.

# 12) Counter sharded across N keys (high write throughput)
INCR counter:1
INCR counter:2
# To read: sum the shards.
SUM = 0
for i in 1..N:
    SUM += GET counter:$i

# 13) Distinct daily counts (bitmap)
SETBIT visitors:2026-06-08 42 1
SETBIT visitors:2026-06-08 99 1
BITCOUNT visitors:2026-06-08

# 14) Object cache (JSON blob)
SET user:42 '{"name":"Ada","email":"a@x.com","role":"admin"}' EX 600
GET user:42
# Use HASH instead if you frequently update individual fields

# 15) Atomic increment with cap (Lua)
EVAL "local v = tonumber(redis.call('INCR', KEYS[1]))
      if v > tonumber(ARGV[1]) then
          redis.call('DECR', KEYS[1])
          return -1
      end
      return v" 1 inventory:item:A100 100

# 16) GETSET — atomic read + write
GETSET counter 0                                    # gets old value, resets to 0
# Use for snapshot + reset patterns

# 17) Sliding window rate limit (more accurate than fixed window)
# Use sorted sets — see redis/sorted-sets lesson

# 18) Multi-region / cluster considerations
# - Single shard: all strings on one node, easy
# - Cluster: keys distributed by hash slot; use { } in keys for grouping (e.g. {user:42}:profile, {user:42}:settings → same shard)

# 19) Node + ioredis
import Redis from 'ioredis';
const redis = new Redis();

await redis.set('user:42', 'Ada', 'EX', 60);
const v = await redis.get('user:42');

await redis.incr('pageviews');
await redis.expire('pageviews', 60);

# Pipeline (multiple commands in one round trip)
const pipeline = redis.pipeline();
pipeline.set('a', 1);
pipeline.set('b', 2);
pipeline.incr('c');
const results = await pipeline.exec();

# Transactions (MULTI / EXEC)
const multi = redis.multi();
multi.set('a', 1);
multi.incr('a');
const results = await multi.exec();

# 20) Common bugs
#   • Forgetting EXPIRE — keys grow forever
#   • Storing huge values (>1MB) — slow ops + memory pressure
#   • Using GET + SET pattern instead of INCR for counters — race conditions
#   • Caching with KEEPTTL forgotten — old TTLs override new ones
#   • Mixing TTL semantics (EX vs PX vs EXAT) and getting timing wrong

# 21) Memory tips
#   • Use HASH for small objects (memory-efficient)
#   • Use bitmaps / hyperloglog for cardinality counting
#   • Monitor with MEMORY USAGE <key>
#   • Set maxmemory-policy (allkeys-lru, allkeys-lfu, volatile-ttl)

# 22) When NOT to use string commands
#   • Field-level updates on objects → use HASH (HSET / HGET / HINCRBY)
#   • Append-only logs / replay → use STREAM (XADD / XREAD)
#   • Unique sets of IDs → use SET (SADD / SISMEMBER)
#   • Ranked / scored data → use SORTED SET (ZADD / ZRANGE)

Why it matters

Strings power most Redis use cases: counters via INCR, caches via SET EX, rate limits via INCR + EXPIRE, bitmaps for unique visitors. Always set a TTL on cache keys — without one, memory grows until something breaks.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
SET hits 0
INCR hits             # 1
INCRBY hits 10        # 11
APPEND name " Lovelace"
GETRANGE name 0 2     # "Ada"
Try it Yourself »

Exercise

Atomic increment.

hits

Discussion

Loading…