[{"data":1,"prerenderedAt":389},["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:mail":18,"i-simple-icons:x":20,"i-simple-icons:linkedin":22,"i-simple-icons:dribbble":25,"i-simple-icons:github":27,"i-lucide:arrow-up-right":29,"daily-index-en":31,"i-lucide:chevron-right":385,"i-lucide:notebook-pen":387},{"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\">\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":21},"\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":23,"hidden":24},"\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":26},"\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":28},"\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":30},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 7h10v10M7 17L17 7\"\u002F>",[32,134,282,354],{"id":33,"title":34,"body":35,"date":120,"description":121,"extension":122,"lang":123,"meta":124,"minutes":74,"navigation":24,"path":125,"seo":126,"stem":127,"subjects":128,"tags":130,"__hash__":133},"articles\u002Flearn\u002Fen\u002Farticles\u002F2026-08-06.md","A ClusterIP cannot be pinged",{"type":36,"value":37,"toc":117},"minimark",[38,42,45,85,88,110,113],[39,40,41],"p",{},"A ClusterIP is not assigned to any network interface. Nothing owns it, so nothing\nanswers ICMP.",[39,43,44],{},"What actually exists is a set of iptables or IPVS rules on every node that rewrite\nthe destination address — but only for the ports the Service declares.",[46,47,52],"pre",{"className":48,"code":49,"language":50,"meta":51,"style":51},"language-bash shiki shiki-themes github-dark-dimmed github-dark-dimmed","ping 10.96.0.42          # always fails, means nothing\ncurl 10.96.0.42:80       # this is the real test\n","bash","",[53,54,55,72],"code",{"__ignoreMap":51},[56,57,60,64,68],"span",{"class":58,"line":59},"line",1,[56,61,63],{"class":62},"siJwO","ping",[56,65,67],{"class":66},"sQdni"," 10.96.0.42",[56,69,71],{"class":70},"s0RzX","          # always fails, means nothing\n",[56,73,75,78,82],{"class":58,"line":74},2,[56,76,77],{"class":62},"curl",[56,79,81],{"class":80},"szYpP"," 10.96.0.42:80",[56,83,84],{"class":70},"       # this is the real test\n",[39,86,87],{},"If you need to know whether a Service is wired up, check its endpoints instead:",[46,89,91],{"className":48,"code":90,"language":50,"meta":51,"style":51},"kubectl get endpointslices -l kubernetes.io\u002Fservice-name=payments\n",[53,92,93],{"__ignoreMap":51},[56,94,95,98,101,104,107],{"class":58,"line":59},[56,96,97],{"class":62},"kubectl",[56,99,100],{"class":80}," get",[56,102,103],{"class":80}," endpointslices",[56,105,106],{"class":66}," -l",[56,108,109],{"class":80}," kubernetes.io\u002Fservice-name=payments\n",[39,111,112],{},"An empty list means the selector matches nothing, or the pods are failing readiness.\nThat is the actual answer, and ping was never going to give it to you.",[114,115,116],"style",{},"html pre.shiki code .siJwO, html code.shiki .siJwO{--shiki-default:#F69D50;--shiki-dark:#F69D50}html pre.shiki code .sQdni, html code.shiki .sQdni{--shiki-default:#6CB6FF;--shiki-dark:#6CB6FF}html pre.shiki code .s0RzX, html code.shiki .s0RzX{--shiki-default:#768390;--shiki-dark:#768390}html pre.shiki code .szYpP, html code.shiki .szYpP{--shiki-default:#96D0FF;--shiki-dark:#96D0FF}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":51,"searchDepth":118,"depth":118,"links":119},3,[],"2026-08-06","Why a failed ping proves nothing about whether your Service works.","md","en",{},"\u002Flearn\u002Fen\u002Farticles\u002F2026-08-06",{"title":34,"description":121},"learn\u002Fen\u002Farticles\u002F2026-08-06",[129],"kubernetes",[131,132],"services","debugging","g_WmoqBs1YOeMw7NsHp6F2JNMU1_QOW2iN0erDDOrcU",{"id":135,"title":136,"body":137,"date":271,"description":272,"extension":122,"lang":123,"meta":273,"minutes":74,"navigation":24,"path":274,"seo":275,"stem":276,"subjects":277,"tags":279,"__hash__":281},"articles\u002Flearn\u002Fen\u002Farticles\u002F2026-08-05.md","await null still yields",{"type":36,"value":138,"toc":269},[139,146,251,260,266],[39,140,141,142,145],{},"A common assumption is that ",[53,143,144],{},"await"," on a non-promise is a no-op. It is not.",[46,147,151],{"className":148,"code":149,"language":150,"meta":51,"style":51},"language-js shiki shiki-themes github-dark-dimmed github-dark-dimmed","async function run() {\n  console.log('a')\n  await null\n  console.log('c')\n}\n\nrun()\nconsole.log('b')\n\u002F\u002F a, b, c\n","js",[53,152,153,170,187,195,209,215,221,230,245],{"__ignoreMap":51},[56,154,155,159,162,166],{"class":58,"line":59},[56,156,158],{"class":157},"sEYkB","async",[56,160,161],{"class":157}," function",[56,163,165],{"class":164},"s-wk_"," run",[56,167,169],{"class":168},"sM9_K","() {\n",[56,171,172,175,178,181,184],{"class":58,"line":74},[56,173,174],{"class":168},"  console.",[56,176,177],{"class":164},"log",[56,179,180],{"class":168},"(",[56,182,183],{"class":80},"'a'",[56,185,186],{"class":168},")\n",[56,188,189,192],{"class":58,"line":118},[56,190,191],{"class":157},"  await",[56,193,194],{"class":66}," null\n",[56,196,198,200,202,204,207],{"class":58,"line":197},4,[56,199,174],{"class":168},[56,201,177],{"class":164},[56,203,180],{"class":168},[56,205,206],{"class":80},"'c'",[56,208,186],{"class":168},[56,210,212],{"class":58,"line":211},5,[56,213,214],{"class":168},"}\n",[56,216,218],{"class":58,"line":217},6,[56,219,220],{"emptyLinePlaceholder":24},"\n",[56,222,224,227],{"class":58,"line":223},7,[56,225,226],{"class":164},"run",[56,228,229],{"class":168},"()\n",[56,231,233,236,238,240,243],{"class":58,"line":232},8,[56,234,235],{"class":168},"console.",[56,237,177],{"class":164},[56,239,180],{"class":168},[56,241,242],{"class":80},"'b'",[56,244,186],{"class":168},[56,246,248],{"class":58,"line":247},9,[56,249,250],{"class":70},"\u002F\u002F a, b, c\n",[39,252,253,255,256,259],{},[53,254,144],{}," always suspends. The operand is wrapped, and everything after it is\nscheduled as a microtask — whether you awaited a promise, a number, or ",[53,257,258],{},"null",".",[39,261,262,263,265],{},"The practical consequence: adding an ",[53,264,144],{}," to a function changes the ordering of\ncode that never touched promises. That is usually harmless and occasionally the\nexplanation for a bug that appeared when someone made a function async.",[114,267,268],{},"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 .s0RzX, html code.shiki .s0RzX{--shiki-default:#768390;--shiki-dark:#768390}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":51,"searchDepth":118,"depth":118,"links":270},[],"2026-08-05","Awaiting a non-promise does not resolve synchronously.",{},"\u002Flearn\u002Fen\u002Farticles\u002F2026-08-05",{"title":136,"description":272},"learn\u002Fen\u002Farticles\u002F2026-08-05",[278],"javascript",[158,280],"event-loop","OR8sLwlVFtPv0ENwClhFGDSsY0bYxUet6wjNC7MeTJw",{"id":283,"title":284,"body":285,"date":342,"description":343,"extension":122,"lang":123,"meta":344,"minutes":118,"navigation":24,"path":345,"seo":346,"stem":347,"subjects":348,"tags":350,"__hash__":353},"articles\u002Flearn\u002Fen\u002Farticles\u002F2026-08-04.md","Jitter every TTL",{"type":36,"value":286,"toc":340},[287,290,293,296,334,337],[39,288,289],{},"A warm-up script writes ten thousand cache keys in one second, each with a\none-hour TTL.",[39,291,292],{},"One hour later, all ten thousand expire in the same second. Every request misses.\nThe database, sized for cached traffic, takes the full uncached load at once.",[39,294,295],{},"The incident happens an hour after a deploy that looked completely clean, which is\nwhat makes it hard to attribute.",[46,297,301],{"className":298,"code":299,"language":300,"meta":51,"style":51},"language-python shiki shiki-themes github-dark-dimmed github-dark-dimmed","ttl = base_ttl + random.randint(0, base_ttl \u002F\u002F 10)\n","python",[53,302,303],{"__ignoreMap":51},[56,304,305,308,311,314,317,320,323,326,329,332],{"class":58,"line":59},[56,306,307],{"class":168},"ttl ",[56,309,310],{"class":157},"=",[56,312,313],{"class":168}," base_ttl ",[56,315,316],{"class":157},"+",[56,318,319],{"class":168}," random.randint(",[56,321,322],{"class":66},"0",[56,324,325],{"class":168},", base_ttl ",[56,327,328],{"class":157},"\u002F\u002F",[56,330,331],{"class":66}," 10",[56,333,186],{"class":168},[39,335,336],{},"Ten percent of randomness spreads the expiry over six minutes instead of one\nsecond. It is one line, and it is the cheapest reliability improvement available to\nanyone running a cache.",[114,338,339],{},"html pre.shiki code .sM9_K, html code.shiki .sM9_K{--shiki-default:#ADBAC7;--shiki-dark:#ADBAC7}html pre.shiki code .sEYkB, html code.shiki .sEYkB{--shiki-default:#F47067;--shiki-dark:#F47067}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);}",{"title":51,"searchDepth":118,"depth":118,"links":341},[],"2026-08-04","Keys written together expire together, and stampede together.",{},"\u002Flearn\u002Fen\u002Farticles\u002F2026-08-04",{"title":284,"description":343},"learn\u002Fen\u002Farticles\u002F2026-08-04",[349],"system-design",[351,352],"caching","reliability","HEWaBarpKAjHeTZV4CP4uOmXMopR-VWoxGO0m6LAclI",{"id":355,"title":356,"body":357,"date":373,"description":374,"extension":122,"lang":123,"meta":375,"minutes":74,"navigation":24,"path":376,"seo":377,"stem":378,"subjects":379,"tags":381,"__hash__":384},"articles\u002Flearn\u002Fen\u002Farticles\u002F2026-08-03.md","Disabled buttons are a dead end",{"type":36,"value":358,"toc":371},[359,362,365,368],[39,360,361],{},"A disabled submit button communicates that something is wrong and refuses to say\nwhat. It is also skipped by keyboard focus and often unreadable against its\nbackground, so a screen reader user gets no signal at all.",[39,363,364],{},"Keep the button enabled. Validate on submit. Move focus to the first error and\ndescribe it in text.",[39,366,367],{},"The user learns what the form wants by asking, which is the interaction they were\nalready attempting. The disabled state asks them to guess instead.",[39,369,370],{},"If the action is genuinely unavailable — a plan limit, a missing permission — say so\nin text next to the control. The reason is the useful part; the disabled state is\njust the absence of one.",{"title":51,"searchDepth":118,"depth":118,"links":372},[],"2026-08-03","They remove the affordance without explaining the requirement.",{},"\u002Flearn\u002Fen\u002Farticles\u002F2026-08-03",{"title":356,"description":374},"learn\u002Fen\u002Farticles\u002F2026-08-03",[380],"ui-ux",[382,383],"forms","accessibility","WM62nfpNMW97kvhd-JlTOgqauLUr4OkbyY5TalAHIS0",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":386},"\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":388},"\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>",1791741962845]