[{"data":1,"prerenderedAt":585},["ShallowReactive",2],{"i-lucide:chevron-down":3,"i-lucide:search":8,"i-lucide:sun":10,"i-lucide:moon":12,"i-lucide:arrow-right":14,"i-lucide:menu":16,"i-lucide:panel-left":18,"i-lucide:mail":20,"i-simple-icons:x":22,"i-simple-icons:linkedin":24,"i-simple-icons:dribbble":27,"i-simple-icons:github":29,"i-lucide:arrow-up-right":31,"sidebar-course-\u002Flearn\u002Fen\u002Fcourses\u002Fcaching":33,"learn-topic-\u002Flearn\u002Fen\u002Fcourses\u002Fcaching":72,"prereq-":84,"sidebar-quiz-\u002Flearn\u002Fen\u002Fcourses\u002Fcaching":85,"lessons-\u002Flearn\u002Fen\u002Fcourses\u002Fcaching":86,"i-lucide:notebook-pen":557,"i-lucide:layers":559,"i-lucide:lock":561,"i-lucide:printer":563,"i-lucide:graduation-cap":565,"i-lucide:book-marked":567,"learn-quiz-\u002Flearn\u002Fen\u002Fcourses\u002Fcaching":85,"i-lucide:chevron-right":569,"i-lucide:workflow":571,"i-lucide:clock":573,"i-lucide:calendar":575,"i-lucide:link":577,"i-lucide:scroll-text":579,"i-lucide:book-open":581,"i-lucide:shopping-bag":583},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":7},0,24,false,"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m6 9l6 6l6-6\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":9},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m21 21l-4.34-4.34\"\u002F>\u003Ccircle cx=\"11\" cy=\"11\" r=\"8\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":11},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"4\"\u002F>\u003Cpath d=\"M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32l1.41 1.41M2 12h2m16 0h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":13},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":15},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 12h14m-7-7l7 7l-7 7\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":17},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 5h16M4 12h16M4 19h16\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":19},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"\u002F>\u003Cpath d=\"M9 3v18\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":21},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m22 7l-8.991 5.727a2 2 0 0 1-2.009 0L2 7\"\u002F>\u003Crect width=\"20\" height=\"16\" x=\"2\" y=\"4\" rx=\"2\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":23},"\u003Cpath fill=\"currentColor\" d=\"M14.234 10.162L22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299l-.929-1.329L3.076 1.56h3.182l5.965 8.532l.929 1.329l7.754 11.09h-3.182z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":25,"hidden":26},"\u003Cpath fill=\"currentColor\" d=\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037c-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85c3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.06 2.06 0 0 1-2.063-2.065a2.064 2.064 0 1 1 2.063 2.065m1.782 13.019H3.555V9h3.564zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0z\"\u002F>",true,{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":28},"\u003Cpath fill=\"currentColor\" d=\"M12 24C5.385 24 0 18.615 0 12S5.385 0 12 0s12 5.385 12 12s-5.385 12-12 12m10.12-10.358c-.35-.11-3.17-.953-6.384-.438c1.34 3.684 1.887 6.684 1.992 7.308a10.28 10.28 0 0 0 4.395-6.87zm-6.115 7.808c-.153-.9-.75-4.032-2.19-7.77l-.066.02c-5.79 2.015-7.86 6.025-8.04 6.4a10.16 10.16 0 0 0 6.29 2.166c1.42 0 2.77-.29 4-.814zm-11.62-2.58c.232-.4 3.045-5.055 8.332-6.765q.202-.067.405-.12q-.392-.879-.832-1.74C7.17 11.775 2.206 11.71 1.756 11.7l-.004.312c0 2.633.998 5.037 2.634 6.855zm-2.42-8.955c.46.008 4.683.026 9.477-1.248a66 66 0 0 0-3.8-5.928a10.28 10.28 0 0 0-5.676 7.17zM9.6 2.052c.282.38 2.145 2.914 3.822 6c3.645-1.365 5.19-3.44 5.373-3.702A10.2 10.2 0 0 0 12 1.764c-.825 0-1.63.1-2.4.285zm10.335 3.483c-.218.29-1.935 2.493-5.724 4.04c.24.49.47.985.68 1.486c.08.18.15.36.22.53c3.41-.43 6.8.26 7.14.33c-.02-2.42-.88-4.64-2.31-6.38z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":30},"\u003Cpath fill=\"currentColor\" d=\"M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":32},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 7h10v10M7 17L17 7\"\u002F>",{"id":34,"title":35,"access":36,"body":37,"description":44,"draft":6,"estimatedMinutes":45,"extension":46,"featured":6,"icon":47,"lang":48,"level":49,"meta":50,"navigation":26,"order":51,"path":52,"prerequisites":53,"resources":54,"seo":60,"sku":58,"stem":61,"subjects":62,"summary":64,"tags":65,"updated":70,"__hash__":71},"courses\u002Flearn\u002Fen\u002Fcourses\u002Fcaching\u002Findex.md","Caching strategies","premium",{"type":38,"value":39,"toc":40},"minimark",[],{"title":41,"searchDepth":42,"depth":42,"links":43},"",3,[],"Read-through, write-behind, invalidation and the failure modes each one buys.",40,"md","lucide:layers","en","advanced",{},1,"\u002Flearn\u002Fen\u002Fcourses\u002Fcaching",[],[55],{"label":56,"file":57,"access":36,"sku":58,"size":59},"Caching decision matrix","caching-decision-matrix.pdf","topic-caching-strategies","310 KB",{"title":35,"description":44},"learn\u002Fen\u002Fcourses\u002Fcaching\u002Findex",[63],"system-design","A cache is a bet that reading stale data is cheaper than reading correct data.\nThe strategies differ in who writes to the cache, when, and what happens when\nthe cache and the source disagree. Cache-aside is the default because it fails\nsafely. Write-behind is the fastest and loses data on a crash. Almost every\nproduction incident involving a cache comes down to invalidation, stampedes, or\na cache that was quietly doing nothing at all.\n",[66,67,68,69],"caching","performance","consistency","redis","2026-08-06","mqYWifp5mzccLyzSY681N-Yn1wymognvHpRRfhOtFBI",{"id":34,"title":35,"access":36,"body":73,"description":44,"draft":6,"estimatedMinutes":45,"extension":46,"featured":6,"icon":47,"lang":48,"level":49,"meta":77,"navigation":26,"order":51,"path":52,"prerequisites":78,"resources":79,"seo":81,"sku":58,"stem":61,"subjects":82,"summary":64,"tags":83,"updated":70,"__hash__":71},{"type":38,"value":74,"toc":75},[],{"title":41,"searchDepth":42,"depth":42,"links":76},[],{},[],[80],{"label":56,"file":57,"access":36,"sku":58,"size":59},{"title":35,"description":44},[63],[66,67,68,69],[],null,[87,316],{"id":88,"title":89,"access":90,"body":91,"description":310,"extension":46,"lang":48,"meta":311,"navigation":26,"order":51,"partial":26,"path":312,"seo":313,"stem":314,"__hash__":315},"lessons\u002Flearn\u002Fen\u002Fcourses\u002Fcaching\u002F01.strategies.md","The four strategies","free",{"type":38,"value":92,"toc":304},[93,97,101,106,109,261,264,268,271,274,278,281,284,288,291,294,300],[94,95,89],"h1",{"id":96},"the-four-strategies",[98,99,100],"p",{},"Every caching pattern answers two questions: who populates the cache, and when is\nthe source of truth updated relative to it.",[102,103,105],"h2",{"id":104},"cache-aside","Cache-aside",[98,107,108],{},"The application checks the cache, and on a miss reads the database and populates\nthe cache itself. The cache has no knowledge of the database.",[110,111,115],"pre",{"className":112,"code":113,"language":114,"meta":41,"style":41},"language-python shiki shiki-themes github-dark-dimmed github-dark-dimmed","def get_user(user_id):\n    cached = cache.get(f\"user:{user_id}\")\n    if cached is not None:\n        return cached\n    user = db.query(\"SELECT * FROM users WHERE id = %s\", user_id)\n    cache.set(f\"user:{user_id}\", user, ttl=300)\n    return user\n","python",[116,117,118,134,168,189,198,220,252],"code",{"__ignoreMap":41},[119,120,122,126,130],"span",{"class":121,"line":51},"line",[119,123,125],{"class":124},"sEYkB","def",[119,127,129],{"class":128},"s-wk_"," get_user",[119,131,133],{"class":132},"sM9_K","(user_id):\n",[119,135,137,140,143,146,149,153,156,159,162,165],{"class":121,"line":136},2,[119,138,139],{"class":132},"    cached ",[119,141,142],{"class":124},"=",[119,144,145],{"class":132}," cache.get(",[119,147,148],{"class":124},"f",[119,150,152],{"class":151},"szYpP","\"user:",[119,154,155],{"class":124},"{",[119,157,158],{"class":132},"user_id",[119,160,161],{"class":124},"}",[119,163,164],{"class":151},"\"",[119,166,167],{"class":132},")\n",[119,169,170,173,176,179,182,186],{"class":121,"line":42},[119,171,172],{"class":124},"    if",[119,174,175],{"class":132}," cached ",[119,177,178],{"class":124},"is",[119,180,181],{"class":124}," not",[119,183,185],{"class":184},"sQdni"," None",[119,187,188],{"class":132},":\n",[119,190,192,195],{"class":121,"line":191},4,[119,193,194],{"class":124},"        return",[119,196,197],{"class":132}," cached\n",[119,199,201,204,206,209,212,215,217],{"class":121,"line":200},5,[119,202,203],{"class":132},"    user ",[119,205,142],{"class":124},[119,207,208],{"class":132}," db.query(",[119,210,211],{"class":151},"\"SELECT * FROM users WHERE id = ",[119,213,214],{"class":124},"%s",[119,216,164],{"class":151},[119,218,219],{"class":132},", user_id)\n",[119,221,223,226,228,230,232,234,236,238,241,245,247,250],{"class":121,"line":222},6,[119,224,225],{"class":132},"    cache.set(",[119,227,148],{"class":124},[119,229,152],{"class":151},[119,231,155],{"class":124},[119,233,158],{"class":132},[119,235,161],{"class":124},[119,237,164],{"class":151},[119,239,240],{"class":132},", user, ",[119,242,244],{"class":243},"siJwO","ttl",[119,246,142],{"class":124},[119,248,249],{"class":184},"300",[119,251,167],{"class":132},[119,253,255,258],{"class":121,"line":254},7,[119,256,257],{"class":124},"    return",[119,259,260],{"class":132}," user\n",[98,262,263],{},"This is the default for a reason: if the cache is down, every request simply\nbecomes a database read. Degraded, not broken.",[102,265,267],{"id":266},"read-through","Read-through",[98,269,270],{},"The cache sits inline. The application only talks to the cache, which fetches from\nthe database on a miss. Logic moves out of the application and into the cache layer.",[98,272,273],{},"Cleaner call sites, but the cache is now on the critical path — if it is unavailable,\nreads fail entirely rather than falling back.",[102,275,277],{"id":276},"write-through","Write-through",[98,279,280],{},"Writes go to the cache, which synchronously writes to the database before\nacknowledging. The cache is never stale.",[98,282,283],{},"The cost is write latency: every write pays for both hops. Worth it when reads\nvastly outnumber writes and stale reads are unacceptable.",[102,285,287],{"id":286},"write-behind","Write-behind",[98,289,290],{},"Writes land in the cache and are flushed to the database asynchronously.",[98,292,293],{},"Fastest writes available, and the only strategy that can lose acknowledged data. A\ncrash between acknowledgement and flush loses whatever was buffered.",[295,296,297],"warning",{},[98,298,299],{},"Write-behind is appropriate for metrics, view counts and analytics events. It is not\nappropriate for anything a user would notice going missing — orders, payments,\nmessages. The performance gain is real, and so is the data loss.",[301,302,303],"style",{},"html pre.shiki code .sEYkB, html code.shiki .sEYkB{--shiki-default:#F47067;--shiki-dark:#F47067}html pre.shiki code .s-wk_, html code.shiki .s-wk_{--shiki-default:#DCBDFB;--shiki-dark:#DCBDFB}html pre.shiki code .sM9_K, html code.shiki .sM9_K{--shiki-default:#ADBAC7;--shiki-dark:#ADBAC7}html pre.shiki code .szYpP, html code.shiki .szYpP{--shiki-default:#96D0FF;--shiki-dark:#96D0FF}html pre.shiki code .sQdni, html code.shiki .sQdni{--shiki-default:#6CB6FF;--shiki-dark:#6CB6FF}html pre.shiki code .siJwO, html code.shiki .siJwO{--shiki-default:#F69D50;--shiki-dark:#F69D50}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":41,"searchDepth":42,"depth":42,"links":305},[306,307,308,309],{"id":104,"depth":136,"text":105},{"id":266,"depth":136,"text":267},{"id":276,"depth":136,"text":277},{"id":286,"depth":136,"text":287},"Cache-aside, read-through, write-through and write-behind compared.",{},"\u002Flearn\u002Fen\u002Fcourses\u002Fcaching\u002Fstrategies",{"title":89,"description":310},"learn\u002Fen\u002Fcourses\u002Fcaching\u002F01.strategies","sh2NUIv6r7JjhJWD_OzLrfaRSj7urg2L7nJtqWFgm04",{"id":317,"title":318,"access":36,"body":319,"description":551,"extension":46,"lang":48,"meta":552,"navigation":26,"order":136,"partial":6,"path":553,"seo":554,"stem":555,"__hash__":556},"lessons\u002Flearn\u002Fen\u002Fcourses\u002Fcaching\u002F02.invalidation.md","Invalidation and stampedes",{"type":38,"value":320,"toc":545},[321,324,327,331,334,338,341,344,347,354,360,429,435,441,445,448,487,490,493,497,500,539,542],[94,322,318],{"id":323},"invalidation-and-stampedes",[98,325,326],{},"Caching is easy. Knowing when the cached value stopped being true is the hard part.",[102,328,330],{"id":329},"ttl-is-a-guess-about-staleness","TTL is a guess about staleness",[98,332,333],{},"A TTL says \"I accept being wrong for up to this long\". Choosing one means deciding\nhow much staleness the product tolerates — a question for the product, not the\ninfrastructure.",[102,335,337],{"id":336},"the-thundering-herd","The thundering herd",[98,339,340],{},"A popular key expires. A thousand concurrent requests miss simultaneously. All\nthousand hit the database with the same query.",[98,342,343],{},"The database, sized for the cached load, falls over. Recovery repopulates the cache,\nthe key expires again, and the pattern repeats on a cycle matching the TTL.",[98,345,346],{},"Three defences:",[98,348,349,353],{},[350,351,352],"strong",{},"Locking."," The first miss takes a lock and recomputes; everyone else waits or\nserves stale. Correct, but adds a coordination point.",[98,355,356,359],{},[350,357,358],{},"Probabilistic early expiry."," Recompute before expiry with a probability that\nrises as the TTL approaches, so refreshes spread out instead of synchronising.",[110,361,363],{"className":112,"code":362,"language":114,"meta":41,"style":41},"def should_refresh(computed_at, ttl, beta=1.0):\n    age = now() - computed_at\n    return age + beta * delta * math.log(random.random()) >= ttl\n",[116,364,365,383,399],{"__ignoreMap":41},[119,366,367,369,372,375,377,380],{"class":121,"line":51},[119,368,125],{"class":124},[119,370,371],{"class":128}," should_refresh",[119,373,374],{"class":132},"(computed_at, ttl, beta",[119,376,142],{"class":124},[119,378,379],{"class":184},"1.0",[119,381,382],{"class":132},"):\n",[119,384,385,388,390,393,396],{"class":121,"line":136},[119,386,387],{"class":132},"    age ",[119,389,142],{"class":124},[119,391,392],{"class":132}," now() ",[119,394,395],{"class":124},"-",[119,397,398],{"class":132}," computed_at\n",[119,400,401,403,406,409,412,415,418,420,423,426],{"class":121,"line":42},[119,402,257],{"class":124},[119,404,405],{"class":132}," age ",[119,407,408],{"class":124},"+",[119,410,411],{"class":132}," beta ",[119,413,414],{"class":124},"*",[119,416,417],{"class":132}," delta ",[119,419,414],{"class":124},[119,421,422],{"class":132}," math.log(random.random()) ",[119,424,425],{"class":124},">=",[119,427,428],{"class":132}," ttl\n",[98,430,431,434],{},[350,432,433],{},"Jitter."," Add randomness to every TTL so keys written together do not expire\ntogether. The cheapest fix and often sufficient.",[436,437,438],"danger",{},[98,439,440],{},"Populating a cache during a deploy or a warm-up script writes thousands of keys\nwithin the same second. With a fixed TTL they all expire within the same second too,\nproducing a synchronised stampede hours later that looks completely unrelated to\nthe deploy that caused it. Always jitter.",[102,442,444],{"id":443},"explicit-invalidation","Explicit invalidation",[98,446,447],{},"Delete the key on write:",[110,449,451],{"className":112,"code":450,"language":114,"meta":41,"style":41},"def update_user(user_id, data):\n    db.update(user_id, data)\n    cache.delete(f\"user:{user_id}\")\n",[116,452,453,463,468],{"__ignoreMap":41},[119,454,455,457,460],{"class":121,"line":51},[119,456,125],{"class":124},[119,458,459],{"class":128}," update_user",[119,461,462],{"class":132},"(user_id, data):\n",[119,464,465],{"class":121,"line":136},[119,466,467],{"class":132},"    db.update(user_id, data)\n",[119,469,470,473,475,477,479,481,483,485],{"class":121,"line":42},[119,471,472],{"class":132},"    cache.delete(",[119,474,148],{"class":124},[119,476,152],{"class":151},[119,478,155],{"class":124},[119,480,158],{"class":132},[119,482,161],{"class":124},[119,484,164],{"class":151},[119,486,167],{"class":132},[98,488,489],{},"Delete rather than overwrite. Overwriting introduces a race where two concurrent\nwriters leave the cache holding the older value.",[98,491,492],{},"The ordering matters too — database first, then cache. Reversed, a concurrent read\nbetween the two steps repopulates the cache with the old row and the stale value\nsurvives its TTL.",[102,494,496],{"id":495},"cached-nothing","Cached nothing",[98,498,499],{},"The failure mode nobody instruments: a cache that works perfectly and is never hit,\nbecause keys are built from something that varies per request.",[110,501,503],{"className":112,"code":502,"language":114,"meta":41,"style":41},"cache.set(f\"user:{user_id}:{request_id}\", user)  # unique every time\n",[116,504,505],{"__ignoreMap":41},[119,506,507,510,512,514,516,518,520,523,525,528,530,532,535],{"class":121,"line":51},[119,508,509],{"class":132},"cache.set(",[119,511,148],{"class":124},[119,513,152],{"class":151},[119,515,155],{"class":124},[119,517,158],{"class":132},[119,519,161],{"class":124},[119,521,522],{"class":151},":",[119,524,155],{"class":124},[119,526,527],{"class":132},"request_id",[119,529,161],{"class":124},[119,531,164],{"class":151},[119,533,534],{"class":132},", user)  ",[119,536,538],{"class":537},"s0RzX","# unique every time\n",[98,540,541],{},"Hit rate is zero. Latency is unchanged. Nothing errors. Monitor hit rate as a first\nclass metric, and alert when it drops — a cache silently doing nothing is a cost with\nno benefit.",[301,543,544],{},"html pre.shiki code .sEYkB, html code.shiki .sEYkB{--shiki-default:#F47067;--shiki-dark:#F47067}html pre.shiki code .s-wk_, html code.shiki .s-wk_{--shiki-default:#DCBDFB;--shiki-dark:#DCBDFB}html pre.shiki code .sM9_K, html code.shiki .sM9_K{--shiki-default:#ADBAC7;--shiki-dark:#ADBAC7}html pre.shiki code .sQdni, html code.shiki .sQdni{--shiki-default:#6CB6FF;--shiki-dark:#6CB6FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .szYpP, html code.shiki .szYpP{--shiki-default:#96D0FF;--shiki-dark:#96D0FF}html pre.shiki code .s0RzX, html code.shiki .s0RzX{--shiki-default:#768390;--shiki-dark:#768390}",{"title":41,"searchDepth":42,"depth":42,"links":546},[547,548,549,550],{"id":329,"depth":136,"text":330},{"id":336,"depth":136,"text":337},{"id":443,"depth":136,"text":444},{"id":495,"depth":136,"text":496},"TTLs, explicit invalidation, and what happens when a hot key expires.",{},"\u002Flearn\u002Fen\u002Fcourses\u002Fcaching\u002Finvalidation",{"title":318,"description":551},"learn\u002Fen\u002Fcourses\u002Fcaching\u002F02.invalidation","fahMLdo2hiDD5K_BQHGZCeYMOkIquLGdRIDAy0WkguI",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":558},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M13.4 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-7.4M2 6h4m-4 4h4m-4 4h4m-4 4h4\"\u002F>\u003Cpath d=\"M21.378 5.626a1 1 0 1 0-3.004-3.004l-5.01 5.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506z\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":560},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z\"\u002F>\u003Cpath d=\"M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12\"\u002F>\u003Cpath d=\"M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":562},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"18\" height=\"11\" x=\"3\" y=\"11\" rx=\"2\" ry=\"2\"\u002F>\u003Cpath d=\"M7 11V7a5 5 0 0 1 10 0v4\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":564},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2M6 9V3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v6\"\u002F>\u003Crect width=\"12\" height=\"8\" x=\"6\" y=\"14\" rx=\"1\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":566},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M21.42 10.922a1 1 0 0 0-.019-1.838L12.83 5.18a2 2 0 0 0-1.66 0L2.6 9.08a1 1 0 0 0 0 1.832l8.57 3.908a2 2 0 0 0 1.66 0zM22 10v6\"\u002F>\u003Cpath d=\"M6 12.5V16a6 3 0 0 0 12 0v-3.5\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":568},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M10 2v8l3-3l3 3V2\"\u002F>\u003Cpath d=\"M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H19a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6.5a1 1 0 0 1 0-5H20\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":570},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m9 18l6-6l-6-6\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":572},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"8\" height=\"8\" x=\"3\" y=\"3\" rx=\"2\"\u002F>\u003Cpath d=\"M7 11v4a2 2 0 0 0 2 2h4\"\u002F>\u003Crect width=\"8\" height=\"8\" x=\"13\" y=\"13\" rx=\"2\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":574},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"10\"\u002F>\u003Cpath d=\"M12 6v6l4 2\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":576},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M8 2v3m8-3v3\"\u002F>\u003Crect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"\u002F>\u003Cpath d=\"M3 9h18\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":578},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"\u002F>\u003Cpath d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":580},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M15 12h-5m5-4h-5m9 9V5a2 2 0 0 0-2-2H4\"\u002F>\u003Cpath d=\"M8 21h12a2 2 0 0 0 2-2v-1a1 1 0 0 0-1-1H11a1 1 0 0 0-1 1v1a2 2 0 1 1-4 0V5a2 2 0 1 0-4 0v2a1 1 0 0 0 1 1h3\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":582},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 5v16m8.001-2A2 2 0 0 0 22 17V5a2 2 0 0 0-1.999-2L16 3.002A5 5 0 0 0 12 5a5 5 0 0 0-4-2H4a2 2 0 0 0-2 2v12a2 2 0 0 0 1.999 2H8a5 5 0 0 1 4 2a5 5 0 0 1 4-2z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":584},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M16 10a4 4 0 0 1-8 0M3.103 6.034h17.794\"\u002F>\u003Cpath d=\"M3.4 5.467a2 2 0 0 0-.4 1.2V20a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6.667a2 2 0 0 0-.4-1.2l-2-2.667A2 2 0 0 0 17 2H7a2 2 0 0 0-1.6.8z\"\u002F>\u003C\u002Fg>",1791742738365]