-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathredis-commands.html
More file actions
679 lines (614 loc) · 36.3 KB
/
redis-commands.html
File metadata and controls
679 lines (614 loc) · 36.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Redis Commands Cheat Sheet — Quick Reference | DevToolbox</title>
<meta name="description" content="Redis commands cheat sheet with essential commands for strings, hashes, lists, sets, sorted sets, pub/sub, transactions, and administration. Quick reference for developers.">
<meta name="keywords" content="redis commands, redis cheat sheet, redis reference, redis cli, redis data types, redis strings, redis hashes, redis lists, redis sets">
<meta property="og:title" content="Redis Commands Cheat Sheet | DevToolbox">
<meta property="og:description" content="Quick reference for Redis commands and data types">
<meta property="og:type" content="website">
<meta property="og:url" content="https://devtoolbox.dedyn.io/cheatsheets/redis-commands">
<meta property="og:site_name" content="DevToolbox">
<meta property="og:image" content="https://devtoolbox.dedyn.io/og/cs-redis-commands.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Redis Commands Cheat Sheet | DevToolbox">
<meta name="twitter:description" content="Quick reference for Redis commands">
<meta name="robots" content="index, follow">
<link rel="canonical" href="https://devtoolbox.dedyn.io/cheatsheets/redis-commands">
<link rel="icon" href="/favicon.ico" sizes="any">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/icons/icon-192.png">
<link rel="manifest" href="/manifest.json">
<meta name="theme-color" content="#3b82f6">
<link rel="stylesheet" href="/css/style.css">
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"name": "Redis Commands Cheat Sheet",
"headline": "Redis Commands Cheat Sheet — Quick Reference",
"description": "Redis commands cheat sheet with essential commands for strings, hashes, lists, sets, sorted sets, pub/sub, transactions, streams, and administration.",
"url": "https://devtoolbox.dedyn.io/cheatsheets/redis-commands",
"author": { "@type": "Organization", "name": "DevToolbox" },
"publisher": { "@type": "Organization", "name": "DevToolbox" }
}
</script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "What are the main data types in Redis?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Redis supports several core data types: Strings (binary-safe text or numbers), Lists (ordered collections of strings), Sets (unordered collections of unique strings), Sorted Sets (sets ordered by a score), Hashes (field-value maps similar to objects), Streams (append-only log structures), and additional types like Bitmaps, HyperLogLogs, and Geospatial indexes. Each type has specialized commands optimized for its access patterns."
}
},
{
"@type": "Question",
"name": "What is the difference between DEL and UNLINK in Redis?",
"acceptedAnswer": {
"@type": "Answer",
"text": "DEL removes keys synchronously, blocking the server until the operation completes. For large keys (big lists, sets, or hashes), this can cause noticeable latency. UNLINK (available since Redis 4.0) removes keys asynchronously by unlinking them from the keyspace immediately and reclaiming memory in a background thread. Use UNLINK for large keys in production to avoid blocking the main Redis thread."
}
},
{
"@type": "Question",
"name": "How do Redis Streams differ from Pub/Sub?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Redis Pub/Sub is fire-and-forget: messages are delivered to subscribers in real time but are lost if no subscriber is listening. Redis Streams (introduced in Redis 5.0) are persistent, append-only log structures that store messages with unique IDs. Streams support consumer groups for load-balanced processing, message acknowledgment, and the ability to read historical messages. Use Pub/Sub for ephemeral notifications and Streams for reliable message processing that requires durability and replay."
}
},
{
"@type": "Question",
"name": "How should I use KEYS vs SCAN in production?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Never use the KEYS command in production because it scans the entire keyspace in a single blocking operation, which can freeze your Redis instance for seconds on large databases. Instead, use SCAN with a cursor-based approach. SCAN incrementally iterates through keys without blocking, returning a small batch per call. Combine it with MATCH for pattern filtering and COUNT to hint at batch size. For hash, set, and sorted set iteration, use HSCAN, SSCAN, and ZSCAN respectively."
}
}
]
}
</script>
<style>
.pattern-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.5rem; margin-bottom: 1.5rem; }
.pattern-card h3 { font-size: 1.1rem; margin-bottom: 0.75rem; color: var(--text); }
.pattern-card p { color: var(--text-muted); line-height: 1.7; margin-bottom: 0.75rem; }
.pattern-card pre { background: var(--code-bg); border: 1px solid var(--border); border-radius: var(--radius); padding: 1rem; overflow-x: auto; font-size: 0.85rem; line-height: 1.5; margin-top: 0.75rem; }
.pattern-card code { font-family: 'SF Mono', 'Fira Code', monospace; color: var(--text); }
.faq-section { margin-top: 2rem; }
.faq-section h2 { font-size: 1.35rem; margin-bottom: 1rem; padding-bottom: 0.5rem; border-bottom: 2px solid var(--primary); }
.faq-item { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.25rem; margin-bottom: 1rem; }
.faq-item h3 { font-size: 1.05rem; margin-bottom: 0.5rem; color: var(--text); }
.faq-item p { color: var(--text-muted); line-height: 1.7; }
.toc { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.25rem 1.5rem; margin-bottom: 2rem; }
.toc h3 { font-size: 1rem; margin-bottom: 0.75rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; }
.toc ul { list-style: none; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 0.35rem; }
.toc a { color: var(--text-muted); font-size: 0.9rem; }
.toc a:hover { color: var(--primary); }
@media (max-width: 768px) { .toc ul { grid-template-columns: 1fr; } }
</style>
</head>
<body>
<header>
<nav>
<a href="/" class="logo"><span class="logo-icon">{ }</span><span>DevToolbox</span></a>
<div class="nav-links"><a href="/index.html#tools">Tools</a><a href="/index.html#cheat-sheets">Cheat Sheets</a><a href="/index.html#guides">Blog</a></div>
</nav>
</header>
<nav class="breadcrumb" aria-label="Breadcrumb"><a href="/">Home</a><span class="separator">/</span><a href="/index.html#cheat-sheets">Cheat Sheets</a><span class="separator">/</span><span class="current">Redis Commands</span></nav>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{ "@type": "ListItem", "position": 1, "name": "Home", "item": "https://devtoolbox.dedyn.io/" },
{ "@type": "ListItem", "position": 2, "name": "Cheat Sheets", "item": "https://devtoolbox.dedyn.io/cheatsheets" },
{ "@type": "ListItem", "position": 3, "name": "Redis Commands" }
]
}
</script>
<main class="cheatsheet-page">
<h1>Redis Commands Cheat Sheet</h1>
<p class="description">Essential Redis commands organized by data type with syntax examples. Covers strings, hashes, lists, sets, sorted sets, streams, pub/sub, transactions, and common production patterns.</p>
<div class="search-box" style="margin-bottom:2rem;">
<input type="text" id="search" placeholder="Search Redis commands (e.g., SET, HGET, LPUSH, ZADD)... (Ctrl+K)" autocomplete="off">
</div>
<div class="toc">
<h3>On This Page</h3>
<ul>
<li><a href="#connection-server">Connection & Server</a></li>
<li><a href="#strings">Strings</a></li>
<li><a href="#hashes">Hashes</a></li>
<li><a href="#lists">Lists</a></li>
<li><a href="#sets">Sets</a></li>
<li><a href="#sorted-sets">Sorted Sets</a></li>
<li><a href="#keys">Keys</a></li>
<li><a href="#pubsub">Pub/Sub</a></li>
<li><a href="#transactions">Transactions</a></li>
<li><a href="#streams">Streams</a></li>
<li><a href="#patterns">Common Patterns</a></li>
<li><a href="#faq">FAQ</a></li>
</ul>
</div>
<!-- 1. Connection & Server -->
<h2 class="section-header" id="connection-server">Connection & Server</h2>
<table class="cheatsheet-table">
<thead><tr><th style="width:45%">Command</th><th>Description</th></tr></thead>
<tbody>
<tr><td><code>PING</code></td><td>Test connection — returns PONG if alive</td></tr>
<tr><td><code>AUTH <password></code></td><td>Authenticate to the server</td></tr>
<tr><td><code>AUTH <user> <password></code></td><td>Authenticate with ACL user (Redis 6+)</td></tr>
<tr><td><code>SELECT <db></code></td><td>Switch database (0-15 by default)</td></tr>
<tr><td><code>INFO</code></td><td>Get server information and statistics</td></tr>
<tr><td><code>INFO server</code></td><td>Get only the server section</td></tr>
<tr><td><code>CONFIG GET <param></code></td><td>Read a configuration parameter</td></tr>
<tr><td><code>CONFIG SET <param> <val></code></td><td>Set a configuration parameter at runtime</td></tr>
<tr><td><code>DBSIZE</code></td><td>Return number of keys in current database</td></tr>
<tr><td><code>FLUSHDB</code></td><td>Delete all keys in the current database</td></tr>
<tr><td><code>FLUSHALL</code></td><td>Delete all keys in all databases</td></tr>
<tr><td><code>CLIENT LIST</code></td><td>List all connected clients</td></tr>
</tbody>
</table>
<div class="pattern-card">
<h3>Connection Examples</h3>
<pre><code class="language-bash"># Connect to local Redis
redis-cli
# Connect to remote Redis with auth
redis-cli -h 10.0.0.5 -p 6379 -a mypassword
# Connect with TLS
redis-cli --tls -h redis.example.com -p 6380
# Check server health
127.0.0.1:6379> PING
PONG
# Get memory usage info
127.0.0.1:6379> INFO memory</code></pre>
</div>
<!-- 2. Strings -->
<h2 class="section-header" id="strings">Strings</h2>
<table class="cheatsheet-table">
<thead><tr><th style="width:45%">Command</th><th>Description</th></tr></thead>
<tbody>
<tr><td><code>SET key value</code></td><td>Set a key to a string value</td></tr>
<tr><td><code>GET key</code></td><td>Get the value of a key</td></tr>
<tr><td><code>MSET k1 v1 k2 v2</code></td><td>Set multiple keys atomically</td></tr>
<tr><td><code>MGET k1 k2 k3</code></td><td>Get multiple values at once</td></tr>
<tr><td><code>INCR key</code></td><td>Increment integer value by 1</td></tr>
<tr><td><code>INCRBY key 10</code></td><td>Increment integer value by 10</td></tr>
<tr><td><code>DECR key</code></td><td>Decrement integer value by 1</td></tr>
<tr><td><code>DECRBY key 5</code></td><td>Decrement integer value by 5</td></tr>
<tr><td><code>APPEND key " more"</code></td><td>Append string to existing value</td></tr>
<tr><td><code>STRLEN key</code></td><td>Get string length of value</td></tr>
<tr><td><code>SETEX key 60 value</code></td><td>Set with 60-second expiration</td></tr>
<tr><td><code>SETNX key value</code></td><td>Set only if key does not exist</td></tr>
<tr><td><code>GETSET key newval</code></td><td>Set new value, return old value</td></tr>
<tr><td><code>GETRANGE key 0 4</code></td><td>Get substring (bytes 0 through 4)</td></tr>
</tbody>
</table>
<div class="pattern-card">
<h3>String Examples</h3>
<pre><code class="language-bash"># Basic set and get
SET user:name "Alice"
GET user:name # "Alice"
# Set with expiration (cache for 5 minutes)
SET api:cache:result '{"status":"ok"}' EX 300
# Atomic counter
SET page:views 0
INCR page:views # 1
INCRBY page:views 10 # 11
# Set only if not exists (simple lock)
SETNX lock:resource "owner-123"
# Bulk operations
MSET city "Berlin" country "DE" lang "en"
MGET city country lang # "Berlin" "DE" "en"</code></pre>
</div>
<!-- 3. Hashes -->
<h2 class="section-header" id="hashes">Hashes</h2>
<table class="cheatsheet-table">
<thead><tr><th style="width:45%">Command</th><th>Description</th></tr></thead>
<tbody>
<tr><td><code>HSET key field value</code></td><td>Set a field in a hash</td></tr>
<tr><td><code>HGET key field</code></td><td>Get a hash field value</td></tr>
<tr><td><code>HMSET key f1 v1 f2 v2</code></td><td>Set multiple hash fields</td></tr>
<tr><td><code>HMGET key f1 f2 f3</code></td><td>Get multiple hash field values</td></tr>
<tr><td><code>HGETALL key</code></td><td>Get all fields and values</td></tr>
<tr><td><code>HDEL key field</code></td><td>Delete a field from a hash</td></tr>
<tr><td><code>HEXISTS key field</code></td><td>Check if field exists (1 or 0)</td></tr>
<tr><td><code>HINCRBY key field 5</code></td><td>Increment integer field by 5</td></tr>
<tr><td><code>HINCRBYFLOAT key field 1.5</code></td><td>Increment float field by 1.5</td></tr>
<tr><td><code>HLEN key</code></td><td>Get number of fields in hash</td></tr>
<tr><td><code>HKEYS key</code></td><td>Get all field names</td></tr>
<tr><td><code>HVALS key</code></td><td>Get all field values</td></tr>
<tr><td><code>HSETNX key field val</code></td><td>Set field only if it does not exist</td></tr>
</tbody>
</table>
<div class="pattern-card">
<h3>Hash Examples</h3>
<pre><code class="language-bash"># Store a user object
HSET user:100 name "Alice" email "alice@dev.io" role "admin"
# Read specific fields
HGET user:100 name # "Alice"
HMGET user:100 name role # "Alice" "admin"
# Get all fields
HGETALL user:100
# "name" "Alice" "email" "alice@dev.io" "role" "admin"
# Increment a numeric field
HSET user:100 login_count 0
HINCRBY user:100 login_count 1 # 1
# Check field existence
HEXISTS user:100 email # 1
HEXISTS user:100 phone # 0</code></pre>
</div>
<!-- 4. Lists -->
<h2 class="section-header" id="lists">Lists</h2>
<table class="cheatsheet-table">
<thead><tr><th style="width:45%">Command</th><th>Description</th></tr></thead>
<tbody>
<tr><td><code>LPUSH key v1 v2</code></td><td>Push values to head (left) of list</td></tr>
<tr><td><code>RPUSH key v1 v2</code></td><td>Push values to tail (right) of list</td></tr>
<tr><td><code>LPOP key</code></td><td>Remove and return first element</td></tr>
<tr><td><code>RPOP key</code></td><td>Remove and return last element</td></tr>
<tr><td><code>LRANGE key 0 -1</code></td><td>Get all elements in list</td></tr>
<tr><td><code>LLEN key</code></td><td>Get list length</td></tr>
<tr><td><code>LINDEX key 0</code></td><td>Get element at index 0</td></tr>
<tr><td><code>LINSERT key BEFORE piv val</code></td><td>Insert before pivot element</td></tr>
<tr><td><code>LINSERT key AFTER piv val</code></td><td>Insert after pivot element</td></tr>
<tr><td><code>LREM key 2 val</code></td><td>Remove first 2 occurrences of val</td></tr>
<tr><td><code>LTRIM key 0 99</code></td><td>Trim list to first 100 elements</td></tr>
<tr><td><code>BLPOP key 30</code></td><td>Blocking pop from head (30s timeout)</td></tr>
<tr><td><code>BRPOP key 30</code></td><td>Blocking pop from tail (30s timeout)</td></tr>
<tr><td><code>LMOVE src dst LEFT RIGHT</code></td><td>Move element between lists (6.2+)</td></tr>
</tbody>
</table>
<div class="pattern-card">
<h3>List Examples</h3>
<pre><code class="language-bash"># Build a task queue
RPUSH queue:jobs "job:1" "job:2" "job:3"
# Worker pops from the left (FIFO)
LPOP queue:jobs # "job:1"
# Blocking pop (worker waits for new jobs)
BLPOP queue:jobs 0 # blocks until a job arrives
# Recent activity feed (keep last 50 items)
LPUSH feed:user:42 "posted a comment"
LTRIM feed:user:42 0 49
LRANGE feed:user:42 0 9 # latest 10 items
# Stack behavior (LIFO)
LPUSH stack:undo "action1" "action2"
LPOP stack:undo # "action2"</code></pre>
</div>
<!-- 5. Sets -->
<h2 class="section-header" id="sets">Sets</h2>
<table class="cheatsheet-table">
<thead><tr><th style="width:45%">Command</th><th>Description</th></tr></thead>
<tbody>
<tr><td><code>SADD key m1 m2</code></td><td>Add members to a set</td></tr>
<tr><td><code>SREM key m1</code></td><td>Remove a member</td></tr>
<tr><td><code>SMEMBERS key</code></td><td>Get all members</td></tr>
<tr><td><code>SISMEMBER key m1</code></td><td>Check if member exists (1 or 0)</td></tr>
<tr><td><code>SCARD key</code></td><td>Get number of members</td></tr>
<tr><td><code>SUNION k1 k2</code></td><td>Return union of sets</td></tr>
<tr><td><code>SINTER k1 k2</code></td><td>Return intersection of sets</td></tr>
<tr><td><code>SDIFF k1 k2</code></td><td>Return members in k1 but not k2</td></tr>
<tr><td><code>SPOP key</code></td><td>Remove and return random member</td></tr>
<tr><td><code>SRANDMEMBER key 3</code></td><td>Return 3 random members</td></tr>
<tr><td><code>SMOVE src dst member</code></td><td>Move member between sets</td></tr>
<tr><td><code>SUNIONSTORE dest k1 k2</code></td><td>Store union in destination</td></tr>
<tr><td><code>SINTERSTORE dest k1 k2</code></td><td>Store intersection in destination</td></tr>
</tbody>
</table>
<div class="pattern-card">
<h3>Set Examples</h3>
<pre><code class="language-bash"># Track unique visitors
SADD visitors:2025-02-12 "user:1" "user:2" "user:3"
SCARD visitors:2025-02-12 # 3
# Tag system
SADD tags:article:50 "redis" "database" "nosql"
SADD tags:article:51 "redis" "caching" "performance"
# Find articles sharing tags
SINTER tags:article:50 tags:article:51 # "redis"
# Find all tags across articles
SUNION tags:article:50 tags:article:51
# "redis" "database" "nosql" "caching" "performance"
# Check membership
SISMEMBER tags:article:50 "redis" # 1</code></pre>
</div>
<!-- 6. Sorted Sets -->
<h2 class="section-header" id="sorted-sets">Sorted Sets</h2>
<table class="cheatsheet-table">
<thead><tr><th style="width:45%">Command</th><th>Description</th></tr></thead>
<tbody>
<tr><td><code>ZADD key score member</code></td><td>Add member with score</td></tr>
<tr><td><code>ZREM key member</code></td><td>Remove a member</td></tr>
<tr><td><code>ZRANGE key 0 -1</code></td><td>Get all members (ascending)</td></tr>
<tr><td><code>ZRANGE key 0 -1 WITHSCORES</code></td><td>Get all with scores</td></tr>
<tr><td><code>ZREVRANGE key 0 9</code></td><td>Top 10 (highest score first)</td></tr>
<tr><td><code>ZRANGEBYSCORE key 10 100</code></td><td>Members with scores 10-100</td></tr>
<tr><td><code>ZRANK key member</code></td><td>Get rank (ascending, 0-indexed)</td></tr>
<tr><td><code>ZREVRANK key member</code></td><td>Get rank (descending)</td></tr>
<tr><td><code>ZSCORE key member</code></td><td>Get score of a member</td></tr>
<tr><td><code>ZCARD key</code></td><td>Get member count</td></tr>
<tr><td><code>ZINCRBY key 5 member</code></td><td>Increment score by 5</td></tr>
<tr><td><code>ZCOUNT key 10 100</code></td><td>Count members with scores 10-100</td></tr>
<tr><td><code>ZPOPMIN key</code></td><td>Remove and return lowest-scored</td></tr>
<tr><td><code>ZPOPMAX key</code></td><td>Remove and return highest-scored</td></tr>
<tr><td><code>ZUNIONSTORE dest 2 k1 k2</code></td><td>Store union of sorted sets</td></tr>
<tr><td><code>ZINTERSTORE dest 2 k1 k2</code></td><td>Store intersection of sorted sets</td></tr>
</tbody>
</table>
<div class="pattern-card">
<h3>Sorted Set Examples</h3>
<pre><code class="language-bash"># Build a leaderboard
ZADD leaderboard 1500 "alice" 1200 "bob" 1800 "carol"
# Top 3 players
ZREVRANGE leaderboard 0 2 WITHSCORES
# "carol" "1800" "alice" "1500" "bob" "1200"
# Alice's rank (0-indexed, highest first)
ZREVRANK leaderboard "alice" # 1
# Increment score after a win
ZINCRBY leaderboard 100 "bob" # 1300
# Players scoring between 1300 and 1600
ZRANGEBYSCORE leaderboard 1300 1600 WITHSCORES</code></pre>
</div>
<!-- 7. Keys -->
<h2 class="section-header" id="keys">Keys</h2>
<table class="cheatsheet-table">
<thead><tr><th style="width:45%">Command</th><th>Description</th></tr></thead>
<tbody>
<tr><td><code>DEL key1 key2</code></td><td>Delete keys (blocking)</td></tr>
<tr><td><code>UNLINK key1 key2</code></td><td>Delete keys asynchronously (4.0+)</td></tr>
<tr><td><code>EXISTS key</code></td><td>Check if key exists (1 or 0)</td></tr>
<tr><td><code>EXPIRE key 60</code></td><td>Set key to expire in 60 seconds</td></tr>
<tr><td><code>PEXPIRE key 5000</code></td><td>Set expiry in milliseconds</td></tr>
<tr><td><code>TTL key</code></td><td>Remaining TTL in seconds (-1 = no expiry)</td></tr>
<tr><td><code>PTTL key</code></td><td>Remaining TTL in milliseconds</td></tr>
<tr><td><code>PERSIST key</code></td><td>Remove expiry (make permanent)</td></tr>
<tr><td><code>RENAME key newkey</code></td><td>Rename a key</td></tr>
<tr><td><code>RENAMENX key newkey</code></td><td>Rename only if newkey does not exist</td></tr>
<tr><td><code>TYPE key</code></td><td>Get the data type of a key</td></tr>
<tr><td><code>KEYS pattern*</code></td><td>Find matching keys (avoid in production!)</td></tr>
<tr><td><code>SCAN 0 MATCH pat* COUNT 100</code></td><td>Iterate keys safely (cursor-based)</td></tr>
<tr><td><code>OBJECT ENCODING key</code></td><td>Get internal encoding of value</td></tr>
<tr><td><code>COPY src dst</code></td><td>Copy key to new key (6.2+)</td></tr>
</tbody>
</table>
<div class="pattern-card">
<h3>Key Management Examples</h3>
<pre><code class="language-bash"># Set a cache key with 5-minute TTL
SET cache:query:abc "result data" EX 300
TTL cache:query:abc # 300
# Check remaining time
TTL cache:query:abc # e.g. 287
# Remove expiry (keep forever)
PERSIST cache:query:abc
TTL cache:query:abc # -1
# Safe iteration (production-friendly)
SCAN 0 MATCH user:* COUNT 100
# Returns: cursor + batch of matching keys
# Continue with returned cursor until 0
# Check data type
TYPE user:100 # "hash"
TYPE queue:jobs # "list"</code></pre>
</div>
<!-- 8. Pub/Sub -->
<h2 class="section-header" id="pubsub">Pub/Sub</h2>
<table class="cheatsheet-table">
<thead><tr><th style="width:45%">Command</th><th>Description</th></tr></thead>
<tbody>
<tr><td><code>SUBSCRIBE ch1 ch2</code></td><td>Subscribe to channels</td></tr>
<tr><td><code>PUBLISH channel "msg"</code></td><td>Publish message to a channel</td></tr>
<tr><td><code>UNSUBSCRIBE ch1</code></td><td>Unsubscribe from a channel</td></tr>
<tr><td><code>PSUBSCRIBE news.*</code></td><td>Subscribe to pattern-matched channels</td></tr>
<tr><td><code>PUNSUBSCRIBE news.*</code></td><td>Unsubscribe from pattern</td></tr>
<tr><td><code>PUBSUB CHANNELS</code></td><td>List active channels</td></tr>
<tr><td><code>PUBSUB NUMSUB ch1</code></td><td>Get subscriber count for channel</td></tr>
</tbody>
</table>
<div class="pattern-card">
<h3>Pub/Sub Examples</h3>
<pre><code class="language-bash"># Terminal 1: Subscribe to notifications
SUBSCRIBE notifications
# Waiting for messages...
# Terminal 2: Publish a message
PUBLISH notifications "User signed up"
# (integer) 1 -- one subscriber received it
# Pattern subscribe (all event channels)
PSUBSCRIBE events.*
# Matches: events.login, events.purchase, events.logout
# Check active channels
PUBSUB CHANNELS
PUBSUB NUMSUB notifications # "notifications" "1"</code></pre>
</div>
<!-- 9. Transactions -->
<h2 class="section-header" id="transactions">Transactions</h2>
<table class="cheatsheet-table">
<thead><tr><th style="width:45%">Command</th><th>Description</th></tr></thead>
<tbody>
<tr><td><code>MULTI</code></td><td>Start a transaction block</td></tr>
<tr><td><code>EXEC</code></td><td>Execute all queued commands</td></tr>
<tr><td><code>DISCARD</code></td><td>Discard queued commands, exit transaction</td></tr>
<tr><td><code>WATCH key1 key2</code></td><td>Watch keys for changes (optimistic lock)</td></tr>
<tr><td><code>UNWATCH</code></td><td>Cancel all watched keys</td></tr>
</tbody>
</table>
<div class="pattern-card">
<h3>Transaction Examples</h3>
<pre><code class="language-bash"># Basic transaction: transfer funds
MULTI
DECRBY account:alice 100
INCRBY account:bob 100
EXEC
# Both commands execute atomically
# Optimistic locking with WATCH
WATCH account:alice
balance = GET account:alice # "500"
MULTI
SET account:alice 400
SET account:bob 600
EXEC
# Returns nil if account:alice was modified by another client
# Abort a transaction
MULTI
SET key1 "val1"
DISCARD # all queued commands discarded</code></pre>
</div>
<!-- 10. Streams -->
<h2 class="section-header" id="streams">Streams</h2>
<table class="cheatsheet-table">
<thead><tr><th style="width:45%">Command</th><th>Description</th></tr></thead>
<tbody>
<tr><td><code>XADD stream * field val</code></td><td>Append entry with auto-generated ID</td></tr>
<tr><td><code>XADD stream maxlen 1000 * f v</code></td><td>Append and cap stream at 1000 entries</td></tr>
<tr><td><code>XREAD COUNT 10 STREAMS s1 0</code></td><td>Read 10 entries from start</td></tr>
<tr><td><code>XREAD BLOCK 5000 STREAMS s1 $</code></td><td>Block-read new entries (5s timeout)</td></tr>
<tr><td><code>XRANGE stream - +</code></td><td>Get all entries in stream</td></tr>
<tr><td><code>XRANGE stream - + COUNT 5</code></td><td>Get first 5 entries</td></tr>
<tr><td><code>XLEN stream</code></td><td>Get number of entries</td></tr>
<tr><td><code>XGROUP CREATE s grp 0</code></td><td>Create a consumer group</td></tr>
<tr><td><code>XREADGROUP GROUP grp c1 COUNT 5 STREAMS s ></code></td><td>Read as consumer c1 in group</td></tr>
<tr><td><code>XACK stream grp id</code></td><td>Acknowledge processed message</td></tr>
<tr><td><code>XPENDING stream grp</code></td><td>View pending (unacked) messages</td></tr>
<tr><td><code>XINFO STREAM stream</code></td><td>Get stream metadata</td></tr>
<tr><td><code>XTRIM stream MAXLEN 500</code></td><td>Trim stream to 500 entries</td></tr>
</tbody>
</table>
<div class="pattern-card">
<h3>Stream Examples</h3>
<pre><code class="language-bash"># Add events to a stream
XADD events * action "login" user "alice"
# "1707667200000-0"
XADD events * action "purchase" user "bob" amount "49.99"
# "1707667200001-0"
# Read all events
XRANGE events - +
# Create a consumer group starting from the beginning
XGROUP CREATE events workers 0
# Consumer reads pending messages
XREADGROUP GROUP workers worker-1 COUNT 5 STREAMS events >
# Acknowledge after processing
XACK events workers "1707667200000-0"
# Check unprocessed messages
XPENDING events workers</code></pre>
</div>
<!-- 11. Common Patterns -->
<h2 class="section-header" id="patterns">Common Patterns</h2>
<div class="pattern-card">
<h3>Caching (Cache-Aside)</h3>
<p>Check cache first. On miss, query the database, then store the result with a TTL to prevent stale data.</p>
<pre><code class="language-bash"># Read-through cache pseudocode
value = GET "cache:user:123"
if value is nil:
value = db.query("SELECT * FROM users WHERE id=123")
SET "cache:user:123" value EX 300 # 5-minute TTL
return value
# Invalidate on write
DEL "cache:user:123"</code></pre>
</div>
<div class="pattern-card">
<h3>Rate Limiting (Sliding Window)</h3>
<p>Use sorted sets with timestamps to enforce per-user request limits with a sliding time window.</p>
<pre><code class="language-bash"># Allow 100 requests per 60 seconds
MULTI
ZREMRANGEBYSCORE ratelimit:user:42 0 (NOW-60)
ZADD ratelimit:user:42 NOW NOW
ZCARD ratelimit:user:42
EXPIRE ratelimit:user:42 60
EXEC
# If ZCARD result > 100, reject the request</code></pre>
</div>
<div class="pattern-card">
<h3>Session Storage</h3>
<p>Store user sessions as hashes with automatic expiration. Fast reads and writes for web session data.</p>
<pre><code class="language-bash"># Create session
HSET session:tok123 user_id 42 role "admin" ip "10.0.0.1"
EXPIRE session:tok123 3600 # 1-hour TTL
# Read session data
HGETALL session:tok123
# Refresh TTL on each request
EXPIRE session:tok123 3600
# Logout: destroy session
DEL session:tok123</code></pre>
</div>
<div class="pattern-card">
<h3>Leaderboard</h3>
<p>Sorted sets provide O(log N) inserts and efficient range queries for real-time leaderboards.</p>
<pre><code class="language-bash"># Add player scores
ZADD leaderboard 1500 "alice" 1200 "bob" 1800 "carol"
# Top 5 with scores
ZREVRANGE leaderboard 0 4 WITHSCORES
# Player rank (0-indexed, highest first)
ZREVRANK leaderboard "alice" # 1
# Increment score after an event
ZINCRBY leaderboard 100 "bob" # 1300</code></pre>
</div>
<!-- FAQ Section -->
<section class="faq-section" id="faq">
<h2>Frequently Asked Questions</h2>
<div class="faq-item">
<h3>What are the main data types in Redis?</h3>
<p>Redis supports several core data types: Strings (binary-safe text or numbers), Lists (ordered collections of strings), Sets (unordered collections of unique strings), Sorted Sets (sets ordered by a score), Hashes (field-value maps similar to objects), Streams (append-only log structures), and additional types like Bitmaps, HyperLogLogs, and Geospatial indexes. Each type has specialized commands optimized for its access patterns.</p>
</div>
<div class="faq-item">
<h3>What is the difference between DEL and UNLINK in Redis?</h3>
<p>DEL removes keys synchronously, blocking the server until the operation completes. For large keys (big lists, sets, or hashes), this can cause noticeable latency. UNLINK (available since Redis 4.0) removes keys asynchronously by unlinking them from the keyspace immediately and reclaiming memory in a background thread. Use UNLINK for large keys in production to avoid blocking the main Redis thread.</p>
</div>
<div class="faq-item">
<h3>How do Redis Streams differ from Pub/Sub?</h3>
<p>Redis Pub/Sub is fire-and-forget: messages are delivered to subscribers in real time but are lost if no subscriber is listening. Redis Streams (introduced in Redis 5.0) are persistent, append-only log structures that store messages with unique IDs. Streams support consumer groups for load-balanced processing, message acknowledgment, and the ability to read historical messages. Use Pub/Sub for ephemeral notifications and Streams for reliable message processing that requires durability and replay.</p>
</div>
<div class="faq-item">
<h3>How should I use KEYS vs SCAN in production?</h3>
<p>Never use the KEYS command in production because it scans the entire keyspace in a single blocking operation, which can freeze your Redis instance for seconds on large databases. Instead, use SCAN with a cursor-based approach. SCAN incrementally iterates through keys without blocking, returning a small batch per call. Combine it with MATCH for pattern filtering and COUNT to hint at batch size. For hash, set, and sorted set iteration, use HSCAN, SSCAN, and ZSCAN respectively.</p>
</div>
</section>
<!-- Related Resources -->
<section class="related-tools">
<h3>Related Resources</h3>
<div class="grid">
<a href="/index.html?search=docker-containers-beginners-guide" class="tool-card">
<h3>Docker Beginners Guide</h3>
<p>Get started with containers and Docker</p>
</a>
<a href="/index.html?search=docker-commands" class="tool-card">
<h3>Docker Commands</h3>
<p>Docker CLI quick reference</p>
</a>
<a href="/json-formatter.html" class="tool-card">
<h3>JSON Formatter</h3>
<p>Format and validate JSON data</p>
</a>
<a href="/index.html?search=sql-basics" class="tool-card">
<h3>SQL Basics</h3>
<p>SQL commands cheat sheet</p>
</a>
<a href="/index.html?search=linux-commands" class="tool-card">
<h3>Linux Commands</h3>
<p>Essential Linux terminal commands</p>
</a>
</div>
</section>
</main>
<footer><p>DevToolbox — Free developer tools, no strings attached.</p></footer>
<script>
document.getElementById('search').addEventListener('input',function(e){
const q=e.target.value.toLowerCase();
document.querySelectorAll('.cheatsheet-table tr').forEach(r=>{
if(r.querySelector('th')){r.style.display='';return;}
r.style.display=r.textContent.toLowerCase().includes(q)?'':'none';
});
});
document.addEventListener('keydown', function(e) {
if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
e.preventDefault();
document.getElementById('search').focus();
document.getElementById('search').select();
}
});
</script>
<script src="/js/track.js" defer></script>
</body>
</html>