[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6GZGSF0T8MKDMCS3TTRQXHQ":3,"skill-same:01M6GZGSF0T8MKDMCS3TTRQXHQ":75},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":16,"sourceHtmlUrl":17,"categories":18,"keywords":19,"publishedAt":33,"linkOnly":34,"markdownContent":35,"markdownBody":36,"frontMatter":37,"refName":38,"commitSha":39,"skillDirectory":40,"forksCount":41,"repositoryHtmlUrl":42,"repositoryHomepageUrl":6,"ownerHtmlUrl":43,"ownerBlogUrl":44,"ownerDescription":45,"updatedAt":46,"install":47,"resources":60},"01M6GZGSF0T8MKDMCS3TTRQXHQ","prevent-cache-stampede-with-single-flight",null,"Use when a popular key expires and every request rebuilds it at once — collapse concurrent misses into one load with a lock, plus a stale-while-revalidate fallback.","jiayaoqijia\u002Fcryptoskill","jiayaoqijia","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F1453879?v=4","01M6GMYTX7Q7S504VC6E756ENR","YQ","01M6GMYV1QKJ1CC75MTTGT9PR0",80,"MIT","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-prevent-cache-stampede-with-single-flight\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-prevent-cache-stampede-with-single-flight\u002FSKILL.md",[],[20,21,22,23,24,25,26,27,28,29,30,31,32],"cache","with","prevent cache stampede with single flight","single","use","stale","fallback","it","lock","load","at","request","when","2026-11-10 10:12:30",false,"---\nname: prevent-cache-stampede-with-single-flight\ndescription: Use when a popular key expires and every request rebuilds it at once — collapse concurrent misses into one load with a lock, plus a stale-while-revalidate fallback.\n---\n\n# Prevent a cache stampede\n\nWhen a hot key expires, every concurrent request misses and races to recompute it. A thousand callers recompute the same value and the origin takes a thousand hits — exactly the load the cache existed to prevent. Collapse the herd to a single loader.\n\n## Procedure\n\n1. Recognise the shape: an origin QPS spike that coincides with a key's TTL boundary, with p99 rising while the key is rebuilt.\n2. Single-flight in-process: coalesce concurrent loads for the same key into one. Go's `golang.org\u002Fx\u002Fsync\u002Fsingleflight`, Node's `p-memoize`, or a per-key promise map:\n```python\ninflight = {}\nasync def get(key):\n    if key not in inflight:\n        inflight[key] = asyncio.create_task(load(key))\n    return await inflight.pop(key)\n```\n3. Across processes, take a short distributed lock before recomputing; losers wait briefly then re-read the now-populated key:\n```python\nif redis.set(f\"lock:{key}\", 1, nx=True, ex=10):\n    val = load(key); redis.setex(key, 300, val)\nelse:\n    await asyncio.sleep(0.05); return await get(key)\n```\n4. Prefer stale-while-revalidate over blocking: serve the expired value and refresh in the background, with `stale-if-error` covering an origin outage.\n5. Jitter every TTL so keys never expire together: `ttl = 300 + random.randint(0, 30)`.\n6. Pre-warm the hottest keys on deploy or on a schedule, before the boundary rather than after it.\n7. Bound the wait: a crashed lock holder must release via the key's `ex` TTL, never via a manual unlock that can deadlock.\n\n## Pitfalls\n\n- A lock with no TTL — a crashed holder blocks the key forever.\n- Serving stale for a security-critical value (auth token, balance) where staleness is not acceptable.\n- Single-flight keyed by a lossy key (`user`) so unrelated tenants collide.\n- Refreshing in the background but never logging failures, so the stale value is served indefinitely.\n- Collapsing the herd and still exceeding a rate-limited upstream's quota on the one reload.\n- A per-process lock only, so N pods still produce N origin calls.\n\n## Verification\n\n    redis-cli monitor | grep -c \"lock:\"      # one lock and one origin load per key\n    for i in $(seq 1 200); do curl -s localhost:8080\u002Fhot >\u002Fdev\u002Fnull & done; wait\n    grep -c \"origin_call\" app.log            # pass: ~1, not ~200\n\nReport the collapse mechanism, the origin call count for N concurrent misses of a cold key, and the TTL jitter range used.\n","# Prevent a cache stampede\n\nWhen a hot key expires, every concurrent request misses and races to recompute it. A thousand callers recompute the same value and the origin takes a thousand hits — exactly the load the cache existed to prevent. Collapse the herd to a single loader.\n\n## Procedure\n\n1. Recognise the shape: an origin QPS spike that coincides with a key's TTL boundary, with p99 rising while the key is rebuilt.\n2. Single-flight in-process: coalesce concurrent loads for the same key into one. Go's `golang.org\u002Fx\u002Fsync\u002Fsingleflight`, Node's `p-memoize`, or a per-key promise map:\n```python\ninflight = {}\nasync def get(key):\n    if key not in inflight:\n        inflight[key] = asyncio.create_task(load(key))\n    return await inflight.pop(key)\n```\n3. Across processes, take a short distributed lock before recomputing; losers wait briefly then re-read the now-populated key:\n```python\nif redis.set(f\"lock:{key}\", 1, nx=True, ex=10):\n    val = load(key); redis.setex(key, 300, val)\nelse:\n    await asyncio.sleep(0.05); return await get(key)\n```\n4. Prefer stale-while-revalidate over blocking: serve the expired value and refresh in the background, with `stale-if-error` covering an origin outage.\n5. Jitter every TTL so keys never expire together: `ttl = 300 + random.randint(0, 30)`.\n6. Pre-warm the hottest keys on deploy or on a schedule, before the boundary rather than after it.\n7. Bound the wait: a crashed lock holder must release via the key's `ex` TTL, never via a manual unlock that can deadlock.\n\n## Pitfalls\n\n- A lock with no TTL — a crashed holder blocks the key forever.\n- Serving stale for a security-critical value (auth token, balance) where staleness is not acceptable.\n- Single-flight keyed by a lossy key (`user`) so unrelated tenants collide.\n- Refreshing in the background but never logging failures, so the stale value is served indefinitely.\n- Collapsing the herd and still exceeding a rate-limited upstream's quota on the one reload.\n- A per-process lock only, so N pods still produce N origin calls.\n\n## Verification\n\n    redis-cli monitor | grep -c \"lock:\"      # one lock and one origin load per key\n    for i in $(seq 1 200); do curl -s localhost:8080\u002Fhot >\u002Fdev\u002Fnull & done; wait\n    grep -c \"origin_call\" app.log            # pass: ~1, not ~200\n\nReport the collapse mechanism, the origin call count for N concurrent misses of a cold key, and the TTL jitter range used.\n",{"name":5,"description":7},"main","3df1d0d67b30ff15236561f8c0f9f06d33f42dfd","skills\u002Fpayments\u002F0xklen-prevent-cache-stampede-with-single-flight",17,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia","https:\u002F\u002Feth2030.com","Hardcore infra. Building @alt-research and applied cryptography.","2026-11-11 08:47:40",{"source":8,"skillName":5,"commands":48,"prompt":58,"zipAvailable":59},[49,52,55],{"tool":50,"command":51},"npx","npx skills add jiayaoqijia\u002Fcryptoskill --skill prevent-cache-stampede-with-single-flight",{"tool":53,"command":54},"bunx","bunx skills add jiayaoqijia\u002Fcryptoskill --skill prevent-cache-stampede-with-single-flight",{"tool":56,"command":57},"pnpm","pnpm dlx skills add jiayaoqijia\u002Fcryptoskill --skill prevent-cache-stampede-with-single-flight","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-prevent-cache-stampede-with-single-flight\u002FSKILL.md",true,[61,65,71],{"path":62,"resourceType":62,"resourceTypeDesc":63,"sizeBytes":64,"sourceHtmlUrl":16},"LICENSE","许可证",1063,{"path":66,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":69,"sourceHtmlUrl":70},"SOURCE.md","REFERENCE","参考文档",367,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-prevent-cache-stampede-with-single-flight\u002FSOURCE.md",{"path":72,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":73,"sourceHtmlUrl":74},"TRUST.auto.yaml",2202,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-prevent-cache-stampede-with-single-flight\u002FTRUST.auto.yaml",[76,104,127,145,158,168],{"skillNo":77,"name":78,"nameZh":6,"description":79,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":80,"sourceHtmlUrl":81,"categories":82,"keywords":83,"publishedAt":33},"01M712C436EQYE43342Q4E7GG1","recipe-performance","Diagnose a specific MetaMask user flow's real-app performance and Sentry critical-user-flow telemetry with deterministic mm-harness recipes. Use for CUF boundaries, cold\u002Fwarm\u002Fbackground-resume behavior, latency regressions, lifecycle tags, duplicate or blocking network requests, long tasks, layout\u002Fpaint cost, screen redraws, React rerenders, or browser trace analysis where tests alone cannot prove the real app.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FSKILL.md",[],[84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103],"performance","recipe performance","recipe","mm","sentry","harness","app","deterministic","recipes","flow","cold","critical","analysis","tasks","react","browser","layout","screen","network","metamask",{"skillNo":105,"name":106,"nameZh":6,"description":107,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":108,"licenseFileUrl":109,"sourceHtmlUrl":110,"categories":111,"keywords":112,"publishedAt":33},"01M70XT2F8A5CQZ81JBP98KSW3","mexc-spot-websocket","MEXC Spot WebSocket workflows for public streams, protobuf handling, depth maintenance, listen keys, and private streams without exposing API keys.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FSKILL.md",[],[113,114,115,116,117,118,119,120,121,122,123,124,125,126],"mexc spot websocket","spot","websocket","api","workflows","public","listen","streams","depth","keys","for","api keys","maintenance","protobuf",{"skillNo":128,"name":129,"nameZh":6,"description":130,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":108,"licenseFileUrl":131,"sourceHtmlUrl":132,"categories":133,"keywords":134,"publishedAt":33},"01M70XT0MBXN3WZY1BKN0CPNKR","mexc-spot-rest","MEXC Spot REST workflows for public data, signed account requests, orders, wallet\u002Fadmin actions, and secure signing without exposing API keys.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FSKILL.md",[],[135,114,136,137,138,139,140,124,123,122,141,142,143,118,144,117,116],"mexc spot rest","REST","admin","signing","Wallet","requests","actions","secure","data","orders",{"skillNo":146,"name":147,"nameZh":6,"description":148,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":108,"licenseFileUrl":149,"sourceHtmlUrl":150,"categories":151,"keywords":152,"publishedAt":33},"01M70XSYSVZ2N0N91XCAR2CAK0","mexc-futures-websocket","MEXC Futures WebSocket workflows for public streams, private account\u002Forder\u002Fposition streams, ping\u002Fpong, subscriptions, and depth maintenance.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FSKILL.md",[],[153,154,115,155,156,125,123,157,121,120,118,117],"mexc futures websocket","futures","position","ping","subscriptions",{"skillNo":159,"name":160,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":161,"sourceHtmlUrl":162,"categories":163,"keywords":164,"publishedAt":33},"01M6H0ZWHVE5W04WG2DKQE2SQC","0xklen-version-and-refresh-sanctions-lists","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FSKILL.md",[],[165,166,167],"refresh","0xklen version and refresh sanctions lists","version",{"skillNo":169,"name":170,"nameZh":6,"description":171,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":172,"sourceHtmlUrl":173,"categories":174,"keywords":175,"publishedAt":33},"01M6H0Z28Q3R8J0S799GJQWXM3","verify-tests-cover-changed-lines","Use when a PR adds code that the existing suite may not exercise. Measures patch coverage — the share of newly changed lines hit by tests — before approving.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FSKILL.md",[],[176,177,178,179,180,181,182,24,183,184,185],"tests","cover","verify tests cover changed lines","verify","coverage","pr","exercise","patch","code","share"]