{"id":1150,"date":"2026-08-19T02:09:28","date_gmt":"2026-08-19T02:09:28","guid":{"rendered":"https:\/\/www.devopsschool.com\/tutorials\/?p=1150"},"modified":"2026-08-19T02:09:29","modified_gmt":"2026-08-19T02:09:29","slug":"redis-tutorials-a-complete-fundamental-turorials","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/tutorials\/redis-tutorials-a-complete-fundamental-turorials\/","title":{"rendered":"Redis Tutorials: A Complete Fundamental Turorials"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">From Fundamentals to Production-Grade Caching, Sessions, Pub\/Sub, Counters, Locks and Failure Handling<\/h2>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">1. What is Redis?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Redis<\/strong> is a high-performance, primarily in-memory data store.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The easiest mental model is:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Redis is a shared, extremely fast data-structure server that applications access over the network.<\/strong><\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Instead of limiting you to simple <code>key \u2192 value<\/code> pairs, Redis lets the value associated with a key be a <strong>String, Hash, List, Set, Sorted Set, Stream, and several other specialized structures<\/strong>. Redis officially describes itself as an in-memory data store that can be used for caching, messaging, streaming, document\/vector workloads and other use cases, with replication and optional disk persistence.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A simple application might look like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart LR\n    U&#91;User] --&gt; A&#91;Application]\n    A --&gt; R&#91;(Redis)]\n    A --&gt; D&#91;(Database)]\n\n    R --&gt;|Fast cached data| A\n    D --&gt;|Source of truth| A\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Without Redis:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Application\n     |\n     | SQL query\n     v\n Database\n     |\n     | 20-200 ms\n     v\n Application\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">With Redis:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Application\n     |\n     | GET product:100\n     v\n   Redis\n     |\n     | Often sub-millisecond \/ low-millisecond\n     v\n Application\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The exact latency depends on network, deployment, workload and payload size, but the important idea is:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>memory access is normally much faster than repeatedly performing expensive database queries or external API calls.<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">2. Why Does Redis Exist?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Imagine an e-commerce site.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Thousands of customers repeatedly request:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Product ID: 100\nName: MacBook Pro\nPrice: \u20b9180000\nCategory: Laptop\nAvailability: In Stock\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Without caching:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Customer 1 \u2500\u2500\u2192 Database\nCustomer 2 \u2500\u2500\u2192 Database\nCustomer 3 \u2500\u2500\u2192 Database\nCustomer 4 \u2500\u2500\u2192 Database\nCustomer 5 \u2500\u2500\u2192 Database\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The database repeatedly performs essentially the same work.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With Redis:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>                 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\nCustomer \u2500\u2500\u2500\u2500\u2500\u2500\u2500&gt;\u2502 Application  \u2502\n                 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                        |\n                    Check Redis\n                        |\n              \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n              \u2502       Redis       \u2502\n              \u2502 product:100       \u2502\n              \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                        |\n                   Cache HIT\n                        |\n                        v\n                     Return\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Only when Redis does not have the data does the application normally query the database.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">3. Redis Is Not Just a Cache<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">This is one of the most important Redis concepts.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Redis can be used for:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Requirement<\/th><th>Redis capability<\/th><\/tr><\/thead><tbody><tr><td>Application caching<\/td><td>Strings \/ Hashes<\/td><\/tr><tr><td>User sessions<\/td><td>Strings \/ Hashes + TTL<\/td><\/tr><tr><td>Counters<\/td><td><code>INCR<\/code>, <code>INCRBY<\/code><\/td><\/tr><tr><td>Leaderboards<\/td><td>Sorted Sets<\/td><\/tr><tr><td>Unique membership<\/td><td>Sets<\/td><\/tr><tr><td>Queues<\/td><td>Lists \/ Streams<\/td><\/tr><tr><td>Live notifications<\/td><td>Pub\/Sub<\/td><\/tr><tr><td>Event processing<\/td><td>Streams<\/td><\/tr><tr><td>Rate limiting<\/td><td>Counters + expiration<\/td><\/tr><tr><td>Temporary distributed coordination<\/td><td><code>SET NX<\/code><\/td><\/tr><tr><td>Geospatial lookup<\/td><td>Geospatial indexes<\/td><\/tr><tr><td>Unique visitor estimation<\/td><td>HyperLogLog<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Redis&#8217; current documentation describes Redis as a <strong>data structure server<\/strong>, with native structures intended for use cases ranging from caching and queuing to event processing.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">4. Redis Architecture \u2014 Simple Mental Model<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Redis normally sits between your application and slower systems.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart TB\n\n    USER&#91;Users]\n\n    LB&#91;Load Balancer]\n\n    A1&#91;Application Instance 1]\n    A2&#91;Application Instance 2]\n    A3&#91;Application Instance 3]\n\n    R&#91;(Redis)]\n\n    DB&#91;(Primary Database)]\n\n    USER --&gt; LB\n\n    LB --&gt; A1\n    LB --&gt; A2\n    LB --&gt; A3\n\n    A1 --&gt; R\n    A2 --&gt; R\n    A3 --&gt; R\n\n    A1 --&gt; DB\n    A2 --&gt; DB\n    A3 --&gt; DB\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redis provides something extremely useful here:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>shared fast state.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Application instances do not need to keep everything inside their own memory.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>App-1 local memory \u2260 App-2 local memory\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">But:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>App-1 \u2500\u2500\u2510\nApp-2 \u2500\u2500\u253c\u2500\u2500&gt; Same Redis\nApp-3 \u2500\u2500\u2518\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">All application instances can access the same session, counter, cached object or temporary lock.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">5. Running Redis Locally<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">For learning, Docker is one of the easiest approaches. Redis&#8217; official documentation provides Docker as one of its supported installation\/run options.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Start Redis:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker run --name redis-lab \\\n  -p 6379:6379 \\\n  -d redis\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check the container:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker ps\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Open Redis CLI:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker exec -it redis-lab redis-cli\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Test Redis:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PING\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Result:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PONG\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Your Redis environment is ready.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">6. Your First Redis Commands<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Store something:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SET name \"Rajesh\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Read it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET name\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Result:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"Rajesh\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Delete it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>DEL name\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check whether it exists:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>EXISTS name\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expiration:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SET verification_code \"928431\" EX 300\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This means:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Key   = verification_code\nValue = 928431\nTTL   = 300 seconds\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check remaining TTL:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>TTL verification_code\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redis supports expiration directly as part of <code>SET<\/code> as well as through expiration commands such as <code>EXPIRE<\/code>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">7. Keys Are Extremely Important<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Redis applications commonly use readable hierarchical key names.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Instead of:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>123\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">prefer:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>user:123\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For a session:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>session:a81fc92\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For a product:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>product:1001\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For a shopping cart:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cart:user:100\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For a rate limiter:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rate:user:100:2026-08-19T07:33\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For a temporary lock:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>lock:order:5432\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A useful convention is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;domain&gt;:&lt;entity&gt;:&lt;id&gt;\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ecommerce:product:1001\necommerce:user:700\necommerce:session:abc123\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Good key naming dramatically improves debugging and operations.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">8. Redis Data Structures<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Redis&#8217; most important characteristic is that values are not all treated as identical blobs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The core structures you should understand first are:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Structure<\/th><th>Think of it as<\/th><th>Common use case<\/th><\/tr><\/thead><tbody><tr><td>String<\/td><td>Single value<\/td><td>Cache, token, counter<\/td><\/tr><tr><td>Hash<\/td><td>Object \/ record<\/td><td>User, product, session<\/td><\/tr><tr><td>List<\/td><td>Ordered sequence<\/td><td>Queue<\/td><\/tr><tr><td>Set<\/td><td>Unique collection<\/td><td>Tags, membership<\/td><\/tr><tr><td>Sorted Set<\/td><td>Ranked collection<\/td><td>Leaderboard<\/td><\/tr><tr><td>Stream<\/td><td>Append-only event log<\/td><td>Event processing<\/td><\/tr><tr><td>Bitmap<\/td><td>Bits<\/td><td>Daily activity flags<\/td><\/tr><tr><td>HyperLogLog<\/td><td>Approximate unique count<\/td><td>Unique visitors<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Redis currently supports an even broader collection of native and specialized data types, but mastering these core structures gives you the foundation for most application workloads.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">9. Redis String<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A Redis String is the simplest structure.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>key \u2192 value\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SET product:100:name \"iPhone\"\nGET product:100:name\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Strings are ideal for:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>cached JSON<\/li>\n\n\n\n<li>tokens<\/li>\n\n\n\n<li>OTPs<\/li>\n\n\n\n<li>feature flags<\/li>\n\n\n\n<li>configuration<\/li>\n\n\n\n<li>counters<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Example JSON:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SET product:100 '{\"name\":\"iPhone\",\"price\":80000}'\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Retrieve:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET product:100\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\"name\":\"iPhone\",\"price\":80000}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">When should you use String?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Use String when:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>One key represents one logical value.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>user:100:last_login \u2192 \"2026-08-19\"\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">10. Redis Hash<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A Hash represents an object containing fields.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Think:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>user:100\n   |\n   +-- name  = Asha\n   +-- city  = Delhi\n   +-- age   = 30\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Commands:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>HSET user:100 name \"Asha\" city \"Delhi\" age 30\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Read one field:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>HGET user:100 name\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Read everything:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>HGETALL user:100\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Update one field:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>HSET user:100 city \"Mumbai\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A Redis Hash naturally represents many application records because Redis hashes are field-value collections similar to dictionaries or maps in programming languages.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Appropriate use cases<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>User profile\nShopping cart\nSession information\nProduct metadata\nApplication configuration\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">11. Redis List<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A List is an ordered sequence.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Task A\nTask B\nTask C\nTask D\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Add:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>LPUSH jobs \"send-email\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Add another:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>LPUSH jobs \"generate-report\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Read:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>LRANGE jobs 0 -1\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redis lists preserve insertion ordering.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">They can be useful for simple queue-like workloads.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">For sophisticated durable event processing, retries, consumer groups and replay, consider Redis Streams or a dedicated messaging platform rather than treating a List as a complete messaging system.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">12. Redis Set<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A Set contains <strong>unique values<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SADD product:100:tags electronics\nSADD product:100:tags mobile\nSADD product:100:tags apple\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Get members:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SMEMBERS product:100:tags\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Adding <code>apple<\/code> again:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SADD product:100:tags apple\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">does not create a duplicate.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Think:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Set = unique unordered collection\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Typical use cases:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>User roles\nPermissions\nUnique tags\nOnline users\nGroup membership\nUnique categories\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redis sets support constant-time add, remove and membership checks in typical cases.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">13. Redis Sorted Set<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A Sorted Set contains unique members, but every member has a <strong>score<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example leaderboard:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ZADD leaderboard 500 Alice\nZADD leaderboard 900 Bob\nZADD leaderboard 700 Charlie\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Read ranking:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ZRANGE leaderboard 0 -1 WITHSCORES\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Conceptually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Bob       900\nCharlie   700\nAlice     500\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Use Sorted Sets for:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Leaderboards\nPriority systems\nRanking\nScores\nScheduling\nTop-N queries\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The difference is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SET\nUnique values\n\nSORTED SET\nUnique values + score + ordering\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redis defines sorted sets as unique strings maintained in order according to their associated score.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">14. Redis Streams<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A Stream is fundamentally different.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Think:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Event 1\nEvent 2\nEvent 3\nEvent 4\n        \u2193\nnew events keep arriving\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>XADD orders * order_id 1001 status created\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Another:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>XADD orders * order_id 1002 status created\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Read:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>XRANGE orders - +\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redis describes Streams as an <strong>append-only log<\/strong> designed to record events in sequence and make them available for processing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Good use cases include:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Order events\nAudit events\nTelemetry\nBackground processing\nConsumer groups\nDurable event workflows\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">15. Data Structure Decision Guide<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A very practical way to remember Redis structures is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Need one value?\n        |\n      String\n\nNeed object fields?\n        |\n       Hash\n\nNeed ordered queue?\n        |\n       List\n\nNeed unique values?\n        |\n       Set\n\nNeed ranking?\n        |\n    Sorted Set\n\nNeed durable event log?\n        |\n      Stream\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Or:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Requirement<\/th><th>Choose<\/th><\/tr><\/thead><tbody><tr><td>Cache product JSON<\/td><td>String<\/td><\/tr><tr><td>Store session fields<\/td><td>Hash<\/td><\/tr><tr><td>Simple task queue<\/td><td>List<\/td><\/tr><tr><td>Unique users<\/td><td>Set<\/td><\/tr><tr><td>Leaderboard<\/td><td>Sorted Set<\/td><\/tr><tr><td>Durable event processing<\/td><td>Stream<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">16. What Is Caching?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Caching means:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Store expensive-to-obtain data somewhere faster so the next request does not have to perform the expensive operation again.<\/strong><\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Database query = 80 ms\nRedis GET      = much faster\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Instead of hitting the database 10,000 times for the same product:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Database\nDatabase\nDatabase\nDatabase\nDatabase\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">we cache it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>             Redis\n           \/ \/ | \\ \\\n        request request\n             |\n        Database only\n        when necessary\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">17. Cache Hit and Cache Miss<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">These two terms are fundamental.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Cache HIT<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Application asks Redis:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET product:100\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redis has it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Application\n     |\n     v\n   Redis\n     |\n    HIT\n     |\n     v\n  Response\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">No database query is needed.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Cache MISS<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Redis does not have it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Application\n     |\n     v\n   Redis\n     |\n    MISS\n     |\n     v\n Database\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The application fetches the data and normally stores it in Redis.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">18. Cache-Aside Pattern<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Cache-aside is probably the most important Redis caching pattern to learn.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It is also called:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Lazy Loading\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <strong>application<\/strong> manages the cache.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The process is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart TD\n\n    A&#91;Application receives request]\n\n    B{Data in Redis?}\n\n    C&#91;Return cached data]\n\n    D&#91;Query Database]\n\n    E&#91;Store result in Redis]\n\n    F&#91;Return result]\n\n    A --&gt; B\n\n    B --&gt;|Yes - HIT| C\n    B --&gt;|No - MISS| D\n\n    D --&gt; E\n    E --&gt; F\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Algorithm:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>1. Check Redis.\n2. If found \u2192 return it.\n3. If not found \u2192 query database.\n4. Put database result into Redis.\n5. Return result.\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">19. Cache-Aside Example<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Assume:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET \/products\/100\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Pseudo-code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def get_product(product_id):\n\n    key = f\"product:{product_id}\"\n\n    # Step 1: Check Redis\n    cached = redis.get(key)\n\n    if cached:\n        return cached\n\n    # Step 2: Cache miss\n    product = database.find_product(product_id)\n\n    # Step 3: Put data into Redis\n    redis.set(key, product, ex=300)\n\n    # Step 4: Return result\n    return product\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The first request looks like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Client\n  |\n  v\nApplication\n  |\n  | GET product:100\n  v\nRedis\n  |\n MISS\n  |\n  v\nDatabase\n  |\n Product\n  |\n  v\nRedis SET + TTL\n  |\n  v\nClient\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Second request:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Client\n  |\n  v\nApplication\n  |\n  v\nRedis\n  |\n HIT\n  |\n  v\nClient\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">No database access.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">20. Why Cache-Aside Is So Popular<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">It has several attractive properties.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The database remains the <strong>source of truth<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Redis contains copies of frequently accessed data.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If Redis loses a cache entry:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Not catastrophic\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">because the application can recreate it from the database.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This architecture is extremely common:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Redis = optimization\nDatabase = authority\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That distinction is one of the safest Redis design principles.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">21. The Problem With Cache-Aside<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Caching introduces another copy of the data.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Database:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>product:100.price = \u20b980,000\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redis:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>product:100.price = \u20b980,000\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Someone updates the database:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>product:100.price = \u20b975,000\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">But Redis still contains:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u20b980,000\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You now have:<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Stale Data<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">That leads directly to one of the hardest caching problems:<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Cache Invalidation<\/h1>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">22. Read-Through \/ Cache-Through<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">In cache-aside:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Application knows how to load the cache.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Conceptually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Application\n   |\n   +---- Redis\n   |\n   +---- Database\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In a <strong>read-through\/cache-through abstraction<\/strong>, the application interacts with a cache layer:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Application\n     |\n     v\nCache Layer\n     |\n     +---- Redis\n     |\n     +---- Database loader\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When data is missing:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Cache Layer\n     |\n     v\nDatabase\n     |\n     v\nRedis\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The difference is primarily <strong>who owns the loading logic<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Redis commands themselves do not magically execute your SQL query because <code>GET<\/code> misses. A framework, library or application layer implements that behavior.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">23. Write-Through Caching<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Write-through means:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">When the application writes data, the authoritative store and cache are updated as part of the write path.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Conceptually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart LR\n\n    A&#91;Application]\n    C&#91;Cache Layer]\n    R&#91;(Redis)]\n    D&#91;(Database)]\n\n    A --&gt;|Write| C\n    C --&gt; D\n    C --&gt; R\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>UPDATE product price\n        |\n        +----&gt; Database = \u20b975,000\n        |\n        +----&gt; Redis    = \u20b975,000\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The goal is to keep Redis warm and synchronized.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">24. Write-Behind \/ Write-Back<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Another architecture sometimes discussed alongside these patterns is <strong>write-behind<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Application\n     |\n     v\n   Cache\n     |\n     | asynchronous\n     v\n Database\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The application may return before the database has been updated.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Advantage:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Very fast writes\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Risk:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Cache failure before persistence\n      \u2193\nPotential data loss\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This pattern requires much more careful durability design.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For ordinary application caching, cache-aside or well-designed write-through strategies are usually easier to reason about.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">25. Cache Pattern Comparison<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Pattern<\/th><th>Read miss handled by<\/th><th>Writes handled by<\/th><th>Complexity<\/th><th>Typical use<\/th><\/tr><\/thead><tbody><tr><td>Cache-aside<\/td><td>Application<\/td><td>Application\/DB<\/td><td>Low<\/td><td>Most applications<\/td><\/tr><tr><td>Read-through<\/td><td>Cache abstraction<\/td><td>Application<\/td><td>Medium<\/td><td>Framework-managed caching<\/td><\/tr><tr><td>Write-through<\/td><td>Cache abstraction<\/td><td>Cache + DB<\/td><td>Medium<\/td><td>Frequently read data<\/td><\/tr><tr><td>Write-behind<\/td><td>Cache layer<\/td><td>Eventually DB<\/td><td>High<\/td><td>Specialized high-write workloads<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The easiest pattern for most developers to start with is:<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Cache-Aside<\/h1>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">26. TTL \u2014 Time To Live<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">TTL determines how long a cached value remains valid.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SET product:100 \"...\" EX 300\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">means:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Store this key for 300 seconds.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">After that:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Redis removes\/expires it.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>TTL product:100\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">27. Why TTL Is Important<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Without TTL:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Old cache entries\n      +\nUnused cache entries\n      +\nPotentially stale values\n      =\nMemory and correctness problems\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">TTL provides a safety mechanism.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>TTL is not a replacement for proper invalidation when freshness matters.<\/strong><\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">28. How Should You Select TTL?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">This question does <strong>not<\/strong> have one universal answer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Do not think:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Redis TTL should always be 5 minutes.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Instead ask:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>How stale is this data allowed to become?\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Examples:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Data<\/th><th>Possible TTL<\/th><\/tr><\/thead><tbody><tr><td>Country list<\/td><td>Hours \/ days<\/td><\/tr><tr><td>Product description<\/td><td>Minutes \/ hours<\/td><\/tr><tr><td>Product price<\/td><td>Shorter<\/td><\/tr><tr><td>Inventory<\/td><td>Seconds or event-invalidated<\/td><\/tr><tr><td>User profile<\/td><td>Minutes<\/td><\/tr><tr><td>OTP<\/td><td>1\u201310 minutes<\/td><\/tr><tr><td>Session<\/td><td>Based on session policy<\/td><\/tr><tr><td>Static configuration<\/td><td>Long<\/td><\/tr><tr><td>Real-time balance<\/td><td>Often avoid ordinary stale caching<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The correct TTL comes primarily from the application&#8217;s <strong>freshness requirement<\/strong>, not from a Redis rule.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">29. TTL Decision Model<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Consider four things:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Business freshness requirement\n          +\nHow frequently data changes\n          +\nCost of rebuilding cache\n          +\nTraffic \/ database capacity\n          =\nTTL decision\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Product Description\nchanges once per week\n\u2193\nTTL could be relatively long\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">But:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Flash Sale Price\nchanges frequently\n\u2193\nLong TTL could be dangerous\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">30. TTL Jitter<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Imagine 100,000 product keys are populated at 10:00 AM with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>TTL = exactly 3600 seconds\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">At 11:00 AM:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>100,000 keys expire\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Suddenly:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>100,000 requests \u2192 database\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This can cause a cache stampede.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Instead of identical TTLs:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>3600\n3600\n3600\n3600\n3600\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">use jitter:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>3412\n3678\n3554\n3721\n3498\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ttl = 3600 + random.randint(-300, 300)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now expiration is distributed across time.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">31. Absolute vs Sliding Expiration<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Absolute expiration<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Session:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Created 09:00\nExpires 10:00\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Usage does not extend it.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Sliding expiration<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Every valid activity refreshes expiration.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>09:00 login\n      |\n09:20 activity \u2192 expiry becomes 10:20\n      |\n09:50 activity \u2192 expiry becomes 10:50\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Sliding expiration is common for user sessions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, security-sensitive applications may combine:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Idle timeout\n+\nMaximum absolute lifetime\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">so a session cannot live forever.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">32. Cache Invalidation<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Cache invalidation means:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Removing or replacing cached data when the underlying authoritative data changes.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Database\nproduct:100\nprice = \u20b980,000\n\nRedis\nproduct:100\nprice = \u20b980,000\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Price changes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Database = \u20b975,000\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">What should happen to Redis?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You need an invalidation strategy.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">33. Strategy 1 \u2014 TTL-Only Invalidation<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Update DB:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Database = \u20b975,000\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Do nothing to Redis.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wait until:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>TTL expires\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Simple but potentially stale.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use when:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Temporary staleness is acceptable.\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">34. Strategy 2 \u2014 Delete Cache After Database Update<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">One of the most common strategies is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>1. Update Database\n2. Delete Redis key\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>database.update_product(product)\n\nredis.delete(f\"product:{product.id}\")\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Next request:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Redis MISS\n    |\n    v\nDatabase\n    |\n    v\nFresh data\n    |\n    v\nRedis\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is often safer than trying to independently reconstruct the exact cached representation during every write.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">35. Strategy 3 \u2014 Update the Cache<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Another option:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>UPDATE database\nUPDATE Redis\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>database.update_product(product)\n\nredis.set(\n    f\"product:{product.id}\",\n    serialize(product),\n    ex=300\n)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Advantage:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Cache remains warm.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">But application logic becomes more complicated because every write path must correctly update every relevant cache key.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">36. Strategy 4 \u2014 Event-Driven Invalidation<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Large systems often use events.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Product Service\n      |\n      | ProductUpdated\n      v\nMessage Broker\n      |\n      v\nCache Invalidation Worker\n      |\n      v\nRedis DEL product:100\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This helps when many systems maintain derived caches.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">37. Cache Invalidation Golden Rule<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Think of cached data as:<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">A derived copy<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">not:<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Automatically synchronized truth<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">The system must answer:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Who updates the authoritative data?\n\nWho invalidates the cache?\n\nWhat happens if invalidation fails?\n\nHow stale may the cache become?\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">TTL should frequently remain as a <strong>backup safety mechanism<\/strong> even if you actively invalidate keys.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">38. Cache Stampede<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Now consider this very common failure.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A popular key:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>homepage:recommendations\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">receives:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>20,000 requests\/second\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redis contains it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Everything works:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>20,000 requests\n       |\n       v\n     Redis\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then the key expires.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">All requests see:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CACHE MISS\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And all query the database.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart TD\n\n    K&#91;Popular Redis key expires]\n\n    A1&#91;Request 1]\n    A2&#91;Request 2]\n    A3&#91;Request 3]\n    A4&#91;Request 10,000]\n\n    DB&#91;(Database)]\n\n    K --&gt; A1\n    K --&gt; A2\n    K --&gt; A3\n    K --&gt; A4\n\n    A1 --&gt; DB\n    A2 --&gt; DB\n    A3 --&gt; DB\n    A4 --&gt; DB\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is:<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Cache Stampede<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">also called:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Thundering Herd\nDogpile Effect\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">39. Why Cache Stampede Is Dangerous<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Normally:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Redis protects database.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">During a stampede:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Redis key expires\n        \u2193\nHuge number of cache misses\n        \u2193\nHuge database traffic\n        \u2193\nDatabase slows down\n        \u2193\nRequests take longer\n        \u2193\nEven more requests accumulate\n        \u2193\nPossible outage\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A cache that was intended to protect the database can therefore contribute to a sudden load spike if expiration is not designed carefully.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">40. Stampede Protection \u2014 TTL Jitter<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">First technique:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Do not expire thousands of related keys simultaneously.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Instead:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>baseTTL + random jitter\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ttl = 300 + random.randint(0, 60)\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">41. Stampede Protection \u2014 Single Refresher<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Instead of allowing every request to rebuild the cache:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Request A \u2192 obtains refresh lock\nRequest B \u2192 waits \/ serves stale\nRequest C \u2192 waits \/ serves stale\nRequest D \u2192 waits \/ serves stale\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Only:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Request A \u2192 Database\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once refreshed:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Redis populated\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">and other requests use the new value.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">42. Stale-While-Revalidate<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Another powerful pattern:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Cache value exists\nbut soft TTL expired\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Instead of blocking the customer:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Return slightly stale value\n        +\nRefresh cache in background\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Conceptually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>                    \u250c\u2500\u2500&gt; Return stale value\nRequest \u2192 Redis \u2500\u2500\u2500\u2500\u2524\n                    \u2514\u2500\u2500&gt; One worker refreshes\n                              |\n                              v\n                           Database\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This can be excellent for:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Homepages\nRecommendations\nContent\nCatalog information\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It may be unacceptable for:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Account balances\nCritical inventory guarantees\nSecurity permissions\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The business meaning of stale data matters.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">43. Stale Data Risk<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Caching always creates the possibility of:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Database value \u2260 cached value\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Database inventory = 0\n\nRedis inventory = 5\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If Redis is blindly trusted:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Customer may purchase nonexistent stock.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Therefore ask:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Is the data informational, or is it authoritative for a critical decision?<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">For critical decisions:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Redis can accelerate the process\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">but the authoritative transactional system may still need to validate the final action.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">44. Redis Pub\/Sub<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Pub\/Sub stands for:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Publish \/ Subscribe\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Components:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Publisher\nChannel\nSubscriber\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart LR\n\n    P&#91;Order Service]\n\n    C((order-events))\n\n    S1&#91;Email Service]\n    S2&#91;Notification Service]\n    S3&#91;WebSocket Service]\n\n    P --&gt;|Publish| C\n\n    C --&gt; S1\n    C --&gt; S2\n    C --&gt; S3\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redis uses commands such as:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SUBSCRIBE\nPUBLISH\nUNSUBSCRIBE\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">for this model.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">45. Redis Pub\/Sub Example<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Terminal 1:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SUBSCRIBE orders\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Terminal 2:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PUBLISH orders \"order-1001-created\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Subscriber receives the message.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Another example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PUBLISH notifications \"user-100-logged-in\"\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">46. Pub\/Sub Is Not a Durable Queue<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">This is critical.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Redis Pub\/Sub provides <strong>at-most-once delivery<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If a subscriber is disconnected when the message is published:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Message can be lost permanently.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redis explicitly documents this behavior and recommends Streams when stronger delivery guarantees and persistence are required.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Think:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Pub\/Sub\n\n\"Who is listening RIGHT NOW?\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">versus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Stream\n\n\"Record this event so consumers can process it.\"\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">47. Pub\/Sub vs Redis Streams<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Feature<\/th><th>Pub\/Sub<\/th><th>Streams<\/th><\/tr><\/thead><tbody><tr><td>Persistent messages<\/td><td>No<\/td><td>Yes<\/td><\/tr><tr><td>Offline consumer receives old message<\/td><td>No<\/td><td>Possible<\/td><\/tr><tr><td>Consumer groups<\/td><td>No<\/td><td>Yes<\/td><\/tr><tr><td>Replay<\/td><td>No<\/td><td>Yes<\/td><\/tr><tr><td>Simple live broadcast<\/td><td>Excellent<\/td><td>Possible<\/td><\/tr><tr><td>Durable processing<\/td><td>Poor fit<\/td><td>Good fit<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Use Pub\/Sub for:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Live notifications\nWebSocket fan-out\nLive dashboards\nCache invalidation notification\nEphemeral events\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Use Streams when:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Events must not simply disappear because a consumer disconnected.\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">48. Redis Pub\/Sub vs Kafka<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">They solve overlapping but different problems.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Redis Pub\/Sub\n       \u2193\nFast ephemeral broadcast\n<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>Kafka\n       \u2193\nDurable distributed event log\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A useful simplified comparison:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Requirement<\/th><th>Redis Pub\/Sub<\/th><th>Kafka<\/th><\/tr><\/thead><tbody><tr><td>Live broadcast<\/td><td>Excellent<\/td><td>Yes<\/td><\/tr><tr><td>Durable event log<\/td><td>No<\/td><td>Yes<\/td><\/tr><tr><td>Replay<\/td><td>No<\/td><td>Yes<\/td><\/tr><tr><td>Long retention<\/td><td>No<\/td><td>Yes<\/td><\/tr><tr><td>Consumer offsets<\/td><td>No<\/td><td>Yes<\/td><\/tr><tr><td>Very simple notifications<\/td><td>Excellent<\/td><td>Often overkill<\/td><\/tr><tr><td>Enterprise event backbone<\/td><td>Usually no<\/td><td>Strong fit<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Do not automatically replace Kafka with Redis Pub\/Sub simply because both can transmit messages.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">49. Redis for User Sessions<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Sessions are one of Redis&#8217; classic use cases.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Imagine three application instances:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart TB\n\n    U&#91;User]\n\n    LB&#91;Load Balancer]\n\n    A1&#91;App 1]\n    A2&#91;App 2]\n    A3&#91;App 3]\n\n    R&#91;(Redis Session Store)]\n\n    U --&gt; LB\n\n    LB --&gt; A1\n    LB --&gt; A2\n    LB --&gt; A3\n\n    A1 --&gt; R\n    A2 --&gt; R\n    A3 --&gt; R\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Without shared session storage:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>User logs in through App-1.\n\nNext request goes to App-2.\n\nApp-2:\n\"Who are you?\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">With Redis:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>App-1\nApp-2\nApp-3\n   |\n   v\nSame Redis session\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Any application instance can resolve the session.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">50. Session Example<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Key:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>session:f81d4fae\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Hash:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>HSET session:f81d4fae \\\n    user_id 100 \\\n    role admin \\\n    authenticated true\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expiration:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>EXPIRE session:f81d4fae 1800\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Meaning:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Session expires after 30 minutes\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">On logout:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>DEL session:f81d4fae\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">51. Session Design Recommendations<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A session should normally have an expiration policy.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Avoid:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>session:* with no expiration forever\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Also avoid placing unnecessary sensitive information directly into session objects.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Prefer:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Session ID\nUser ID\nAuthorization\/context information needed for session\nTimestamps\nMinimal metadata\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Keep the authoritative user\/account records elsewhere unless Redis has deliberately been designed as their primary system.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">52. Distributed Counters<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Imagine ten application servers.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">All must increment:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Number of API requests\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Local counters do not work:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>App-1 = 100\nApp-2 = 200\nApp-3 = 170\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redis provides shared counters:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>            Redis\n              |\n       api_requests = 470\n        \/     |      \\\n      App1   App2    App3\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">53. <code>INCR<\/code><\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Initialize:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SET pageviews 0\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Increment:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>INCR pageviews\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Again:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>INCR pageviews\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Result:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>2\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Add 10:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>INCRBY pageviews 10\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Result:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>12\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redis performs these counter operations atomically, which makes them extremely useful when many application instances modify the same counter.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">54. Counter Use Cases<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Counters work well for:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Page views\nAPI calls\nDownloads\nLogin attempts\nRate limiting\nUsage quotas\nVotes\nTemporary metrics\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>INCR article:500:views\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Ten application instances can safely increment the same Redis key.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">55. Simple Rate Limiting<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Maximum = 100 requests\/minute\/user\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Key:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rate:user:100:202608190733\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">First request:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SET rate:user:100:202608190733 1 EX 60 NX\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Subsequent requests:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>INCR rate:user:100:202608190733\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If counter becomes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>101\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">reject the request.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Concept:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Request\n   |\n   v\nINCR counter\n   |\n   +-- &lt;= 100 \u2192 Allow\n   |\n   +-- &gt; 100  \u2192 Reject\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Production-grade rate limiting may use Lua scripts, sorted sets or other algorithms such as sliding windows or token buckets depending on fairness and precision requirements.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">56. Lightweight Distributed Locks<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose two workers attempt:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Generate invoice 1001\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">at the same time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Without coordination:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Worker A \u2500\u2500&gt; Generate\nWorker B \u2500\u2500&gt; Generate\n\nPossible duplicate invoice\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A Redis lock can coordinate temporary access.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">57. Basic Redis Lock<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Use:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SET lock:invoice:1001 abc123 NX EX 10\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Meaning:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SET     = create key\nNX      = only if key does not already exist\nEX 10   = automatically expire after 10 seconds\nabc123  = unique owner token\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redis&#8217; <code>SET<\/code> command supports conditional creation with <code>NX<\/code> and expiration with <code>EX<\/code>\/<code>PX<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If successful:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Worker owns lock.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If it fails:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Someone else owns lock.\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">58. Why Lock Expiration Is Essential<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Never create:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SET lock:invoice:1001 locked NX\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">without thinking about failure.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Worker obtains lock\n      |\n      v\nWorker crashes\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Lock remains forever.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Nobody can process invoice 1001.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expiration creates a <strong>lease<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Lock eventually disappears.\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">59. Do Not Blindly Delete Somebody Else&#8217;s Lock<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Consider:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Worker A obtains lock for 10 sec.\n\nWorker A becomes slow.\n\nLock expires.\n\nWorker B obtains new lock.\n\nWorker A wakes up.\n\nWorker A executes DEL lock.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Worker A has accidentally deleted:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Worker B's lock.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That is why the value should contain a unique ownership token.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>lock:invoice:1001\n         |\n         v\n550e8400-e29b-41d4-a716\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The owner should release the lock only if the stored token still belongs to it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A classic safe release is an atomic compare-and-delete operation, often implemented with a small Lua script.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if redis.call(\"GET\", KEYS&#91;1]) == ARGV&#91;1] then\n    return redis.call(\"DEL\", KEYS&#91;1])\nelse\n    return 0\nend\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">60. What Redis Locks Are Good For<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Good examples:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Prevent duplicate background refresh\nCoordinate cache rebuild\nPrevent duplicate scheduled job\nShort-lived idempotency coordination\nTemporary singleton work\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Be more cautious with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Bank transfer correctness\nFinancial settlement\nStrict leader election\nIrreversible infrastructure control\nSafety-critical coordination\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A Redis lock is useful, but it is not automatically a substitute for a consensus system or database transaction.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For strict correctness, consider:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Database constraints\nTransactions\nIdempotency keys\nFencing tokens\nConsensus-based coordination\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">depending on the problem.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">61. Connection Pooling<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Applications should not normally do this for every request:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Request\n   |\nCreate TCP connection\n   |\nAuthenticate\n   |\nExecute GET\n   |\nClose connection\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then repeat:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>10,000 times\/second\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Connection establishment itself costs resources.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Instead, clients typically reuse connections.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart LR\n\n    A&#91;Application]\n\n    P&#91;Connection Pool]\n\n    C1&#91;Connection 1]\n    C2&#91;Connection 2]\n    C3&#91;Connection 3]\n\n    R&#91;(Redis)]\n\n    A --&gt; P\n\n    P --&gt; C1\n    P --&gt; C2\n    P --&gt; C3\n\n    C1 --&gt; R\n    C2 --&gt; R\n    C3 --&gt; R\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redis&#8217; current client documentation explicitly includes pooling\/multiplexing as a client concern, and documented clients include Python, Java, JavaScript, Go, .NET, PHP, Rust and others.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">62. Connection Pool Mental Model<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Instead of:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Create\nUse\nDestroy\n\nCreate\nUse\nDestroy\n\nCreate\nUse\nDestroy\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">do:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Create reusable connections\n       |\n       v\n      Pool\n       |\n       +---- request\n       +---- request\n       +---- request\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">However, Redis clients differ.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Some primarily use:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Connection pools\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">while others rely heavily on:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Connection multiplexing\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Therefore:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Follow the architecture of your chosen Redis client rather than blindly configuring an enormous pool.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">63. Connection Pool Parameters to Understand<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Typical settings include:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Maximum connections\nMinimum idle connections\nConnection timeout\nRead timeout\nWrite timeout\nPool wait timeout\nIdle timeout\nHealth checks\nTLS settings\nAuthentication\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example conceptual configuration:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>max_connections = 50\nconnect_timeout  = 1s\nread_timeout     = 500ms\npool_timeout     = 500ms\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Those are examples, <strong>not universal production values<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pool sizing must consider:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Application concurrency\nNumber of application instances\nRedis connection capacity\nCommand latency\nPipeline\/multiplexing behavior\nTraffic pattern\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">64. Connection Pooling Golden Rule<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Do not calculate:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>50 connections sounds good.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Instead calculate total system load.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>100 application pods\n\u00d7\n100 Redis connections\/pod\n=\n10,000 connections\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A seemingly small per-instance pool can become enormous across a cluster.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Always think:<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Per-instance configuration \u00d7 number of instances<\/h1>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">65. Redis Failure Handling<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Eventually one of these will happen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Redis unavailable\nNetwork problem\nTimeout\nConnection exhaustion\nFailover\nHigh latency\nMemory pressure\nApplication bug\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Your architecture must define what happens next.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is often more important than the happy-path Redis code.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">66. Example \u2014 Redis Cache Failure<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Normal:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Application\n     |\n     v\n   Redis\n     |\n    HIT\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redis unavailable:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Application\n     |\n     X\n   Redis\n\n     |\n     v\n Database\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For ordinary cache data, a common strategy is:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Redis fails \u2192 bypass cache \u2192 query source of truth.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">This is called:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Graceful degradation\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">But there is an important danger.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">67. Redis Failure Can Become Database Failure<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Imagine:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Redis handles 50,000 requests\/sec\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redis fails.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Your fallback says:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Use database.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>50,000 requests\/sec \u2192 Database\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The database may support only:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>5,000 queries\/sec.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Result:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Redis outage\n    \u2193\nDatabase overload\n    \u2193\nApplication outage\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is called a <strong>cascading failure<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">68. Protecting the Database During Redis Failure<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Useful mechanisms include:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Short Redis timeouts\nCircuit breakers\nRequest rate limiting\nBulkheads\nDatabase connection limits\nLoad shedding\nFallback data\nStale data\nRetry limits\nBackoff\nJitter\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Conceptually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart TD\n\n    A&#91;Request]\n\n    B{Redis healthy?}\n\n    C&#91;Redis]\n\n    D&#91;Circuit Breaker]\n\n    E{DB capacity available?}\n\n    F&#91;Database]\n\n    G&#91;Fallback \/ reject \/ stale response]\n\n    A --&gt; B\n\n    B --&gt;|Yes| C\n    B --&gt;|No| D\n\n    D --&gt; E\n\n    E --&gt;|Yes| F\n    E --&gt;|No| G\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">69. Never Use Unlimited Retries<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Bad:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Redis timeout\n    \u2193\nRetry\n    \u2193\nRetry\n    \u2193\nRetry\n    \u2193\nRetry forever\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">During an outage every application instance begins retrying.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now the recovering Redis server receives:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Massive retry storm.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Better:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Short timeout\nBounded retries\nExponential backoff\nJitter\nCircuit breaker\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">70. Fail-Open vs Fail-Closed<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Redis failure behavior depends on what Redis is doing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Consider a cache:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Redis unavailable\n\u2193\nQuery database\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Usually reasonable.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now consider a security control:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Redis stores temporary account lockout information.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redis unavailable.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Should you:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Allow everyone?\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Maybe not.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This introduces:<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Fail-open vs fail-closed<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Redis responsibility<\/th><th>Possible failure behavior<\/th><\/tr><\/thead><tbody><tr><td>Product cache<\/td><td>Bypass Redis<\/td><\/tr><tr><td>Recommendation cache<\/td><td>Serve stale\/default<\/td><\/tr><tr><td>Session store<\/td><td>User may need to reauthenticate<\/td><\/tr><tr><td>Rate limiter<\/td><td>Business\/security decision<\/td><\/tr><tr><td>Lock<\/td><td>Do not blindly continue<\/td><\/tr><tr><td>Feature flag<\/td><td>Use safe default<\/td><\/tr><tr><td>Counters<\/td><td>Queue\/degrade depending on importance<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">There is no universal fallback rule.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The fallback must match the <strong>business consequence<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">71. Failure Handling Example<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A useful cache algorithm looks conceptually like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def get_product(product_id):\n\n    try:\n        product = redis.get(product_id)\n\n        if product:\n            return product\n\n    except RedisError:\n        # Cache unavailable.\n        # Continue carefully to source of truth.\n        pass\n\n    product = database.get_product(product_id)\n\n    try:\n        redis.set(product_id, product, ex=300)\n    except RedisError:\n        # Do not fail user request just because cache population failed.\n        pass\n\n    return product\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Notice:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Redis failure\n\u2260\nAutomatically fail customer request\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">because Redis is only a cache in this architecture.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">72. Negative Caching<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose someone repeatedly requests:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>product:999999\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">which does not exist.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Without negative caching:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Request\n   \u2193\nRedis MISS\n   \u2193\nDatabase\n   \u2193\nNot found\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Again:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Redis MISS\nDatabase\nNot found\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A malicious or accidental flood can repeatedly hit the database.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can temporarily cache:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>NOT_FOUND\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">for a short TTL.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>product:999999 \u2192 NOT_FOUND\nTTL = 30 seconds\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is:<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Negative caching<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">But use short TTLs because the object might later be created.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">73. Hot Keys<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose nearly all traffic requests:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>product:iphone-latest\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That single key becomes extremely hot.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>                 Redis\n                   |\n        product:iphone-latest\n         \/ \/ \/ \/ \/ \/ \/ \/ \/\n     millions of requests\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Even if Redis overall has enough capacity, extremely skewed key access can create localized load problems.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Monitor:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Traffic distribution\nCommand latency\nHot keys\nNetwork throughput\nCPU\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Caching architecture is not just about total key count.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">74. Large Values<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Do not casually store enormous payloads under one key.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cache:everything\n    =\n500 MB JSON\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Problems include:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Network latency\nSerialization cost\nMemory pressure\nBlocking\/processing cost\nHuge invalidations\nPoor cache efficiency\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Prefer appropriately sized objects:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>product:100\nproduct:101\nproduct:102\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">when that matches your access pattern.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">75. Redis Memory Is Not Infinite<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Redis is often memory-centric.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That means capacity planning matters.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Think:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Number of keys\n\u00d7\nAverage key size\n\u00d7\nAverage value size\n+\nRedis structure overhead\n+\nReplication\/persistence overhead\n+\nOperational headroom\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Do not estimate only:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>My JSON files total 5 GB,\ntherefore I need exactly 5 GB RAM.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Real Redis memory consumption includes metadata and internal representations.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">76. TTL vs Eviction<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">These are different concepts.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">TTL<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You deliberately say:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>This key should expire in 300 seconds.\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Eviction<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Redis is under configured memory pressure and removes keys according to the configured memory-management policy.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Therefore:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Expiration = data lifetime policy\n\nEviction = memory pressure policy\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Do not design correctness around the assumption that a cache entry will always survive until its TTL.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">77. What Should Be Cached?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Good caching candidates often have:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>High read frequency\nExpensive computation\nExpensive DB query\nRepeated identical access\nTolerance for controlled staleness\nReasonable object size\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Examples:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Product catalog\nConfiguration\nUser profile summary\nSearch suggestions\nDashboard aggregates\nRecommendation results\nReference data\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">78. What Should Not Automatically Be Cached?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Be cautious with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Highly volatile authoritative financial data\nOne-time data rarely read again\nHuge objects\nData with extremely low cache hit rate\nData where stale values are dangerous\nQueries cheaper than cache management\nSensitive data without proper controls\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Caching has a cost:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Code complexity\nInvalidation logic\nMemory\nObservability\nFailure modes\nStaleness\nOperational burden\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A cache should solve a real performance or scalability problem.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">79. Cache Hit Ratio<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">One useful metric is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Cache Hit Ratio\n=\nCache Hits\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nHits + Misses\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Hits   = 9,000\nMisses = 1,000\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Hit ratio:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>9000 \/ 10000\n=\n90%\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A high hit ratio often indicates that Redis is successfully shielding the backend.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But high hit ratio alone does not prove success.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You should also ask:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Did application latency improve?\n\nDid database load decrease?\n\nIs the data fresh enough?\n\nWhat is Redis cost?\n\nAre hot keys forming?\n\nAre evictions increasing?\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">80. Important Redis Production Metrics<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Monitor at least the following categories.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Performance<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>Command latency\np50\np95\np99\nOperations\/sec\nNetwork throughput\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Cache<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>Hits\nMisses\nHit ratio\nEvictions\nExpired keys\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Memory<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>Used memory\nMemory fragmentation\nmaxmemory utilization\nLarge keys\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Connections<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>Connected clients\nConnection failures\nRejected connections\nPool exhaustion\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Availability<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>Errors\nTimeouts\nFailovers\nReplication health\nReplication lag\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Backend impact<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>Database QPS\nDatabase CPU\nDatabase connection utilization\nDatabase latency\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You need both Redis metrics and application\/backend metrics to understand whether caching is helping.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">81. Complete Production Cache Request<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Now combine the concepts.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart TD\n\n    U&#91;Client Request]\n\n    A&#91;Application]\n\n    R{Redis available?}\n\n    H{Cache Hit?}\n\n    C&#91;Return Cached Value]\n\n    CB&#91;Circuit Breaker \/ Protection]\n\n    DB&#91;(Database)]\n\n    S&#91;Store in Redis with TTL + Jitter]\n\n    RESP&#91;Return Response]\n\n    FAIL&#91;Fallback \/ Load Shed \/ Error]\n\n    U --&gt; A\n\n    A --&gt; R\n\n    R --&gt;|Yes| H\n    R --&gt;|No| CB\n\n    H --&gt;|Yes| C\n\n    H --&gt;|No| CB\n\n    CB --&gt;|Backend capacity available| DB\n    CB --&gt;|Backend protected| FAIL\n\n    DB --&gt; S\n    S --&gt; RESP\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is much closer to a real production cache than simply:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>redis.get()\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">82. Complete E-Commerce Example<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s connect all the Redis use cases into one system.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart TB\n\n    USER&#91;Customers]\n\n    APP&#91;Shopping Application]\n\n    REDIS&#91;(Redis)]\n\n    DB&#91;(SQL Database)]\n\n    PAYMENT&#91;Payment Service]\n\n    EMAIL&#91;Email Worker]\n\n    USER --&gt; APP\n\n    APP --&gt; REDIS\n    APP --&gt; DB\n    APP --&gt; PAYMENT\n\n    REDIS --&gt; EMAIL\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redis could provide:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>product:*            \u2192 product cache\n\nsession:*            \u2192 sessions\n\ncart:*               \u2192 shopping carts\n\nrate:*               \u2192 rate limiting\n\nproduct:*:views      \u2192 counters\n\nleaderboard:*        \u2192 sorted sets\n\nlock:order:*         \u2192 lightweight coordination\n\nnotifications        \u2192 Pub\/Sub\n\norder-events         \u2192 Streams\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">One Redis system therefore exposes several data-structure capabilities, but each use case has different durability and failure requirements.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">83. Example Request \u2014 Product Page<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Customer requests:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET \/products\/100\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Process:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>1. Application receives request.\n\n2. GET product:100 from Redis.\n\n3. HIT?\n       YES\n       \u2193\n   Return product.\n\n4. MISS?\n       \u2193\n   Query database.\n\n5. Database returns product.\n\n6. Store:\n   product:100\n   TTL = base + jitter\n\n7. Return customer response.\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">84. Example Request \u2014 Add to Cart<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Redis Hash:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>HSET cart:user:100 product:500 2\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Meaning:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>User 100\nCart\n\nProduct 500\nQuantity 2\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Another:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>HSET cart:user:100 product:600 1\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cart:user:100\n    |\n    +-- product:500 = 2\n    |\n    +-- product:600 = 1\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Add expiration if carts should disappear after inactivity.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">85. Example Request \u2014 User Session<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Login:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>HSET session:abc123 \\\n    user_id 100 \\\n    authenticated 1\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Set expiration:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>EXPIRE session:abc123 1800\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Any application node can now resolve:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>session:abc123\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">86. Example Request \u2014 Product Views<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Each product page:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>INCR product:100:views\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Across:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>App-1\nApp-2\nApp-3\nApp-4\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">the counter is shared.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">87. Example Request \u2014 Avoid Duplicate Order Processing<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Worker attempts:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SET lock:order:7001 unique-token NX EX 15\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Success:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Process order.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Failure:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Another worker currently owns the lease.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">After work:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Atomic owner-token check\n+\ndelete lock\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">88. Example \u2014 Live Order Notification<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Publisher:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PUBLISH orders \"Order 7001 confirmed\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Subscribers:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>WebSocket server\nNotification service\nDashboard\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">receive it while connected.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If the business requirement becomes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"This message must never simply disappear.\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">do not rely solely on Pub\/Sub.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use something durable such as:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Redis Streams\nKafka\nanother durable broker\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">depending on requirements.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">89. When Redis Should NOT Be Used<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">This is just as important as knowing when Redis should be used.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Do not automatically use Redis simply because:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Redis is fast.\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">90. Do Not Use Redis as a Replacement for Every Database<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose you need:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT customer.name,\n       SUM(order.amount)\nFROM customers\nJOIN orders ...\nJOIN invoices ...\nWHERE ...\nGROUP BY ...\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A relational database is designed for this type of workload.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Redis does not automatically replace:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PostgreSQL\nMySQL\nOracle\nSQL Server\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">91. Avoid Redis for Huge Cold Datasets<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Imagine:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>20 TB archive\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">that is accessed:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>once every three months.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Putting the entire dataset in expensive memory may provide little benefit.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A disk\/object-storage\/database architecture may be more appropriate.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">92. Avoid Redis for Large Binary Objects<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Avoid treating Redis as:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Image repository\nVideo repository\nBackup repository\nISO repository\nMassive file store\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Instead use systems designed for large objects:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Amazon S3\nGoogle Cloud Storage\nAzure Blob Storage\nObject storage\/CDN\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redis may cache metadata or small hot objects, but large binary storage is usually a poor fit.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">93. Avoid Pub\/Sub for Durable Messaging<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Requirement:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PaymentCreated event MUST be processed.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Subscriber crashes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With Pub\/Sub:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Message may disappear.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That violates the requirement.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Redis officially documents Pub\/Sub&#8217;s at-most-once semantics.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Redis Streams\nKafka\nRabbitMQ\nor another durable messaging architecture\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">depending on the system&#8217;s requirements.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">94. Do Not Use Redis Locks as Magical Distributed Transactions<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">This:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SET lock:money-transfer NX EX 10\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">does not suddenly provide:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Global transactional correctness\nDistributed consensus\nExactly-once execution\nFinancial settlement guarantees\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Distributed systems can experience:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Network delays\nProcess pauses\nClock\/time issues\nLease expiration\nFailover\nPartial failure\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Use Redis locking for problems whose correctness model fits a lease-based lock.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">95. Avoid Redis When Caching Gives No Benefit<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Request A reads unique data once.\n\nRequest B reads different unique data once.\n\nRequest C reads different unique data once.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Cache hit ratio approaches:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>0%\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now Redis adds:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Network call\nSerialization\nMemory\nInfrastructure cost\nOperational complexity\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">without meaningfully reducing database work.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Do not cache merely because caching is fashionable.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">96. Redis Decision Matrix<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Requirement<\/th><th>Redis?<\/th><th>Feature<\/th><\/tr><\/thead><tbody><tr><td>Fast product cache<\/td><td>\u2705<\/td><td>String \/ Hash<\/td><\/tr><tr><td>User sessions<\/td><td>\u2705<\/td><td>Hash\/String + TTL<\/td><\/tr><tr><td>Distributed counter<\/td><td>\u2705<\/td><td><code>INCR<\/code><\/td><\/tr><tr><td>Leaderboard<\/td><td>\u2705<\/td><td>Sorted Set<\/td><\/tr><tr><td>Unique membership<\/td><td>\u2705<\/td><td>Set<\/td><\/tr><tr><td>Live ephemeral notifications<\/td><td>\u2705<\/td><td>Pub\/Sub<\/td><\/tr><tr><td>Durable event processing<\/td><td>\u2705<\/td><td>Streams<\/td><\/tr><tr><td>Approximate unique visitor count<\/td><td>\u2705<\/td><td>HyperLogLog<\/td><\/tr><tr><td>Temporary coordination<\/td><td>\u2705<\/td><td><code>SET NX EX<\/code><\/td><\/tr><tr><td>Large relational joins<\/td><td>\u274c<\/td><td>Use relational DB<\/td><\/tr><tr><td>Huge video archive<\/td><td>\u274c<\/td><td>Use object storage<\/td><\/tr><tr><td>Durable Pub\/Sub-style event history<\/td><td>\u274c Pub\/Sub<\/td><td>Use Streams\/Kafka\/etc.<\/td><\/tr><tr><td>Strong consensus<\/td><td>\u274c<\/td><td>Use appropriate coordination mechanism<\/td><\/tr><tr><td>Low reuse \/ zero cache hits<\/td><td>Usually \u274c<\/td><td>Cache may add no value<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">97. Cache-Aside vs Write-Through Summary<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>CACHE-ASIDE\n\nApplication\n   |\n   +--&gt; Redis\n   |\n   +--&gt; Database\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Application owns cache logic.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<pre class=\"wp-block-code\"><code>READ-THROUGH\n\nApplication\n   |\n   v\nCache abstraction\n   |\n   +--&gt; Redis\n   |\n   +--&gt; Database loader\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Cache abstraction owns loading logic.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<pre class=\"wp-block-code\"><code>WRITE-THROUGH\n\nApplication\n   |\n   v\nCache abstraction\n   |\n   +--&gt; Cache\n   |\n   +--&gt; Database\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Both are updated on the write path.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">98. TTL Summary<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Never ask only:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>What TTL should Redis use?\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Ask:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>How stale may this data safely become?\n\nHow often does it change?\n\nHow expensive is reconstruction?\n\nWhat happens when thousands of keys expire?\n\nCan we actively invalidate it?\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then choose:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>TTL\n+\nJitter\n+\nInvalidation\n+\nStampede strategy\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">99. Cache Invalidation Summary<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Four common mechanisms:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>1. TTL expiration\n\n2. Delete on database change\n\n3. Update cache on database change\n\n4. Event-driven invalidation\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A strong production architecture often combines:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Active invalidation\n+\nTTL safety net\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">100. Stampede Summary<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Problem:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Popular key expires\n       \u2193\nThousands of MISSes\n       \u2193\nThousands of DB queries\n       \u2193\nDatabase overload\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Solutions include:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>TTL jitter\n\nSingle refresher \/ mutex\n\nStale-while-revalidate\n\nRequest coalescing\n\nEarly refresh\n\nBackend rate protection\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">101. Connection Pooling Summary<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Do:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Application process\n       |\n       v\nReusable Redis client\n       |\nPool \/ multiplexed connections\n       |\n       v\nRedis\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Avoid:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Every request\n    \u2193\nNew connection\n    \u2193\nRedis\n    \u2193\nClose connection\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And remember:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pool size\n\u00d7\napplication instance count\n=\ntotal potential connections\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">102. Failure Handling Summary<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">For each Redis use case ask:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>What happens if Redis disappears for 30 seconds?\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Cache:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Maybe bypass Redis.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Session:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Maybe temporarily unavailable\/re-authenticate.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Rate limiter:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Choose fail-open or fail-closed intentionally.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Lock:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Do not blindly continue.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Pub\/Sub:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Messages during disconnect may be lost.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Counter:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Decide whether temporary loss\/unavailability matters.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The same Redis failure cannot have one identical fallback strategy for every use case.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">103. Production Redis Golden Rules<\/h1>\n\n\n\n<h3 class=\"wp-block-heading\">Rule 1<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Treat the database as the source of truth when Redis is being used purely as a cache.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Rule 2<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Use the Redis data structure that naturally represents the problem.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Rule 3<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Do not cache everything.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Rule 4<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Give temporary cache data a deliberate expiration strategy.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Rule 5<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Use TTL jitter for large groups of similarly expiring keys.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Rule 6<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Design cache invalidation before production.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Rule 7<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Protect the database from cache failure.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Rule 8<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Use bounded retries and timeouts.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Rule 9<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Reuse Redis connections through the architecture supported by your client.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Rule 10<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Monitor hits, misses, memory, evictions, latency and backend load.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Rule 11<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Do not use Pub\/Sub when you require durable delivery.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Rule 12<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Treat Redis locks as leases, not magical distributed transactions.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Rule 13<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Use unique lock ownership tokens.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Rule 14<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Never depend blindly on stale cached data for critical decisions.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Rule 15<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Design Redis failure behavior before Redis actually fails.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">104. The Complete Mental Model<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">If you remember only one diagram from this tutorial, remember this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart TB\n\n    CLIENT&#91;Clients]\n\n    APP&#91;Application Layer]\n\n    POOL&#91;Redis Client \/ Connection Pool]\n\n    REDIS&#91;(Redis)]\n\n    DB&#91;(Authoritative Database)]\n\n    EVENTS&#91;Durable Event System]\n\n    CLIENT --&gt; APP\n\n    APP --&gt; POOL\n\n    POOL --&gt; REDIS\n\n    APP --&gt; DB\n\n    APP --&gt; EVENTS\n\n    REDIS --&gt;|Cache \/ Sessions \/ Counters \/ Locks| APP\n\n    DB --&gt;|Source of Truth| APP\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Redis is positioned where <strong>fast shared state<\/strong> creates value.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">105. Redis in One Sentence<\/h1>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Redis is a high-speed shared data-structure store that applications commonly use to reduce expensive work and coordinate temporary state, but every Redis use case must have deliberate policies for freshness, expiration, durability and failure.<\/strong><\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">106. Final Topic Map<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">You can now connect the complete learning journey:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart TD\n\n    A&#91;Redis Fundamentals]\n\n    B&#91;Redis Data Structures]\n\n    C&#91;Caching]\n\n    D&#91;Cache-Aside]\n\n    E&#91;Read\/Write-Through]\n\n    F&#91;TTL]\n\n    G&#91;Cache Invalidation]\n\n    H&#91;Stampede &amp; Staleness]\n\n    I&#91;Pub\/Sub]\n\n    J&#91;Sessions]\n\n    K&#91;Counters]\n\n    L&#91;Distributed Locks]\n\n    M&#91;Connection Pooling]\n\n    N&#91;Failure Handling]\n\n    O&#91;When NOT to Use Redis]\n\n    P&#91;Production Redis Architecture]\n\n    A --&gt; B\n    B --&gt; C\n    C --&gt; D\n    D --&gt; E\n    E --&gt; F\n    F --&gt; G\n    G --&gt; H\n\n    H --&gt; I\n    H --&gt; J\n    H --&gt; K\n    H --&gt; L\n\n    I --&gt; M\n    J --&gt; M\n    K --&gt; M\n    L --&gt; M\n\n    M --&gt; N\n    N --&gt; O\n    O --&gt; P\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">107. Final GOLD Standard Comparison<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Topic<\/th><th>Core Question<\/th><th>Key Redis Concept<\/th><\/tr><\/thead><tbody><tr><td>Redis<\/td><td>Why use it?<\/td><td>Fast shared state<\/td><\/tr><tr><td>Data structures<\/td><td>How should data be represented?<\/td><td>String\/Hash\/List\/Set\/ZSet\/Stream<\/td><\/tr><tr><td>Cache-aside<\/td><td>Who manages cache misses?<\/td><td>Application<\/td><\/tr><tr><td>Read-through<\/td><td>Who loads missing data?<\/td><td>Cache abstraction<\/td><\/tr><tr><td>Write-through<\/td><td>How are writes synchronized?<\/td><td>Cache + DB write path<\/td><\/tr><tr><td>TTL<\/td><td>How long may data live?<\/td><td>Expiration<\/td><\/tr><tr><td>Invalidation<\/td><td>How do we remove stale copies?<\/td><td>Delete\/update\/event<\/td><\/tr><tr><td>Stampede<\/td><td>What if many misses occur together?<\/td><td>Jitter\/locking\/SWR<\/td><\/tr><tr><td>Stale data<\/td><td>How old may data safely become?<\/td><td>Freshness policy<\/td><\/tr><tr><td>Pub\/Sub<\/td><td>Need real-time ephemeral broadcast?<\/td><td><code>PUBLISH<\/code> \/ <code>SUBSCRIBE<\/code><\/td><\/tr><tr><td>Sessions<\/td><td>Need shared temporary user state?<\/td><td>Hash\/String + TTL<\/td><\/tr><tr><td>Counters<\/td><td>Need atomic shared numbers?<\/td><td><code>INCR<\/code><\/td><\/tr><tr><td>Lightweight locks<\/td><td>Need temporary coordination?<\/td><td><code>SET NX EX\/PX<\/code><\/td><\/tr><tr><td>Pooling<\/td><td>How should applications connect efficiently?<\/td><td>Reuse\/multiplex<\/td><\/tr><tr><td>Failure handling<\/td><td>What happens when Redis fails?<\/td><td>Fallback\/circuit breaker<\/td><\/tr><tr><td>Don&#8217;t use Redis<\/td><td>Is Redis actually the right system?<\/td><td>Architectural judgment<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">108. The Most Important Redis Lesson<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Learning Redis commands is relatively easy:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GET\nSET\nDEL\nEXPIRE\nHSET\nSADD\nZADD\nINCR\nPUBLISH\nSUBSCRIBE\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The difficult\u2014and valuable\u2014part is learning to answer:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Should this data be cached?\n\nWho owns the truth?\n\nHow long may the cached copy live?\n\nHow is it invalidated?\n\nWhat if the key expires during heavy traffic?\n\nWhat if Redis goes down?\n\nWhat if the database goes down?\n\nCan stale data hurt the business?\n\nDo I need durability?\n\nDo I need atomicity?\n\nDo I actually need Redis?\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When you can answer those questions, you are no longer simply <strong>using Redis commands<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You are <strong>designing a production Redis architecture<\/strong>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>From Fundamentals to Production-Grade Caching, Sessions, Pub\/Sub, Counters, Locks and Failure Handling 1. What is Redis? Redis is a high-performance, primarily in-memory data store. The easiest mental&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1150","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1150","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/comments?post=1150"}],"version-history":[{"count":1,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1150\/revisions"}],"predecessor-version":[{"id":1151,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1150\/revisions\/1151"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/media?parent=1150"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/categories?post=1150"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/tags?post=1150"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}