[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-trigger-dev-staff-engineering-skills-memory-leaks":3,"mdc--uxry4h-key":40,"related-repo-trigger-dev-staff-engineering-skills-memory-leaks":3400,"related-org-trigger-dev-staff-engineering-skills-memory-leaks":3483},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":29,"repoUrl":30,"updatedAt":31,"license":32,"forks":33,"topics":34,"repo":35,"sourceUrl":38,"mdContent":39},"staff-engineering-skills-memory-leaks","detect and prevent memory leaks","Prevent memory leaks in garbage-collected languages (Node.js, Go). Use when writing code that accumulates state over time -- in-memory caches, event listeners, timers, closures, goroutines, or any data structure that grows as requests are processed. Activates on patterns like module-level Map\u002FSet\u002FArray that grows without eviction, addEventListener or .on() without corresponding removal, setInterval without clearInterval, closures capturing large objects, Go goroutines without cancellation, or defer inside loops.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"trigger-dev","Trigger.dev","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Ftrigger-dev.jpg","triggerdotdev",[13,17,20,23,26],{"name":14,"slug":15,"type":16},"Performance","performance","tag",{"name":18,"slug":19,"type":16},"Engineering","engineering",{"name":21,"slug":22,"type":16},"Node.js","nodejs",{"name":24,"slug":25,"type":16},"Debugging","debugging",{"name":27,"slug":28,"type":16},"Go","go",3,"https:\u002F\u002Fgithub.com\u002Ftriggerdotdev\u002Fstaff-engineering-skills","2026-06-17T08:40:51.326772",null,1,[],{"repoUrl":30,"stars":29,"forks":33,"topics":36,"description":37},[],"Skills that give AI   coding agents staff-engineer instincts: recognizing and avoiding production failure modes like cardinality, idempotency, and race conditions.","https:\u002F\u002Fgithub.com\u002Ftriggerdotdev\u002Fstaff-engineering-skills\u002Ftree\u002FHEAD\u002Fskills\u002Fstaff-engineering-skills-memory-leaks","---\nname: staff-engineering-skills-memory-leaks\ndescription: Prevent memory leaks in garbage-collected languages (Node.js, Go). Use when writing code that accumulates state over time -- in-memory caches, event listeners, timers, closures, goroutines, or any data structure that grows as requests are processed. Activates on patterns like module-level Map\u002FSet\u002FArray that grows without eviction, addEventListener or .on() without corresponding removal, setInterval without clearInterval, closures capturing large objects, Go goroutines without cancellation, or defer inside loops.\n---\n\n# Memory Leaks Trap\n\nIt works fine in testing. After a week in production, the OOM killer visits. Before writing any code that accumulates state, ask: **what removes entries from this, and what limits its size?**\n\n## How Memory Leaks Happen in GC Languages\n\nIn JavaScript and Go, leaks aren't about forgetting `free()`. They're about holding references you no longer need. The GC only reclaims **unreachable** memory; a reference held through a Map, closure, listener, or goroutine pins that memory forever.\n\nThe danger is the time dimension. A 200-byte-per-request leak is invisible in a 100-request test. At 1,000 req\u002Fs, it's 17GB per day.\n\n## The Five Leak Patterns\n\n| Pattern | What happens | How to spot it |\n|---------|-------------|----------------|\n| **Unbounded accumulator** | Map\u002FSet\u002FArray grows without eviction | Module-level collection with `.set()`\u002F`.push()` but no `.delete()`\u002F`.pop()` |\n| **Event listener leak** | New listener per request, never removed | `.on()`\u002F`addEventListener` without matching `.off()`\u002F`removeEventListener` |\n| **Closure capture** | Callback pins a large object in scope | Closure on a long-lived callback referencing outer-scope variables |\n| **Timer leak** | `setInterval` runs forever | No `clearInterval` on shutdown or when the resource is gone |\n| **Goroutine leak** (Go) | Goroutine blocks on channel\u002Flock forever | `go func()` without context cancellation or channel close |\n\n## Detection: When You're Writing a Leak\n\n**Stop and fix if you see:**\n\n1. **`new Map()`\u002F`new Set()`\u002F`[]` at module scope with `.set()`\u002F`.push()` but no removal** -- if nothing limits its size or evicts old entries, it grows until OOM.\n\n2. **`.on(\"event\", handler)` or `addEventListener` without matching `.off()`\u002F`removeEventListener`** -- every call adds a listener; per-request or per-connection, they accumulate. Node warns with `MaxListenersExceededWarning` -- never suppress it.\n\n3. **`setInterval` without `clearInterval`** -- the timer runs forever and pins any objects its callback references. Clear it when the owning resource is destroyed.\n\n4. **A closure passed to a long-lived callback (scheduler, event bus, queue)** -- check what it captures. It may pin the entire request context or a large dataset even if it uses one field.\n\n5. **`go func()` reading a channel or waiting on a lock without a context\u002Fdone channel** -- if the channel never closes and the context never cancels, it blocks forever. Each leaked goroutine holds 8KB+ of stack plus referenced data.\n\n6. **`defer` inside a loop** (Go) -- defer runs when the **function** returns, not the iteration. In a 100,000-item loop, all deferred calls accumulate until the function exits.\n\n## Patterns\n\n### Bounded cache with LRU eviction\n\nNever use a plain `Map` as a cache. Always use LRU (or similar) with a `max` size and `ttl` so the memory ceiling is predictable.\n\n```typescript\nimport { LRUCache } from \"lru-cache\";\n\nconst userCache = new LRUCache\u003Cstring, User>({ max: 10_000, ttl: 5 * 60 * 1000 });\n\nexport async function getUser(id: string): Promise\u003CUser> {\n  const cached = userCache.get(id);\n  if (cached) return cached;\n  const user = await db.users.findUnique({ where: { id } });\n  userCache.set(id, user);\n  return user;\n}\n```\n\n### Event listener cleanup\n\nEvery `.on()` needs a corresponding `.off()` tied to the lifecycle of the resource that owns the listener. With modern APIs, an `AbortController` `signal` removes all listeners tied to it on `abort()`:\n\n```typescript\nexport function handleWebSocket(ws: WebSocket, userId: string) {\n  const ac = new AbortController();\n  eventBus.on(\"notification\", (event) => {\n    if (event.userId === userId) ws.send(JSON.stringify(event));\n  }, { signal: ac.signal });\n  ws.on(\"close\", () => ac.abort()); \u002F\u002F removes the listener\n}\n```\n\n### Closures that don't capture more than they need\n\n```typescript\n\u002F\u002F BAD: closure captures largeDataset (500MB) even though it only uses summary\nasync function processReport(reportId: string) {\n  const largeDataset = await fetchDataset(reportId);\n  const summary = summarize(largeDataset);\n  scheduler.onComplete(reportId, () => notifyUser(`Report ${reportId}: ${summary}`));\n  \u002F\u002F largeDataset is pinned by the closure's scope -- can't be GC'd\n}\n\n\u002F\u002F GOOD: extract needed values before creating the closure\nasync function processReport(reportId: string) {\n  const largeDataset = await fetchDataset(reportId);\n  const message = `Report ${reportId}: ${summarize(largeDataset)}`;\n  scheduler.onComplete(reportId, () => notifyUser(message));\n  \u002F\u002F largeDataset is now eligible for GC\n}\n```\n\n### WeakMap for metadata on transient objects\n\nUse `WeakMap` to attach metadata to objects whose lifecycle you don't control. Unlike `Map`, it doesn't prevent GC of its keys, so entries vanish automatically with no manual cleanup.\n\n```typescript\nconst requestMetadata = new WeakMap\u003CRequest, { startTime: number; traceId: string }>();\n\nexport function trackRequest(req: Request) {\n  requestMetadata.set(req, { startTime: Date.now(), traceId: crypto.randomUUID() });\n}\n\u002F\u002F Entry removed automatically when the Request is GC'd after the response.\n```\n\n### Timer cleanup\n\n```typescript\nexport function startHeartbeat(connection: Connection) {\n  const timer = setInterval(() => connection.ping(), 30_000);\n  connection.on(\"close\", () => clearInterval(timer));\n  process.on(\"SIGTERM\", () => clearInterval(timer)); \u002F\u002F also clear on shutdown\n}\n```\n\n### Go: goroutine lifecycle with context\n\nEvery goroutine needs an exit path -- channel closed, context cancelled, or both. Without one, it's a leak.\n\n```go\nfunc watchForUpdates(ctx context.Context, ch \u003C-chan Update, handler func(Update)) {\n    go func() {\n        for {\n            select {\n            case update, ok := \u003C-ch:\n                if !ok { return } \u002F\u002F channel closed\n                handler(update)\n            case \u003C-ctx.Done():\n                return \u002F\u002F context cancelled\n            }\n        }\n    }()\n}\n```\n\n### Go: defer in loops -- extract to a function\n\n```go\n\u002F\u002F BAD: all file handles stay open until processFiles returns\nfunc processFiles(paths []string) error {\n    for _, path := range paths {\n        f, _ := os.Open(path)\n        defer f.Close() \u002F\u002F accumulates!\n    }\n    return nil\n}\n\n\u002F\u002F GOOD: defer runs per-iteration because it lives in its own function scope\nfunc processFiles(paths []string) error {\n    for _, path := range paths {\n        if err := processFile(path); err != nil { return err }\n    }\n    return nil\n}\n\nfunc processFile(path string) error {\n    f, err := os.Open(path)\n    if err != nil { return err }\n    defer f.Close()\n    return nil\n}\n```\n\n## The Container Restart Mask\n\nContainers mask leaks. A 20MB\u002Fhour leak in a 512MB pod OOM-restarts every ~24 hours -- teams see one restart a day and call it \"container flakiness.\" It persists for months until a traffic increase makes it OOM every 6 hours and someone investigates.\n\n**Periodic restarts at a regular interval = suspect a memory leak.** Plot memory over time -- a linear upward trend is the signature.\n\n## Anti-Patterns\n\n```typescript\n\u002F\u002F Unbounded Map: grows until OOM\nconst cache = new Map\u003Cstring, any>();\nfunction getItem(key) { if (!cache.has(key)) cache.set(key, fetchItem(key)); }\n\n\u002F\u002F Listener leak: new listener per connection, never removed\neventBus.on(\"event\", (data) => ws.send(data)); \u002F\u002F in a per-connection handler\n\n\u002F\u002F Timer leak: no clearInterval anywhere\nsetInterval(() => refreshData(), 60_000);\n\n\u002F\u002F Closure capture: pins 500MB dataset via scope\nconst data = await fetchLargeDataset();\nconst summary = summarize(data);\nscheduler.later(() => log(`Done: ${summary}`)); \u002F\u002F data is pinned\n```\n\n## Related Traps\n\n- **Cache Invalidation** -- unbounded caches are the most common source of memory leaks. Every cache needs a max size and eviction policy. See the Cache Invalidation skill.\n- **Backpressure** -- unbounded buffers (queues, arrays) that grow because the consumer can't keep up are both a backpressure failure and a memory leak. Apply backpressure before the buffer exhausts memory.\n- **Thundering Herd** -- when an OOM-killed process restarts with cold caches, the sudden spike in cache misses can cause a thundering herd on the database.\n",{"data":41,"body":42},{"name":4,"description":6},{"type":43,"children":44},"root",[45,54,66,73,94,99,105,320,326,334,491,497,504,533,1061,1067,1109,1482,1488,1967,1973,1993,2251,2257,2517,2523,2528,2639,2645,2834,2840,2845,2855,2861,3354,3360,3394],{"type":46,"tag":47,"props":48,"children":50},"element","h1",{"id":49},"memory-leaks-trap",[51],{"type":52,"value":53},"text","Memory Leaks Trap",{"type":46,"tag":55,"props":56,"children":57},"p",{},[58,60],{"type":52,"value":59},"It works fine in testing. After a week in production, the OOM killer visits. Before writing any code that accumulates state, ask: ",{"type":46,"tag":61,"props":62,"children":63},"strong",{},[64],{"type":52,"value":65},"what removes entries from this, and what limits its size?",{"type":46,"tag":67,"props":68,"children":70},"h2",{"id":69},"how-memory-leaks-happen-in-gc-languages",[71],{"type":52,"value":72},"How Memory Leaks Happen in GC Languages",{"type":46,"tag":55,"props":74,"children":75},{},[76,78,85,87,92],{"type":52,"value":77},"In JavaScript and Go, leaks aren't about forgetting ",{"type":46,"tag":79,"props":80,"children":82},"code",{"className":81},[],[83],{"type":52,"value":84},"free()",{"type":52,"value":86},". They're about holding references you no longer need. The GC only reclaims ",{"type":46,"tag":61,"props":88,"children":89},{},[90],{"type":52,"value":91},"unreachable",{"type":52,"value":93}," memory; a reference held through a Map, closure, listener, or goroutine pins that memory forever.",{"type":46,"tag":55,"props":95,"children":96},{},[97],{"type":52,"value":98},"The danger is the time dimension. A 200-byte-per-request leak is invisible in a 100-request test. At 1,000 req\u002Fs, it's 17GB per day.",{"type":46,"tag":67,"props":100,"children":102},{"id":101},"the-five-leak-patterns",[103],{"type":52,"value":104},"The Five Leak Patterns",{"type":46,"tag":106,"props":107,"children":108},"table",{},[109,133],{"type":46,"tag":110,"props":111,"children":112},"thead",{},[113],{"type":46,"tag":114,"props":115,"children":116},"tr",{},[117,123,128],{"type":46,"tag":118,"props":119,"children":120},"th",{},[121],{"type":52,"value":122},"Pattern",{"type":46,"tag":118,"props":124,"children":125},{},[126],{"type":52,"value":127},"What happens",{"type":46,"tag":118,"props":129,"children":130},{},[131],{"type":52,"value":132},"How to spot it",{"type":46,"tag":134,"props":135,"children":136},"tbody",{},[137,188,235,256,291],{"type":46,"tag":114,"props":138,"children":139},{},[140,149,154],{"type":46,"tag":141,"props":142,"children":143},"td",{},[144],{"type":46,"tag":61,"props":145,"children":146},{},[147],{"type":52,"value":148},"Unbounded accumulator",{"type":46,"tag":141,"props":150,"children":151},{},[152],{"type":52,"value":153},"Map\u002FSet\u002FArray grows without eviction",{"type":46,"tag":141,"props":155,"children":156},{},[157,159,165,167,173,175,181,182],{"type":52,"value":158},"Module-level collection with ",{"type":46,"tag":79,"props":160,"children":162},{"className":161},[],[163],{"type":52,"value":164},".set()",{"type":52,"value":166},"\u002F",{"type":46,"tag":79,"props":168,"children":170},{"className":169},[],[171],{"type":52,"value":172},".push()",{"type":52,"value":174}," but no ",{"type":46,"tag":79,"props":176,"children":178},{"className":177},[],[179],{"type":52,"value":180},".delete()",{"type":52,"value":166},{"type":46,"tag":79,"props":183,"children":185},{"className":184},[],[186],{"type":52,"value":187},".pop()",{"type":46,"tag":114,"props":189,"children":190},{},[191,199,204],{"type":46,"tag":141,"props":192,"children":193},{},[194],{"type":46,"tag":61,"props":195,"children":196},{},[197],{"type":52,"value":198},"Event listener leak",{"type":46,"tag":141,"props":200,"children":201},{},[202],{"type":52,"value":203},"New listener per request, never removed",{"type":46,"tag":141,"props":205,"children":206},{},[207,213,214,220,222,228,229],{"type":46,"tag":79,"props":208,"children":210},{"className":209},[],[211],{"type":52,"value":212},".on()",{"type":52,"value":166},{"type":46,"tag":79,"props":215,"children":217},{"className":216},[],[218],{"type":52,"value":219},"addEventListener",{"type":52,"value":221}," without matching ",{"type":46,"tag":79,"props":223,"children":225},{"className":224},[],[226],{"type":52,"value":227},".off()",{"type":52,"value":166},{"type":46,"tag":79,"props":230,"children":232},{"className":231},[],[233],{"type":52,"value":234},"removeEventListener",{"type":46,"tag":114,"props":236,"children":237},{},[238,246,251],{"type":46,"tag":141,"props":239,"children":240},{},[241],{"type":46,"tag":61,"props":242,"children":243},{},[244],{"type":52,"value":245},"Closure capture",{"type":46,"tag":141,"props":247,"children":248},{},[249],{"type":52,"value":250},"Callback pins a large object in scope",{"type":46,"tag":141,"props":252,"children":253},{},[254],{"type":52,"value":255},"Closure on a long-lived callback referencing outer-scope variables",{"type":46,"tag":114,"props":257,"children":258},{},[259,267,278],{"type":46,"tag":141,"props":260,"children":261},{},[262],{"type":46,"tag":61,"props":263,"children":264},{},[265],{"type":52,"value":266},"Timer leak",{"type":46,"tag":141,"props":268,"children":269},{},[270,276],{"type":46,"tag":79,"props":271,"children":273},{"className":272},[],[274],{"type":52,"value":275},"setInterval",{"type":52,"value":277}," runs forever",{"type":46,"tag":141,"props":279,"children":280},{},[281,283,289],{"type":52,"value":282},"No ",{"type":46,"tag":79,"props":284,"children":286},{"className":285},[],[287],{"type":52,"value":288},"clearInterval",{"type":52,"value":290}," on shutdown or when the resource is gone",{"type":46,"tag":114,"props":292,"children":293},{},[294,304,309],{"type":46,"tag":141,"props":295,"children":296},{},[297,302],{"type":46,"tag":61,"props":298,"children":299},{},[300],{"type":52,"value":301},"Goroutine leak",{"type":52,"value":303}," (Go)",{"type":46,"tag":141,"props":305,"children":306},{},[307],{"type":52,"value":308},"Goroutine blocks on channel\u002Flock forever",{"type":46,"tag":141,"props":310,"children":311},{},[312,318],{"type":46,"tag":79,"props":313,"children":315},{"className":314},[],[316],{"type":52,"value":317},"go func()",{"type":52,"value":319}," without context cancellation or channel close",{"type":46,"tag":67,"props":321,"children":323},{"id":322},"detection-when-youre-writing-a-leak",[324],{"type":52,"value":325},"Detection: When You're Writing a Leak",{"type":46,"tag":55,"props":327,"children":328},{},[329],{"type":46,"tag":61,"props":330,"children":331},{},[332],{"type":52,"value":333},"Stop and fix if you see:",{"type":46,"tag":335,"props":336,"children":337},"ol",{},[338,382,423,443,453,468],{"type":46,"tag":339,"props":340,"children":341},"li",{},[342,380],{"type":46,"tag":61,"props":343,"children":344},{},[345,351,352,358,359,365,367,372,373,378],{"type":46,"tag":79,"props":346,"children":348},{"className":347},[],[349],{"type":52,"value":350},"new Map()",{"type":52,"value":166},{"type":46,"tag":79,"props":353,"children":355},{"className":354},[],[356],{"type":52,"value":357},"new Set()",{"type":52,"value":166},{"type":46,"tag":79,"props":360,"children":362},{"className":361},[],[363],{"type":52,"value":364},"[]",{"type":52,"value":366}," at module scope with ",{"type":46,"tag":79,"props":368,"children":370},{"className":369},[],[371],{"type":52,"value":164},{"type":52,"value":166},{"type":46,"tag":79,"props":374,"children":376},{"className":375},[],[377],{"type":52,"value":172},{"type":52,"value":379}," but no removal",{"type":52,"value":381}," -- if nothing limits its size or evicts old entries, it grows until OOM.",{"type":46,"tag":339,"props":383,"children":384},{},[385,413,415,421],{"type":46,"tag":61,"props":386,"children":387},{},[388,394,396,401,402,407,408],{"type":46,"tag":79,"props":389,"children":391},{"className":390},[],[392],{"type":52,"value":393},".on(\"event\", handler)",{"type":52,"value":395}," or ",{"type":46,"tag":79,"props":397,"children":399},{"className":398},[],[400],{"type":52,"value":219},{"type":52,"value":221},{"type":46,"tag":79,"props":403,"children":405},{"className":404},[],[406],{"type":52,"value":227},{"type":52,"value":166},{"type":46,"tag":79,"props":409,"children":411},{"className":410},[],[412],{"type":52,"value":234},{"type":52,"value":414}," -- every call adds a listener; per-request or per-connection, they accumulate. Node warns with ",{"type":46,"tag":79,"props":416,"children":418},{"className":417},[],[419],{"type":52,"value":420},"MaxListenersExceededWarning",{"type":52,"value":422}," -- never suppress it.",{"type":46,"tag":339,"props":424,"children":425},{},[426,441],{"type":46,"tag":61,"props":427,"children":428},{},[429,434,436],{"type":46,"tag":79,"props":430,"children":432},{"className":431},[],[433],{"type":52,"value":275},{"type":52,"value":435}," without ",{"type":46,"tag":79,"props":437,"children":439},{"className":438},[],[440],{"type":52,"value":288},{"type":52,"value":442}," -- the timer runs forever and pins any objects its callback references. Clear it when the owning resource is destroyed.",{"type":46,"tag":339,"props":444,"children":445},{},[446,451],{"type":46,"tag":61,"props":447,"children":448},{},[449],{"type":52,"value":450},"A closure passed to a long-lived callback (scheduler, event bus, queue)",{"type":52,"value":452}," -- check what it captures. It may pin the entire request context or a large dataset even if it uses one field.",{"type":46,"tag":339,"props":454,"children":455},{},[456,466],{"type":46,"tag":61,"props":457,"children":458},{},[459,464],{"type":46,"tag":79,"props":460,"children":462},{"className":461},[],[463],{"type":52,"value":317},{"type":52,"value":465}," reading a channel or waiting on a lock without a context\u002Fdone channel",{"type":52,"value":467}," -- if the channel never closes and the context never cancels, it blocks forever. Each leaked goroutine holds 8KB+ of stack plus referenced data.",{"type":46,"tag":339,"props":469,"children":470},{},[471,482,484,489],{"type":46,"tag":61,"props":472,"children":473},{},[474,480],{"type":46,"tag":79,"props":475,"children":477},{"className":476},[],[478],{"type":52,"value":479},"defer",{"type":52,"value":481}," inside a loop",{"type":52,"value":483}," (Go) -- defer runs when the ",{"type":46,"tag":61,"props":485,"children":486},{},[487],{"type":52,"value":488},"function",{"type":52,"value":490}," returns, not the iteration. In a 100,000-item loop, all deferred calls accumulate until the function exits.",{"type":46,"tag":67,"props":492,"children":494},{"id":493},"patterns",[495],{"type":52,"value":496},"Patterns",{"type":46,"tag":498,"props":499,"children":501},"h3",{"id":500},"bounded-cache-with-lru-eviction",[502],{"type":52,"value":503},"Bounded cache with LRU eviction",{"type":46,"tag":55,"props":505,"children":506},{},[507,509,515,517,523,525,531],{"type":52,"value":508},"Never use a plain ",{"type":46,"tag":79,"props":510,"children":512},{"className":511},[],[513],{"type":52,"value":514},"Map",{"type":52,"value":516}," as a cache. Always use LRU (or similar) with a ",{"type":46,"tag":79,"props":518,"children":520},{"className":519},[],[521],{"type":52,"value":522},"max",{"type":52,"value":524}," size and ",{"type":46,"tag":79,"props":526,"children":528},{"className":527},[],[529],{"type":52,"value":530},"ttl",{"type":52,"value":532}," so the memory ceiling is predictable.",{"type":46,"tag":534,"props":535,"children":540},"pre",{"className":536,"code":537,"language":538,"meta":539,"style":539},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { LRUCache } from \"lru-cache\";\n\nconst userCache = new LRUCache\u003Cstring, User>({ max: 10_000, ttl: 5 * 60 * 1000 });\n\nexport async function getUser(id: string): Promise\u003CUser> {\n  const cached = userCache.get(id);\n  if (cached) return cached;\n  const user = await db.users.findUnique({ where: { id } });\n  userCache.set(id, user);\n  return user;\n}\n","typescript","",[541],{"type":46,"tag":79,"props":542,"children":543},{"__ignoreMap":539},[544,598,608,740,748,819,869,906,993,1035,1052],{"type":46,"tag":545,"props":546,"children":548},"span",{"class":547,"line":33},"line",[549,555,561,567,572,577,582,588,593],{"type":46,"tag":545,"props":550,"children":552},{"style":551},"--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic",[553],{"type":52,"value":554},"import",{"type":46,"tag":545,"props":556,"children":558},{"style":557},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[559],{"type":52,"value":560}," {",{"type":46,"tag":545,"props":562,"children":564},{"style":563},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[565],{"type":52,"value":566}," LRUCache",{"type":46,"tag":545,"props":568,"children":569},{"style":557},[570],{"type":52,"value":571}," }",{"type":46,"tag":545,"props":573,"children":574},{"style":551},[575],{"type":52,"value":576}," from",{"type":46,"tag":545,"props":578,"children":579},{"style":557},[580],{"type":52,"value":581}," \"",{"type":46,"tag":545,"props":583,"children":585},{"style":584},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[586],{"type":52,"value":587},"lru-cache",{"type":46,"tag":545,"props":589,"children":590},{"style":557},[591],{"type":52,"value":592},"\"",{"type":46,"tag":545,"props":594,"children":595},{"style":557},[596],{"type":52,"value":597},";\n",{"type":46,"tag":545,"props":599,"children":601},{"class":547,"line":600},2,[602],{"type":46,"tag":545,"props":603,"children":605},{"emptyLinePlaceholder":604},true,[606],{"type":52,"value":607},"\n",{"type":46,"tag":545,"props":609,"children":610},{"class":547,"line":29},[611,617,622,627,632,637,642,648,653,658,663,668,673,679,684,690,694,699,703,708,713,718,722,727,731,736],{"type":46,"tag":545,"props":612,"children":614},{"style":613},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[615],{"type":52,"value":616},"const",{"type":46,"tag":545,"props":618,"children":619},{"style":563},[620],{"type":52,"value":621}," userCache ",{"type":46,"tag":545,"props":623,"children":624},{"style":557},[625],{"type":52,"value":626},"=",{"type":46,"tag":545,"props":628,"children":629},{"style":557},[630],{"type":52,"value":631}," new",{"type":46,"tag":545,"props":633,"children":635},{"style":634},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[636],{"type":52,"value":566},{"type":46,"tag":545,"props":638,"children":639},{"style":557},[640],{"type":52,"value":641},"\u003C",{"type":46,"tag":545,"props":643,"children":645},{"style":644},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[646],{"type":52,"value":647},"string",{"type":46,"tag":545,"props":649,"children":650},{"style":557},[651],{"type":52,"value":652},",",{"type":46,"tag":545,"props":654,"children":655},{"style":644},[656],{"type":52,"value":657}," User",{"type":46,"tag":545,"props":659,"children":660},{"style":557},[661],{"type":52,"value":662},">",{"type":46,"tag":545,"props":664,"children":665},{"style":563},[666],{"type":52,"value":667},"(",{"type":46,"tag":545,"props":669,"children":670},{"style":557},[671],{"type":52,"value":672},"{",{"type":46,"tag":545,"props":674,"children":676},{"style":675},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[677],{"type":52,"value":678}," max",{"type":46,"tag":545,"props":680,"children":681},{"style":557},[682],{"type":52,"value":683},":",{"type":46,"tag":545,"props":685,"children":687},{"style":686},"--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C",[688],{"type":52,"value":689}," 10_000",{"type":46,"tag":545,"props":691,"children":692},{"style":557},[693],{"type":52,"value":652},{"type":46,"tag":545,"props":695,"children":696},{"style":675},[697],{"type":52,"value":698}," ttl",{"type":46,"tag":545,"props":700,"children":701},{"style":557},[702],{"type":52,"value":683},{"type":46,"tag":545,"props":704,"children":705},{"style":686},[706],{"type":52,"value":707}," 5",{"type":46,"tag":545,"props":709,"children":710},{"style":557},[711],{"type":52,"value":712}," *",{"type":46,"tag":545,"props":714,"children":715},{"style":686},[716],{"type":52,"value":717}," 60",{"type":46,"tag":545,"props":719,"children":720},{"style":557},[721],{"type":52,"value":712},{"type":46,"tag":545,"props":723,"children":724},{"style":686},[725],{"type":52,"value":726}," 1000",{"type":46,"tag":545,"props":728,"children":729},{"style":557},[730],{"type":52,"value":571},{"type":46,"tag":545,"props":732,"children":733},{"style":563},[734],{"type":52,"value":735},")",{"type":46,"tag":545,"props":737,"children":738},{"style":557},[739],{"type":52,"value":597},{"type":46,"tag":545,"props":741,"children":743},{"class":547,"line":742},4,[744],{"type":46,"tag":545,"props":745,"children":746},{"emptyLinePlaceholder":604},[747],{"type":52,"value":607},{"type":46,"tag":545,"props":749,"children":751},{"class":547,"line":750},5,[752,757,762,767,772,776,782,786,791,796,801,805,810,814],{"type":46,"tag":545,"props":753,"children":754},{"style":551},[755],{"type":52,"value":756},"export",{"type":46,"tag":545,"props":758,"children":759},{"style":613},[760],{"type":52,"value":761}," async",{"type":46,"tag":545,"props":763,"children":764},{"style":613},[765],{"type":52,"value":766}," function",{"type":46,"tag":545,"props":768,"children":769},{"style":634},[770],{"type":52,"value":771}," getUser",{"type":46,"tag":545,"props":773,"children":774},{"style":557},[775],{"type":52,"value":667},{"type":46,"tag":545,"props":777,"children":779},{"style":778},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic",[780],{"type":52,"value":781},"id",{"type":46,"tag":545,"props":783,"children":784},{"style":557},[785],{"type":52,"value":683},{"type":46,"tag":545,"props":787,"children":788},{"style":644},[789],{"type":52,"value":790}," string",{"type":46,"tag":545,"props":792,"children":793},{"style":557},[794],{"type":52,"value":795},"):",{"type":46,"tag":545,"props":797,"children":798},{"style":644},[799],{"type":52,"value":800}," Promise",{"type":46,"tag":545,"props":802,"children":803},{"style":557},[804],{"type":52,"value":641},{"type":46,"tag":545,"props":806,"children":807},{"style":644},[808],{"type":52,"value":809},"User",{"type":46,"tag":545,"props":811,"children":812},{"style":557},[813],{"type":52,"value":662},{"type":46,"tag":545,"props":815,"children":816},{"style":557},[817],{"type":52,"value":818}," {\n",{"type":46,"tag":545,"props":820,"children":822},{"class":547,"line":821},6,[823,828,833,838,843,848,853,857,861,865],{"type":46,"tag":545,"props":824,"children":825},{"style":613},[826],{"type":52,"value":827},"  const",{"type":46,"tag":545,"props":829,"children":830},{"style":563},[831],{"type":52,"value":832}," cached",{"type":46,"tag":545,"props":834,"children":835},{"style":557},[836],{"type":52,"value":837}," =",{"type":46,"tag":545,"props":839,"children":840},{"style":563},[841],{"type":52,"value":842}," userCache",{"type":46,"tag":545,"props":844,"children":845},{"style":557},[846],{"type":52,"value":847},".",{"type":46,"tag":545,"props":849,"children":850},{"style":634},[851],{"type":52,"value":852},"get",{"type":46,"tag":545,"props":854,"children":855},{"style":675},[856],{"type":52,"value":667},{"type":46,"tag":545,"props":858,"children":859},{"style":563},[860],{"type":52,"value":781},{"type":46,"tag":545,"props":862,"children":863},{"style":675},[864],{"type":52,"value":735},{"type":46,"tag":545,"props":866,"children":867},{"style":557},[868],{"type":52,"value":597},{"type":46,"tag":545,"props":870,"children":872},{"class":547,"line":871},7,[873,878,883,888,893,898,902],{"type":46,"tag":545,"props":874,"children":875},{"style":551},[876],{"type":52,"value":877},"  if",{"type":46,"tag":545,"props":879,"children":880},{"style":675},[881],{"type":52,"value":882}," (",{"type":46,"tag":545,"props":884,"children":885},{"style":563},[886],{"type":52,"value":887},"cached",{"type":46,"tag":545,"props":889,"children":890},{"style":675},[891],{"type":52,"value":892},") ",{"type":46,"tag":545,"props":894,"children":895},{"style":551},[896],{"type":52,"value":897},"return",{"type":46,"tag":545,"props":899,"children":900},{"style":563},[901],{"type":52,"value":832},{"type":46,"tag":545,"props":903,"children":904},{"style":557},[905],{"type":52,"value":597},{"type":46,"tag":545,"props":907,"children":909},{"class":547,"line":908},8,[910,914,919,923,928,933,937,942,946,951,955,959,964,968,972,977,981,985,989],{"type":46,"tag":545,"props":911,"children":912},{"style":613},[913],{"type":52,"value":827},{"type":46,"tag":545,"props":915,"children":916},{"style":563},[917],{"type":52,"value":918}," user",{"type":46,"tag":545,"props":920,"children":921},{"style":557},[922],{"type":52,"value":837},{"type":46,"tag":545,"props":924,"children":925},{"style":551},[926],{"type":52,"value":927}," await",{"type":46,"tag":545,"props":929,"children":930},{"style":563},[931],{"type":52,"value":932}," db",{"type":46,"tag":545,"props":934,"children":935},{"style":557},[936],{"type":52,"value":847},{"type":46,"tag":545,"props":938,"children":939},{"style":563},[940],{"type":52,"value":941},"users",{"type":46,"tag":545,"props":943,"children":944},{"style":557},[945],{"type":52,"value":847},{"type":46,"tag":545,"props":947,"children":948},{"style":634},[949],{"type":52,"value":950},"findUnique",{"type":46,"tag":545,"props":952,"children":953},{"style":675},[954],{"type":52,"value":667},{"type":46,"tag":545,"props":956,"children":957},{"style":557},[958],{"type":52,"value":672},{"type":46,"tag":545,"props":960,"children":961},{"style":675},[962],{"type":52,"value":963}," where",{"type":46,"tag":545,"props":965,"children":966},{"style":557},[967],{"type":52,"value":683},{"type":46,"tag":545,"props":969,"children":970},{"style":557},[971],{"type":52,"value":560},{"type":46,"tag":545,"props":973,"children":974},{"style":563},[975],{"type":52,"value":976}," id",{"type":46,"tag":545,"props":978,"children":979},{"style":557},[980],{"type":52,"value":571},{"type":46,"tag":545,"props":982,"children":983},{"style":557},[984],{"type":52,"value":571},{"type":46,"tag":545,"props":986,"children":987},{"style":675},[988],{"type":52,"value":735},{"type":46,"tag":545,"props":990,"children":991},{"style":557},[992],{"type":52,"value":597},{"type":46,"tag":545,"props":994,"children":996},{"class":547,"line":995},9,[997,1002,1006,1011,1015,1019,1023,1027,1031],{"type":46,"tag":545,"props":998,"children":999},{"style":563},[1000],{"type":52,"value":1001},"  userCache",{"type":46,"tag":545,"props":1003,"children":1004},{"style":557},[1005],{"type":52,"value":847},{"type":46,"tag":545,"props":1007,"children":1008},{"style":634},[1009],{"type":52,"value":1010},"set",{"type":46,"tag":545,"props":1012,"children":1013},{"style":675},[1014],{"type":52,"value":667},{"type":46,"tag":545,"props":1016,"children":1017},{"style":563},[1018],{"type":52,"value":781},{"type":46,"tag":545,"props":1020,"children":1021},{"style":557},[1022],{"type":52,"value":652},{"type":46,"tag":545,"props":1024,"children":1025},{"style":563},[1026],{"type":52,"value":918},{"type":46,"tag":545,"props":1028,"children":1029},{"style":675},[1030],{"type":52,"value":735},{"type":46,"tag":545,"props":1032,"children":1033},{"style":557},[1034],{"type":52,"value":597},{"type":46,"tag":545,"props":1036,"children":1038},{"class":547,"line":1037},10,[1039,1044,1048],{"type":46,"tag":545,"props":1040,"children":1041},{"style":551},[1042],{"type":52,"value":1043},"  return",{"type":46,"tag":545,"props":1045,"children":1046},{"style":563},[1047],{"type":52,"value":918},{"type":46,"tag":545,"props":1049,"children":1050},{"style":557},[1051],{"type":52,"value":597},{"type":46,"tag":545,"props":1053,"children":1055},{"class":547,"line":1054},11,[1056],{"type":46,"tag":545,"props":1057,"children":1058},{"style":557},[1059],{"type":52,"value":1060},"}\n",{"type":46,"tag":498,"props":1062,"children":1064},{"id":1063},"event-listener-cleanup",[1065],{"type":52,"value":1066},"Event listener cleanup",{"type":46,"tag":55,"props":1068,"children":1069},{},[1070,1072,1077,1079,1084,1086,1092,1094,1100,1102,1108],{"type":52,"value":1071},"Every ",{"type":46,"tag":79,"props":1073,"children":1075},{"className":1074},[],[1076],{"type":52,"value":212},{"type":52,"value":1078}," needs a corresponding ",{"type":46,"tag":79,"props":1080,"children":1082},{"className":1081},[],[1083],{"type":52,"value":227},{"type":52,"value":1085}," tied to the lifecycle of the resource that owns the listener. With modern APIs, an ",{"type":46,"tag":79,"props":1087,"children":1089},{"className":1088},[],[1090],{"type":52,"value":1091},"AbortController",{"type":52,"value":1093}," ",{"type":46,"tag":79,"props":1095,"children":1097},{"className":1096},[],[1098],{"type":52,"value":1099},"signal",{"type":52,"value":1101}," removes all listeners tied to it on ",{"type":46,"tag":79,"props":1103,"children":1105},{"className":1104},[],[1106],{"type":52,"value":1107},"abort()",{"type":52,"value":683},{"type":46,"tag":534,"props":1110,"children":1112},{"className":536,"code":1111,"language":538,"meta":539,"style":539},"export function handleWebSocket(ws: WebSocket, userId: string) {\n  const ac = new AbortController();\n  eventBus.on(\"notification\", (event) => {\n    if (event.userId === userId) ws.send(JSON.stringify(event));\n  }, { signal: ac.signal });\n  ws.on(\"close\", () => ac.abort()); \u002F\u002F removes the listener\n}\n",[1113],{"type":46,"tag":79,"props":1114,"children":1115},{"__ignoreMap":539},[1116,1175,1209,1269,1355,1400,1475],{"type":46,"tag":545,"props":1117,"children":1118},{"class":547,"line":33},[1119,1123,1127,1132,1136,1141,1145,1150,1154,1159,1163,1167,1171],{"type":46,"tag":545,"props":1120,"children":1121},{"style":551},[1122],{"type":52,"value":756},{"type":46,"tag":545,"props":1124,"children":1125},{"style":613},[1126],{"type":52,"value":766},{"type":46,"tag":545,"props":1128,"children":1129},{"style":634},[1130],{"type":52,"value":1131}," handleWebSocket",{"type":46,"tag":545,"props":1133,"children":1134},{"style":557},[1135],{"type":52,"value":667},{"type":46,"tag":545,"props":1137,"children":1138},{"style":778},[1139],{"type":52,"value":1140},"ws",{"type":46,"tag":545,"props":1142,"children":1143},{"style":557},[1144],{"type":52,"value":683},{"type":46,"tag":545,"props":1146,"children":1147},{"style":644},[1148],{"type":52,"value":1149}," WebSocket",{"type":46,"tag":545,"props":1151,"children":1152},{"style":557},[1153],{"type":52,"value":652},{"type":46,"tag":545,"props":1155,"children":1156},{"style":778},[1157],{"type":52,"value":1158}," userId",{"type":46,"tag":545,"props":1160,"children":1161},{"style":557},[1162],{"type":52,"value":683},{"type":46,"tag":545,"props":1164,"children":1165},{"style":644},[1166],{"type":52,"value":790},{"type":46,"tag":545,"props":1168,"children":1169},{"style":557},[1170],{"type":52,"value":735},{"type":46,"tag":545,"props":1172,"children":1173},{"style":557},[1174],{"type":52,"value":818},{"type":46,"tag":545,"props":1176,"children":1177},{"class":547,"line":600},[1178,1182,1187,1191,1195,1200,1205],{"type":46,"tag":545,"props":1179,"children":1180},{"style":613},[1181],{"type":52,"value":827},{"type":46,"tag":545,"props":1183,"children":1184},{"style":563},[1185],{"type":52,"value":1186}," ac",{"type":46,"tag":545,"props":1188,"children":1189},{"style":557},[1190],{"type":52,"value":837},{"type":46,"tag":545,"props":1192,"children":1193},{"style":557},[1194],{"type":52,"value":631},{"type":46,"tag":545,"props":1196,"children":1197},{"style":634},[1198],{"type":52,"value":1199}," AbortController",{"type":46,"tag":545,"props":1201,"children":1202},{"style":675},[1203],{"type":52,"value":1204},"()",{"type":46,"tag":545,"props":1206,"children":1207},{"style":557},[1208],{"type":52,"value":597},{"type":46,"tag":545,"props":1210,"children":1211},{"class":547,"line":29},[1212,1217,1221,1226,1230,1234,1239,1243,1247,1251,1256,1260,1265],{"type":46,"tag":545,"props":1213,"children":1214},{"style":563},[1215],{"type":52,"value":1216},"  eventBus",{"type":46,"tag":545,"props":1218,"children":1219},{"style":557},[1220],{"type":52,"value":847},{"type":46,"tag":545,"props":1222,"children":1223},{"style":634},[1224],{"type":52,"value":1225},"on",{"type":46,"tag":545,"props":1227,"children":1228},{"style":675},[1229],{"type":52,"value":667},{"type":46,"tag":545,"props":1231,"children":1232},{"style":557},[1233],{"type":52,"value":592},{"type":46,"tag":545,"props":1235,"children":1236},{"style":584},[1237],{"type":52,"value":1238},"notification",{"type":46,"tag":545,"props":1240,"children":1241},{"style":557},[1242],{"type":52,"value":592},{"type":46,"tag":545,"props":1244,"children":1245},{"style":557},[1246],{"type":52,"value":652},{"type":46,"tag":545,"props":1248,"children":1249},{"style":557},[1250],{"type":52,"value":882},{"type":46,"tag":545,"props":1252,"children":1253},{"style":778},[1254],{"type":52,"value":1255},"event",{"type":46,"tag":545,"props":1257,"children":1258},{"style":557},[1259],{"type":52,"value":735},{"type":46,"tag":545,"props":1261,"children":1262},{"style":613},[1263],{"type":52,"value":1264}," =>",{"type":46,"tag":545,"props":1266,"children":1267},{"style":557},[1268],{"type":52,"value":818},{"type":46,"tag":545,"props":1270,"children":1271},{"class":547,"line":742},[1272,1277,1281,1285,1289,1294,1299,1303,1307,1311,1315,1320,1324,1329,1333,1338,1342,1346,1351],{"type":46,"tag":545,"props":1273,"children":1274},{"style":551},[1275],{"type":52,"value":1276},"    if",{"type":46,"tag":545,"props":1278,"children":1279},{"style":675},[1280],{"type":52,"value":882},{"type":46,"tag":545,"props":1282,"children":1283},{"style":563},[1284],{"type":52,"value":1255},{"type":46,"tag":545,"props":1286,"children":1287},{"style":557},[1288],{"type":52,"value":847},{"type":46,"tag":545,"props":1290,"children":1291},{"style":563},[1292],{"type":52,"value":1293},"userId",{"type":46,"tag":545,"props":1295,"children":1296},{"style":557},[1297],{"type":52,"value":1298}," ===",{"type":46,"tag":545,"props":1300,"children":1301},{"style":563},[1302],{"type":52,"value":1158},{"type":46,"tag":545,"props":1304,"children":1305},{"style":675},[1306],{"type":52,"value":892},{"type":46,"tag":545,"props":1308,"children":1309},{"style":563},[1310],{"type":52,"value":1140},{"type":46,"tag":545,"props":1312,"children":1313},{"style":557},[1314],{"type":52,"value":847},{"type":46,"tag":545,"props":1316,"children":1317},{"style":634},[1318],{"type":52,"value":1319},"send",{"type":46,"tag":545,"props":1321,"children":1322},{"style":675},[1323],{"type":52,"value":667},{"type":46,"tag":545,"props":1325,"children":1326},{"style":563},[1327],{"type":52,"value":1328},"JSON",{"type":46,"tag":545,"props":1330,"children":1331},{"style":557},[1332],{"type":52,"value":847},{"type":46,"tag":545,"props":1334,"children":1335},{"style":634},[1336],{"type":52,"value":1337},"stringify",{"type":46,"tag":545,"props":1339,"children":1340},{"style":675},[1341],{"type":52,"value":667},{"type":46,"tag":545,"props":1343,"children":1344},{"style":563},[1345],{"type":52,"value":1255},{"type":46,"tag":545,"props":1347,"children":1348},{"style":675},[1349],{"type":52,"value":1350},"))",{"type":46,"tag":545,"props":1352,"children":1353},{"style":557},[1354],{"type":52,"value":597},{"type":46,"tag":545,"props":1356,"children":1357},{"class":547,"line":750},[1358,1363,1367,1372,1376,1380,1384,1388,1392,1396],{"type":46,"tag":545,"props":1359,"children":1360},{"style":557},[1361],{"type":52,"value":1362},"  },",{"type":46,"tag":545,"props":1364,"children":1365},{"style":557},[1366],{"type":52,"value":560},{"type":46,"tag":545,"props":1368,"children":1369},{"style":675},[1370],{"type":52,"value":1371}," signal",{"type":46,"tag":545,"props":1373,"children":1374},{"style":557},[1375],{"type":52,"value":683},{"type":46,"tag":545,"props":1377,"children":1378},{"style":563},[1379],{"type":52,"value":1186},{"type":46,"tag":545,"props":1381,"children":1382},{"style":557},[1383],{"type":52,"value":847},{"type":46,"tag":545,"props":1385,"children":1386},{"style":563},[1387],{"type":52,"value":1099},{"type":46,"tag":545,"props":1389,"children":1390},{"style":557},[1391],{"type":52,"value":571},{"type":46,"tag":545,"props":1393,"children":1394},{"style":675},[1395],{"type":52,"value":735},{"type":46,"tag":545,"props":1397,"children":1398},{"style":557},[1399],{"type":52,"value":597},{"type":46,"tag":545,"props":1401,"children":1402},{"class":547,"line":821},[1403,1408,1412,1416,1420,1424,1429,1433,1437,1442,1446,1450,1454,1459,1464,1469],{"type":46,"tag":545,"props":1404,"children":1405},{"style":563},[1406],{"type":52,"value":1407},"  ws",{"type":46,"tag":545,"props":1409,"children":1410},{"style":557},[1411],{"type":52,"value":847},{"type":46,"tag":545,"props":1413,"children":1414},{"style":634},[1415],{"type":52,"value":1225},{"type":46,"tag":545,"props":1417,"children":1418},{"style":675},[1419],{"type":52,"value":667},{"type":46,"tag":545,"props":1421,"children":1422},{"style":557},[1423],{"type":52,"value":592},{"type":46,"tag":545,"props":1425,"children":1426},{"style":584},[1427],{"type":52,"value":1428},"close",{"type":46,"tag":545,"props":1430,"children":1431},{"style":557},[1432],{"type":52,"value":592},{"type":46,"tag":545,"props":1434,"children":1435},{"style":557},[1436],{"type":52,"value":652},{"type":46,"tag":545,"props":1438,"children":1439},{"style":557},[1440],{"type":52,"value":1441}," ()",{"type":46,"tag":545,"props":1443,"children":1444},{"style":613},[1445],{"type":52,"value":1264},{"type":46,"tag":545,"props":1447,"children":1448},{"style":563},[1449],{"type":52,"value":1186},{"type":46,"tag":545,"props":1451,"children":1452},{"style":557},[1453],{"type":52,"value":847},{"type":46,"tag":545,"props":1455,"children":1456},{"style":634},[1457],{"type":52,"value":1458},"abort",{"type":46,"tag":545,"props":1460,"children":1461},{"style":675},[1462],{"type":52,"value":1463},"())",{"type":46,"tag":545,"props":1465,"children":1466},{"style":557},[1467],{"type":52,"value":1468},";",{"type":46,"tag":545,"props":1470,"children":1472},{"style":1471},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[1473],{"type":52,"value":1474}," \u002F\u002F removes the listener\n",{"type":46,"tag":545,"props":1476,"children":1477},{"class":547,"line":871},[1478],{"type":46,"tag":545,"props":1479,"children":1480},{"style":557},[1481],{"type":52,"value":1060},{"type":46,"tag":498,"props":1483,"children":1485},{"id":1484},"closures-that-dont-capture-more-than-they-need",[1486],{"type":52,"value":1487},"Closures that don't capture more than they need",{"type":46,"tag":534,"props":1489,"children":1491},{"className":536,"code":1490,"language":538,"meta":539,"style":539},"\u002F\u002F BAD: closure captures largeDataset (500MB) even though it only uses summary\nasync function processReport(reportId: string) {\n  const largeDataset = await fetchDataset(reportId);\n  const summary = summarize(largeDataset);\n  scheduler.onComplete(reportId, () => notifyUser(`Report ${reportId}: ${summary}`));\n  \u002F\u002F largeDataset is pinned by the closure's scope -- can't be GC'd\n}\n\n\u002F\u002F GOOD: extract needed values before creating the closure\nasync function processReport(reportId: string) {\n  const largeDataset = await fetchDataset(reportId);\n  const message = `Report ${reportId}: ${summarize(largeDataset)}`;\n  scheduler.onComplete(reportId, () => notifyUser(message));\n  \u002F\u002F largeDataset is now eligible for GC\n}\n",[1492],{"type":46,"tag":79,"props":1493,"children":1494},{"__ignoreMap":539},[1495,1503,1545,1586,1624,1721,1729,1736,1743,1751,1790,1829,1893,1950,1959],{"type":46,"tag":545,"props":1496,"children":1497},{"class":547,"line":33},[1498],{"type":46,"tag":545,"props":1499,"children":1500},{"style":1471},[1501],{"type":52,"value":1502},"\u002F\u002F BAD: closure captures largeDataset (500MB) even though it only uses summary\n",{"type":46,"tag":545,"props":1504,"children":1505},{"class":547,"line":600},[1506,1511,1515,1520,1524,1529,1533,1537,1541],{"type":46,"tag":545,"props":1507,"children":1508},{"style":613},[1509],{"type":52,"value":1510},"async",{"type":46,"tag":545,"props":1512,"children":1513},{"style":613},[1514],{"type":52,"value":766},{"type":46,"tag":545,"props":1516,"children":1517},{"style":634},[1518],{"type":52,"value":1519}," processReport",{"type":46,"tag":545,"props":1521,"children":1522},{"style":557},[1523],{"type":52,"value":667},{"type":46,"tag":545,"props":1525,"children":1526},{"style":778},[1527],{"type":52,"value":1528},"reportId",{"type":46,"tag":545,"props":1530,"children":1531},{"style":557},[1532],{"type":52,"value":683},{"type":46,"tag":545,"props":1534,"children":1535},{"style":644},[1536],{"type":52,"value":790},{"type":46,"tag":545,"props":1538,"children":1539},{"style":557},[1540],{"type":52,"value":735},{"type":46,"tag":545,"props":1542,"children":1543},{"style":557},[1544],{"type":52,"value":818},{"type":46,"tag":545,"props":1546,"children":1547},{"class":547,"line":29},[1548,1552,1557,1561,1565,1570,1574,1578,1582],{"type":46,"tag":545,"props":1549,"children":1550},{"style":613},[1551],{"type":52,"value":827},{"type":46,"tag":545,"props":1553,"children":1554},{"style":563},[1555],{"type":52,"value":1556}," largeDataset",{"type":46,"tag":545,"props":1558,"children":1559},{"style":557},[1560],{"type":52,"value":837},{"type":46,"tag":545,"props":1562,"children":1563},{"style":551},[1564],{"type":52,"value":927},{"type":46,"tag":545,"props":1566,"children":1567},{"style":634},[1568],{"type":52,"value":1569}," fetchDataset",{"type":46,"tag":545,"props":1571,"children":1572},{"style":675},[1573],{"type":52,"value":667},{"type":46,"tag":545,"props":1575,"children":1576},{"style":563},[1577],{"type":52,"value":1528},{"type":46,"tag":545,"props":1579,"children":1580},{"style":675},[1581],{"type":52,"value":735},{"type":46,"tag":545,"props":1583,"children":1584},{"style":557},[1585],{"type":52,"value":597},{"type":46,"tag":545,"props":1587,"children":1588},{"class":547,"line":742},[1589,1593,1598,1602,1607,1611,1616,1620],{"type":46,"tag":545,"props":1590,"children":1591},{"style":613},[1592],{"type":52,"value":827},{"type":46,"tag":545,"props":1594,"children":1595},{"style":563},[1596],{"type":52,"value":1597}," summary",{"type":46,"tag":545,"props":1599,"children":1600},{"style":557},[1601],{"type":52,"value":837},{"type":46,"tag":545,"props":1603,"children":1604},{"style":634},[1605],{"type":52,"value":1606}," summarize",{"type":46,"tag":545,"props":1608,"children":1609},{"style":675},[1610],{"type":52,"value":667},{"type":46,"tag":545,"props":1612,"children":1613},{"style":563},[1614],{"type":52,"value":1615},"largeDataset",{"type":46,"tag":545,"props":1617,"children":1618},{"style":675},[1619],{"type":52,"value":735},{"type":46,"tag":545,"props":1621,"children":1622},{"style":557},[1623],{"type":52,"value":597},{"type":46,"tag":545,"props":1625,"children":1626},{"class":547,"line":750},[1627,1632,1636,1641,1645,1649,1653,1657,1661,1666,1670,1675,1680,1685,1689,1694,1699,1703,1708,1713,1717],{"type":46,"tag":545,"props":1628,"children":1629},{"style":563},[1630],{"type":52,"value":1631},"  scheduler",{"type":46,"tag":545,"props":1633,"children":1634},{"style":557},[1635],{"type":52,"value":847},{"type":46,"tag":545,"props":1637,"children":1638},{"style":634},[1639],{"type":52,"value":1640},"onComplete",{"type":46,"tag":545,"props":1642,"children":1643},{"style":675},[1644],{"type":52,"value":667},{"type":46,"tag":545,"props":1646,"children":1647},{"style":563},[1648],{"type":52,"value":1528},{"type":46,"tag":545,"props":1650,"children":1651},{"style":557},[1652],{"type":52,"value":652},{"type":46,"tag":545,"props":1654,"children":1655},{"style":557},[1656],{"type":52,"value":1441},{"type":46,"tag":545,"props":1658,"children":1659},{"style":613},[1660],{"type":52,"value":1264},{"type":46,"tag":545,"props":1662,"children":1663},{"style":634},[1664],{"type":52,"value":1665}," notifyUser",{"type":46,"tag":545,"props":1667,"children":1668},{"style":675},[1669],{"type":52,"value":667},{"type":46,"tag":545,"props":1671,"children":1672},{"style":557},[1673],{"type":52,"value":1674},"`",{"type":46,"tag":545,"props":1676,"children":1677},{"style":584},[1678],{"type":52,"value":1679},"Report ",{"type":46,"tag":545,"props":1681,"children":1682},{"style":557},[1683],{"type":52,"value":1684},"${",{"type":46,"tag":545,"props":1686,"children":1687},{"style":563},[1688],{"type":52,"value":1528},{"type":46,"tag":545,"props":1690,"children":1691},{"style":557},[1692],{"type":52,"value":1693},"}",{"type":46,"tag":545,"props":1695,"children":1696},{"style":584},[1697],{"type":52,"value":1698},": ",{"type":46,"tag":545,"props":1700,"children":1701},{"style":557},[1702],{"type":52,"value":1684},{"type":46,"tag":545,"props":1704,"children":1705},{"style":563},[1706],{"type":52,"value":1707},"summary",{"type":46,"tag":545,"props":1709,"children":1710},{"style":557},[1711],{"type":52,"value":1712},"}`",{"type":46,"tag":545,"props":1714,"children":1715},{"style":675},[1716],{"type":52,"value":1350},{"type":46,"tag":545,"props":1718,"children":1719},{"style":557},[1720],{"type":52,"value":597},{"type":46,"tag":545,"props":1722,"children":1723},{"class":547,"line":821},[1724],{"type":46,"tag":545,"props":1725,"children":1726},{"style":1471},[1727],{"type":52,"value":1728},"  \u002F\u002F largeDataset is pinned by the closure's scope -- can't be GC'd\n",{"type":46,"tag":545,"props":1730,"children":1731},{"class":547,"line":871},[1732],{"type":46,"tag":545,"props":1733,"children":1734},{"style":557},[1735],{"type":52,"value":1060},{"type":46,"tag":545,"props":1737,"children":1738},{"class":547,"line":908},[1739],{"type":46,"tag":545,"props":1740,"children":1741},{"emptyLinePlaceholder":604},[1742],{"type":52,"value":607},{"type":46,"tag":545,"props":1744,"children":1745},{"class":547,"line":995},[1746],{"type":46,"tag":545,"props":1747,"children":1748},{"style":1471},[1749],{"type":52,"value":1750},"\u002F\u002F GOOD: extract needed values before creating the closure\n",{"type":46,"tag":545,"props":1752,"children":1753},{"class":547,"line":1037},[1754,1758,1762,1766,1770,1774,1778,1782,1786],{"type":46,"tag":545,"props":1755,"children":1756},{"style":613},[1757],{"type":52,"value":1510},{"type":46,"tag":545,"props":1759,"children":1760},{"style":613},[1761],{"type":52,"value":766},{"type":46,"tag":545,"props":1763,"children":1764},{"style":634},[1765],{"type":52,"value":1519},{"type":46,"tag":545,"props":1767,"children":1768},{"style":557},[1769],{"type":52,"value":667},{"type":46,"tag":545,"props":1771,"children":1772},{"style":778},[1773],{"type":52,"value":1528},{"type":46,"tag":545,"props":1775,"children":1776},{"style":557},[1777],{"type":52,"value":683},{"type":46,"tag":545,"props":1779,"children":1780},{"style":644},[1781],{"type":52,"value":790},{"type":46,"tag":545,"props":1783,"children":1784},{"style":557},[1785],{"type":52,"value":735},{"type":46,"tag":545,"props":1787,"children":1788},{"style":557},[1789],{"type":52,"value":818},{"type":46,"tag":545,"props":1791,"children":1792},{"class":547,"line":1054},[1793,1797,1801,1805,1809,1813,1817,1821,1825],{"type":46,"tag":545,"props":1794,"children":1795},{"style":613},[1796],{"type":52,"value":827},{"type":46,"tag":545,"props":1798,"children":1799},{"style":563},[1800],{"type":52,"value":1556},{"type":46,"tag":545,"props":1802,"children":1803},{"style":557},[1804],{"type":52,"value":837},{"type":46,"tag":545,"props":1806,"children":1807},{"style":551},[1808],{"type":52,"value":927},{"type":46,"tag":545,"props":1810,"children":1811},{"style":634},[1812],{"type":52,"value":1569},{"type":46,"tag":545,"props":1814,"children":1815},{"style":675},[1816],{"type":52,"value":667},{"type":46,"tag":545,"props":1818,"children":1819},{"style":563},[1820],{"type":52,"value":1528},{"type":46,"tag":545,"props":1822,"children":1823},{"style":675},[1824],{"type":52,"value":735},{"type":46,"tag":545,"props":1826,"children":1827},{"style":557},[1828],{"type":52,"value":597},{"type":46,"tag":545,"props":1830,"children":1832},{"class":547,"line":1831},12,[1833,1837,1842,1846,1851,1855,1859,1863,1867,1871,1875,1880,1885,1889],{"type":46,"tag":545,"props":1834,"children":1835},{"style":613},[1836],{"type":52,"value":827},{"type":46,"tag":545,"props":1838,"children":1839},{"style":563},[1840],{"type":52,"value":1841}," message",{"type":46,"tag":545,"props":1843,"children":1844},{"style":557},[1845],{"type":52,"value":837},{"type":46,"tag":545,"props":1847,"children":1848},{"style":557},[1849],{"type":52,"value":1850}," `",{"type":46,"tag":545,"props":1852,"children":1853},{"style":584},[1854],{"type":52,"value":1679},{"type":46,"tag":545,"props":1856,"children":1857},{"style":557},[1858],{"type":52,"value":1684},{"type":46,"tag":545,"props":1860,"children":1861},{"style":563},[1862],{"type":52,"value":1528},{"type":46,"tag":545,"props":1864,"children":1865},{"style":557},[1866],{"type":52,"value":1693},{"type":46,"tag":545,"props":1868,"children":1869},{"style":584},[1870],{"type":52,"value":1698},{"type":46,"tag":545,"props":1872,"children":1873},{"style":557},[1874],{"type":52,"value":1684},{"type":46,"tag":545,"props":1876,"children":1877},{"style":634},[1878],{"type":52,"value":1879},"summarize",{"type":46,"tag":545,"props":1881,"children":1882},{"style":563},[1883],{"type":52,"value":1884},"(largeDataset)",{"type":46,"tag":545,"props":1886,"children":1887},{"style":557},[1888],{"type":52,"value":1712},{"type":46,"tag":545,"props":1890,"children":1891},{"style":557},[1892],{"type":52,"value":597},{"type":46,"tag":545,"props":1894,"children":1896},{"class":547,"line":1895},13,[1897,1901,1905,1909,1913,1917,1921,1925,1929,1933,1937,1942,1946],{"type":46,"tag":545,"props":1898,"children":1899},{"style":563},[1900],{"type":52,"value":1631},{"type":46,"tag":545,"props":1902,"children":1903},{"style":557},[1904],{"type":52,"value":847},{"type":46,"tag":545,"props":1906,"children":1907},{"style":634},[1908],{"type":52,"value":1640},{"type":46,"tag":545,"props":1910,"children":1911},{"style":675},[1912],{"type":52,"value":667},{"type":46,"tag":545,"props":1914,"children":1915},{"style":563},[1916],{"type":52,"value":1528},{"type":46,"tag":545,"props":1918,"children":1919},{"style":557},[1920],{"type":52,"value":652},{"type":46,"tag":545,"props":1922,"children":1923},{"style":557},[1924],{"type":52,"value":1441},{"type":46,"tag":545,"props":1926,"children":1927},{"style":613},[1928],{"type":52,"value":1264},{"type":46,"tag":545,"props":1930,"children":1931},{"style":634},[1932],{"type":52,"value":1665},{"type":46,"tag":545,"props":1934,"children":1935},{"style":675},[1936],{"type":52,"value":667},{"type":46,"tag":545,"props":1938,"children":1939},{"style":563},[1940],{"type":52,"value":1941},"message",{"type":46,"tag":545,"props":1943,"children":1944},{"style":675},[1945],{"type":52,"value":1350},{"type":46,"tag":545,"props":1947,"children":1948},{"style":557},[1949],{"type":52,"value":597},{"type":46,"tag":545,"props":1951,"children":1953},{"class":547,"line":1952},14,[1954],{"type":46,"tag":545,"props":1955,"children":1956},{"style":1471},[1957],{"type":52,"value":1958},"  \u002F\u002F largeDataset is now eligible for GC\n",{"type":46,"tag":545,"props":1960,"children":1962},{"class":547,"line":1961},15,[1963],{"type":46,"tag":545,"props":1964,"children":1965},{"style":557},[1966],{"type":52,"value":1060},{"type":46,"tag":498,"props":1968,"children":1970},{"id":1969},"weakmap-for-metadata-on-transient-objects",[1971],{"type":52,"value":1972},"WeakMap for metadata on transient objects",{"type":46,"tag":55,"props":1974,"children":1975},{},[1976,1978,1984,1986,1991],{"type":52,"value":1977},"Use ",{"type":46,"tag":79,"props":1979,"children":1981},{"className":1980},[],[1982],{"type":52,"value":1983},"WeakMap",{"type":52,"value":1985}," to attach metadata to objects whose lifecycle you don't control. Unlike ",{"type":46,"tag":79,"props":1987,"children":1989},{"className":1988},[],[1990],{"type":52,"value":514},{"type":52,"value":1992},", it doesn't prevent GC of its keys, so entries vanish automatically with no manual cleanup.",{"type":46,"tag":534,"props":1994,"children":1996},{"className":536,"code":1995,"language":538,"meta":539,"style":539},"const requestMetadata = new WeakMap\u003CRequest, { startTime: number; traceId: string }>();\n\nexport function trackRequest(req: Request) {\n  requestMetadata.set(req, { startTime: Date.now(), traceId: crypto.randomUUID() });\n}\n\u002F\u002F Entry removed automatically when the Request is GC'd after the response.\n",[1997],{"type":46,"tag":79,"props":1998,"children":1999},{"__ignoreMap":539},[2000,2086,2093,2135,2236,2243],{"type":46,"tag":545,"props":2001,"children":2002},{"class":547,"line":33},[2003,2007,2012,2016,2020,2025,2029,2034,2038,2042,2047,2051,2056,2060,2065,2069,2073,2078,2082],{"type":46,"tag":545,"props":2004,"children":2005},{"style":613},[2006],{"type":52,"value":616},{"type":46,"tag":545,"props":2008,"children":2009},{"style":563},[2010],{"type":52,"value":2011}," requestMetadata ",{"type":46,"tag":545,"props":2013,"children":2014},{"style":557},[2015],{"type":52,"value":626},{"type":46,"tag":545,"props":2017,"children":2018},{"style":557},[2019],{"type":52,"value":631},{"type":46,"tag":545,"props":2021,"children":2022},{"style":634},[2023],{"type":52,"value":2024}," WeakMap",{"type":46,"tag":545,"props":2026,"children":2027},{"style":557},[2028],{"type":52,"value":641},{"type":46,"tag":545,"props":2030,"children":2031},{"style":644},[2032],{"type":52,"value":2033},"Request",{"type":46,"tag":545,"props":2035,"children":2036},{"style":557},[2037],{"type":52,"value":652},{"type":46,"tag":545,"props":2039,"children":2040},{"style":557},[2041],{"type":52,"value":560},{"type":46,"tag":545,"props":2043,"children":2044},{"style":675},[2045],{"type":52,"value":2046}," startTime",{"type":46,"tag":545,"props":2048,"children":2049},{"style":557},[2050],{"type":52,"value":683},{"type":46,"tag":545,"props":2052,"children":2053},{"style":644},[2054],{"type":52,"value":2055}," number",{"type":46,"tag":545,"props":2057,"children":2058},{"style":557},[2059],{"type":52,"value":1468},{"type":46,"tag":545,"props":2061,"children":2062},{"style":675},[2063],{"type":52,"value":2064}," traceId",{"type":46,"tag":545,"props":2066,"children":2067},{"style":557},[2068],{"type":52,"value":683},{"type":46,"tag":545,"props":2070,"children":2071},{"style":644},[2072],{"type":52,"value":790},{"type":46,"tag":545,"props":2074,"children":2075},{"style":557},[2076],{"type":52,"value":2077}," }>",{"type":46,"tag":545,"props":2079,"children":2080},{"style":563},[2081],{"type":52,"value":1204},{"type":46,"tag":545,"props":2083,"children":2084},{"style":557},[2085],{"type":52,"value":597},{"type":46,"tag":545,"props":2087,"children":2088},{"class":547,"line":600},[2089],{"type":46,"tag":545,"props":2090,"children":2091},{"emptyLinePlaceholder":604},[2092],{"type":52,"value":607},{"type":46,"tag":545,"props":2094,"children":2095},{"class":547,"line":29},[2096,2100,2104,2109,2113,2118,2122,2127,2131],{"type":46,"tag":545,"props":2097,"children":2098},{"style":551},[2099],{"type":52,"value":756},{"type":46,"tag":545,"props":2101,"children":2102},{"style":613},[2103],{"type":52,"value":766},{"type":46,"tag":545,"props":2105,"children":2106},{"style":634},[2107],{"type":52,"value":2108}," trackRequest",{"type":46,"tag":545,"props":2110,"children":2111},{"style":557},[2112],{"type":52,"value":667},{"type":46,"tag":545,"props":2114,"children":2115},{"style":778},[2116],{"type":52,"value":2117},"req",{"type":46,"tag":545,"props":2119,"children":2120},{"style":557},[2121],{"type":52,"value":683},{"type":46,"tag":545,"props":2123,"children":2124},{"style":644},[2125],{"type":52,"value":2126}," Request",{"type":46,"tag":545,"props":2128,"children":2129},{"style":557},[2130],{"type":52,"value":735},{"type":46,"tag":545,"props":2132,"children":2133},{"style":557},[2134],{"type":52,"value":818},{"type":46,"tag":545,"props":2136,"children":2137},{"class":547,"line":742},[2138,2143,2147,2151,2155,2159,2163,2167,2171,2175,2180,2184,2189,2193,2197,2201,2205,2210,2214,2219,2224,2228,2232],{"type":46,"tag":545,"props":2139,"children":2140},{"style":563},[2141],{"type":52,"value":2142},"  requestMetadata",{"type":46,"tag":545,"props":2144,"children":2145},{"style":557},[2146],{"type":52,"value":847},{"type":46,"tag":545,"props":2148,"children":2149},{"style":634},[2150],{"type":52,"value":1010},{"type":46,"tag":545,"props":2152,"children":2153},{"style":675},[2154],{"type":52,"value":667},{"type":46,"tag":545,"props":2156,"children":2157},{"style":563},[2158],{"type":52,"value":2117},{"type":46,"tag":545,"props":2160,"children":2161},{"style":557},[2162],{"type":52,"value":652},{"type":46,"tag":545,"props":2164,"children":2165},{"style":557},[2166],{"type":52,"value":560},{"type":46,"tag":545,"props":2168,"children":2169},{"style":675},[2170],{"type":52,"value":2046},{"type":46,"tag":545,"props":2172,"children":2173},{"style":557},[2174],{"type":52,"value":683},{"type":46,"tag":545,"props":2176,"children":2177},{"style":563},[2178],{"type":52,"value":2179}," Date",{"type":46,"tag":545,"props":2181,"children":2182},{"style":557},[2183],{"type":52,"value":847},{"type":46,"tag":545,"props":2185,"children":2186},{"style":634},[2187],{"type":52,"value":2188},"now",{"type":46,"tag":545,"props":2190,"children":2191},{"style":675},[2192],{"type":52,"value":1204},{"type":46,"tag":545,"props":2194,"children":2195},{"style":557},[2196],{"type":52,"value":652},{"type":46,"tag":545,"props":2198,"children":2199},{"style":675},[2200],{"type":52,"value":2064},{"type":46,"tag":545,"props":2202,"children":2203},{"style":557},[2204],{"type":52,"value":683},{"type":46,"tag":545,"props":2206,"children":2207},{"style":563},[2208],{"type":52,"value":2209}," crypto",{"type":46,"tag":545,"props":2211,"children":2212},{"style":557},[2213],{"type":52,"value":847},{"type":46,"tag":545,"props":2215,"children":2216},{"style":634},[2217],{"type":52,"value":2218},"randomUUID",{"type":46,"tag":545,"props":2220,"children":2221},{"style":675},[2222],{"type":52,"value":2223},"() ",{"type":46,"tag":545,"props":2225,"children":2226},{"style":557},[2227],{"type":52,"value":1693},{"type":46,"tag":545,"props":2229,"children":2230},{"style":675},[2231],{"type":52,"value":735},{"type":46,"tag":545,"props":2233,"children":2234},{"style":557},[2235],{"type":52,"value":597},{"type":46,"tag":545,"props":2237,"children":2238},{"class":547,"line":750},[2239],{"type":46,"tag":545,"props":2240,"children":2241},{"style":557},[2242],{"type":52,"value":1060},{"type":46,"tag":545,"props":2244,"children":2245},{"class":547,"line":821},[2246],{"type":46,"tag":545,"props":2247,"children":2248},{"style":1471},[2249],{"type":52,"value":2250},"\u002F\u002F Entry removed automatically when the Request is GC'd after the response.\n",{"type":46,"tag":498,"props":2252,"children":2254},{"id":2253},"timer-cleanup",[2255],{"type":52,"value":2256},"Timer cleanup",{"type":46,"tag":534,"props":2258,"children":2260},{"className":536,"code":2259,"language":538,"meta":539,"style":539},"export function startHeartbeat(connection: Connection) {\n  const timer = setInterval(() => connection.ping(), 30_000);\n  connection.on(\"close\", () => clearInterval(timer));\n  process.on(\"SIGTERM\", () => clearInterval(timer)); \u002F\u002F also clear on shutdown\n}\n",[2261],{"type":46,"tag":79,"props":2262,"children":2263},{"__ignoreMap":539},[2264,2306,2374,2440,2510],{"type":46,"tag":545,"props":2265,"children":2266},{"class":547,"line":33},[2267,2271,2275,2280,2284,2289,2293,2298,2302],{"type":46,"tag":545,"props":2268,"children":2269},{"style":551},[2270],{"type":52,"value":756},{"type":46,"tag":545,"props":2272,"children":2273},{"style":613},[2274],{"type":52,"value":766},{"type":46,"tag":545,"props":2276,"children":2277},{"style":634},[2278],{"type":52,"value":2279}," startHeartbeat",{"type":46,"tag":545,"props":2281,"children":2282},{"style":557},[2283],{"type":52,"value":667},{"type":46,"tag":545,"props":2285,"children":2286},{"style":778},[2287],{"type":52,"value":2288},"connection",{"type":46,"tag":545,"props":2290,"children":2291},{"style":557},[2292],{"type":52,"value":683},{"type":46,"tag":545,"props":2294,"children":2295},{"style":644},[2296],{"type":52,"value":2297}," Connection",{"type":46,"tag":545,"props":2299,"children":2300},{"style":557},[2301],{"type":52,"value":735},{"type":46,"tag":545,"props":2303,"children":2304},{"style":557},[2305],{"type":52,"value":818},{"type":46,"tag":545,"props":2307,"children":2308},{"class":547,"line":600},[2309,2313,2318,2322,2327,2331,2335,2339,2344,2348,2353,2357,2361,2366,2370],{"type":46,"tag":545,"props":2310,"children":2311},{"style":613},[2312],{"type":52,"value":827},{"type":46,"tag":545,"props":2314,"children":2315},{"style":563},[2316],{"type":52,"value":2317}," timer",{"type":46,"tag":545,"props":2319,"children":2320},{"style":557},[2321],{"type":52,"value":837},{"type":46,"tag":545,"props":2323,"children":2324},{"style":634},[2325],{"type":52,"value":2326}," setInterval",{"type":46,"tag":545,"props":2328,"children":2329},{"style":675},[2330],{"type":52,"value":667},{"type":46,"tag":545,"props":2332,"children":2333},{"style":557},[2334],{"type":52,"value":1204},{"type":46,"tag":545,"props":2336,"children":2337},{"style":613},[2338],{"type":52,"value":1264},{"type":46,"tag":545,"props":2340,"children":2341},{"style":563},[2342],{"type":52,"value":2343}," connection",{"type":46,"tag":545,"props":2345,"children":2346},{"style":557},[2347],{"type":52,"value":847},{"type":46,"tag":545,"props":2349,"children":2350},{"style":634},[2351],{"type":52,"value":2352},"ping",{"type":46,"tag":545,"props":2354,"children":2355},{"style":675},[2356],{"type":52,"value":1204},{"type":46,"tag":545,"props":2358,"children":2359},{"style":557},[2360],{"type":52,"value":652},{"type":46,"tag":545,"props":2362,"children":2363},{"style":686},[2364],{"type":52,"value":2365}," 30_000",{"type":46,"tag":545,"props":2367,"children":2368},{"style":675},[2369],{"type":52,"value":735},{"type":46,"tag":545,"props":2371,"children":2372},{"style":557},[2373],{"type":52,"value":597},{"type":46,"tag":545,"props":2375,"children":2376},{"class":547,"line":29},[2377,2382,2386,2390,2394,2398,2402,2406,2410,2414,2418,2423,2427,2432,2436],{"type":46,"tag":545,"props":2378,"children":2379},{"style":563},[2380],{"type":52,"value":2381},"  connection",{"type":46,"tag":545,"props":2383,"children":2384},{"style":557},[2385],{"type":52,"value":847},{"type":46,"tag":545,"props":2387,"children":2388},{"style":634},[2389],{"type":52,"value":1225},{"type":46,"tag":545,"props":2391,"children":2392},{"style":675},[2393],{"type":52,"value":667},{"type":46,"tag":545,"props":2395,"children":2396},{"style":557},[2397],{"type":52,"value":592},{"type":46,"tag":545,"props":2399,"children":2400},{"style":584},[2401],{"type":52,"value":1428},{"type":46,"tag":545,"props":2403,"children":2404},{"style":557},[2405],{"type":52,"value":592},{"type":46,"tag":545,"props":2407,"children":2408},{"style":557},[2409],{"type":52,"value":652},{"type":46,"tag":545,"props":2411,"children":2412},{"style":557},[2413],{"type":52,"value":1441},{"type":46,"tag":545,"props":2415,"children":2416},{"style":613},[2417],{"type":52,"value":1264},{"type":46,"tag":545,"props":2419,"children":2420},{"style":634},[2421],{"type":52,"value":2422}," clearInterval",{"type":46,"tag":545,"props":2424,"children":2425},{"style":675},[2426],{"type":52,"value":667},{"type":46,"tag":545,"props":2428,"children":2429},{"style":563},[2430],{"type":52,"value":2431},"timer",{"type":46,"tag":545,"props":2433,"children":2434},{"style":675},[2435],{"type":52,"value":1350},{"type":46,"tag":545,"props":2437,"children":2438},{"style":557},[2439],{"type":52,"value":597},{"type":46,"tag":545,"props":2441,"children":2442},{"class":547,"line":742},[2443,2448,2452,2456,2460,2464,2469,2473,2477,2481,2485,2489,2493,2497,2501,2505],{"type":46,"tag":545,"props":2444,"children":2445},{"style":563},[2446],{"type":52,"value":2447},"  process",{"type":46,"tag":545,"props":2449,"children":2450},{"style":557},[2451],{"type":52,"value":847},{"type":46,"tag":545,"props":2453,"children":2454},{"style":634},[2455],{"type":52,"value":1225},{"type":46,"tag":545,"props":2457,"children":2458},{"style":675},[2459],{"type":52,"value":667},{"type":46,"tag":545,"props":2461,"children":2462},{"style":557},[2463],{"type":52,"value":592},{"type":46,"tag":545,"props":2465,"children":2466},{"style":584},[2467],{"type":52,"value":2468},"SIGTERM",{"type":46,"tag":545,"props":2470,"children":2471},{"style":557},[2472],{"type":52,"value":592},{"type":46,"tag":545,"props":2474,"children":2475},{"style":557},[2476],{"type":52,"value":652},{"type":46,"tag":545,"props":2478,"children":2479},{"style":557},[2480],{"type":52,"value":1441},{"type":46,"tag":545,"props":2482,"children":2483},{"style":613},[2484],{"type":52,"value":1264},{"type":46,"tag":545,"props":2486,"children":2487},{"style":634},[2488],{"type":52,"value":2422},{"type":46,"tag":545,"props":2490,"children":2491},{"style":675},[2492],{"type":52,"value":667},{"type":46,"tag":545,"props":2494,"children":2495},{"style":563},[2496],{"type":52,"value":2431},{"type":46,"tag":545,"props":2498,"children":2499},{"style":675},[2500],{"type":52,"value":1350},{"type":46,"tag":545,"props":2502,"children":2503},{"style":557},[2504],{"type":52,"value":1468},{"type":46,"tag":545,"props":2506,"children":2507},{"style":1471},[2508],{"type":52,"value":2509}," \u002F\u002F also clear on shutdown\n",{"type":46,"tag":545,"props":2511,"children":2512},{"class":547,"line":750},[2513],{"type":46,"tag":545,"props":2514,"children":2515},{"style":557},[2516],{"type":52,"value":1060},{"type":46,"tag":498,"props":2518,"children":2520},{"id":2519},"go-goroutine-lifecycle-with-context",[2521],{"type":52,"value":2522},"Go: goroutine lifecycle with context",{"type":46,"tag":55,"props":2524,"children":2525},{},[2526],{"type":52,"value":2527},"Every goroutine needs an exit path -- channel closed, context cancelled, or both. Without one, it's a leak.",{"type":46,"tag":534,"props":2529,"children":2532},{"className":2530,"code":2531,"language":28,"meta":539,"style":539},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","func watchForUpdates(ctx context.Context, ch \u003C-chan Update, handler func(Update)) {\n    go func() {\n        for {\n            select {\n            case update, ok := \u003C-ch:\n                if !ok { return } \u002F\u002F channel closed\n                handler(update)\n            case \u003C-ctx.Done():\n                return \u002F\u002F context cancelled\n            }\n        }\n    }()\n}\n",[2533],{"type":46,"tag":79,"props":2534,"children":2535},{"__ignoreMap":539},[2536,2544,2552,2560,2568,2576,2584,2592,2600,2608,2616,2624,2632],{"type":46,"tag":545,"props":2537,"children":2538},{"class":547,"line":33},[2539],{"type":46,"tag":545,"props":2540,"children":2541},{},[2542],{"type":52,"value":2543},"func watchForUpdates(ctx context.Context, ch \u003C-chan Update, handler func(Update)) {\n",{"type":46,"tag":545,"props":2545,"children":2546},{"class":547,"line":600},[2547],{"type":46,"tag":545,"props":2548,"children":2549},{},[2550],{"type":52,"value":2551},"    go func() {\n",{"type":46,"tag":545,"props":2553,"children":2554},{"class":547,"line":29},[2555],{"type":46,"tag":545,"props":2556,"children":2557},{},[2558],{"type":52,"value":2559},"        for {\n",{"type":46,"tag":545,"props":2561,"children":2562},{"class":547,"line":742},[2563],{"type":46,"tag":545,"props":2564,"children":2565},{},[2566],{"type":52,"value":2567},"            select {\n",{"type":46,"tag":545,"props":2569,"children":2570},{"class":547,"line":750},[2571],{"type":46,"tag":545,"props":2572,"children":2573},{},[2574],{"type":52,"value":2575},"            case update, ok := \u003C-ch:\n",{"type":46,"tag":545,"props":2577,"children":2578},{"class":547,"line":821},[2579],{"type":46,"tag":545,"props":2580,"children":2581},{},[2582],{"type":52,"value":2583},"                if !ok { return } \u002F\u002F channel closed\n",{"type":46,"tag":545,"props":2585,"children":2586},{"class":547,"line":871},[2587],{"type":46,"tag":545,"props":2588,"children":2589},{},[2590],{"type":52,"value":2591},"                handler(update)\n",{"type":46,"tag":545,"props":2593,"children":2594},{"class":547,"line":908},[2595],{"type":46,"tag":545,"props":2596,"children":2597},{},[2598],{"type":52,"value":2599},"            case \u003C-ctx.Done():\n",{"type":46,"tag":545,"props":2601,"children":2602},{"class":547,"line":995},[2603],{"type":46,"tag":545,"props":2604,"children":2605},{},[2606],{"type":52,"value":2607},"                return \u002F\u002F context cancelled\n",{"type":46,"tag":545,"props":2609,"children":2610},{"class":547,"line":1037},[2611],{"type":46,"tag":545,"props":2612,"children":2613},{},[2614],{"type":52,"value":2615},"            }\n",{"type":46,"tag":545,"props":2617,"children":2618},{"class":547,"line":1054},[2619],{"type":46,"tag":545,"props":2620,"children":2621},{},[2622],{"type":52,"value":2623},"        }\n",{"type":46,"tag":545,"props":2625,"children":2626},{"class":547,"line":1831},[2627],{"type":46,"tag":545,"props":2628,"children":2629},{},[2630],{"type":52,"value":2631},"    }()\n",{"type":46,"tag":545,"props":2633,"children":2634},{"class":547,"line":1895},[2635],{"type":46,"tag":545,"props":2636,"children":2637},{},[2638],{"type":52,"value":1060},{"type":46,"tag":498,"props":2640,"children":2642},{"id":2641},"go-defer-in-loops-extract-to-a-function",[2643],{"type":52,"value":2644},"Go: defer in loops -- extract to a function",{"type":46,"tag":534,"props":2646,"children":2648},{"className":2530,"code":2647,"language":28,"meta":539,"style":539},"\u002F\u002F BAD: all file handles stay open until processFiles returns\nfunc processFiles(paths []string) error {\n    for _, path := range paths {\n        f, _ := os.Open(path)\n        defer f.Close() \u002F\u002F accumulates!\n    }\n    return nil\n}\n\n\u002F\u002F GOOD: defer runs per-iteration because it lives in its own function scope\nfunc processFiles(paths []string) error {\n    for _, path := range paths {\n        if err := processFile(path); err != nil { return err }\n    }\n    return nil\n}\n\nfunc processFile(path string) error {\n    f, err := os.Open(path)\n    if err != nil { return err }\n    defer f.Close()\n    return nil\n}\n",[2649],{"type":46,"tag":79,"props":2650,"children":2651},{"__ignoreMap":539},[2652,2660,2668,2676,2684,2692,2700,2708,2715,2722,2730,2737,2744,2752,2759,2766,2774,2782,2791,2800,2809,2818,2826],{"type":46,"tag":545,"props":2653,"children":2654},{"class":547,"line":33},[2655],{"type":46,"tag":545,"props":2656,"children":2657},{},[2658],{"type":52,"value":2659},"\u002F\u002F BAD: all file handles stay open until processFiles returns\n",{"type":46,"tag":545,"props":2661,"children":2662},{"class":547,"line":600},[2663],{"type":46,"tag":545,"props":2664,"children":2665},{},[2666],{"type":52,"value":2667},"func processFiles(paths []string) error {\n",{"type":46,"tag":545,"props":2669,"children":2670},{"class":547,"line":29},[2671],{"type":46,"tag":545,"props":2672,"children":2673},{},[2674],{"type":52,"value":2675},"    for _, path := range paths {\n",{"type":46,"tag":545,"props":2677,"children":2678},{"class":547,"line":742},[2679],{"type":46,"tag":545,"props":2680,"children":2681},{},[2682],{"type":52,"value":2683},"        f, _ := os.Open(path)\n",{"type":46,"tag":545,"props":2685,"children":2686},{"class":547,"line":750},[2687],{"type":46,"tag":545,"props":2688,"children":2689},{},[2690],{"type":52,"value":2691},"        defer f.Close() \u002F\u002F accumulates!\n",{"type":46,"tag":545,"props":2693,"children":2694},{"class":547,"line":821},[2695],{"type":46,"tag":545,"props":2696,"children":2697},{},[2698],{"type":52,"value":2699},"    }\n",{"type":46,"tag":545,"props":2701,"children":2702},{"class":547,"line":871},[2703],{"type":46,"tag":545,"props":2704,"children":2705},{},[2706],{"type":52,"value":2707},"    return nil\n",{"type":46,"tag":545,"props":2709,"children":2710},{"class":547,"line":908},[2711],{"type":46,"tag":545,"props":2712,"children":2713},{},[2714],{"type":52,"value":1060},{"type":46,"tag":545,"props":2716,"children":2717},{"class":547,"line":995},[2718],{"type":46,"tag":545,"props":2719,"children":2720},{"emptyLinePlaceholder":604},[2721],{"type":52,"value":607},{"type":46,"tag":545,"props":2723,"children":2724},{"class":547,"line":1037},[2725],{"type":46,"tag":545,"props":2726,"children":2727},{},[2728],{"type":52,"value":2729},"\u002F\u002F GOOD: defer runs per-iteration because it lives in its own function scope\n",{"type":46,"tag":545,"props":2731,"children":2732},{"class":547,"line":1054},[2733],{"type":46,"tag":545,"props":2734,"children":2735},{},[2736],{"type":52,"value":2667},{"type":46,"tag":545,"props":2738,"children":2739},{"class":547,"line":1831},[2740],{"type":46,"tag":545,"props":2741,"children":2742},{},[2743],{"type":52,"value":2675},{"type":46,"tag":545,"props":2745,"children":2746},{"class":547,"line":1895},[2747],{"type":46,"tag":545,"props":2748,"children":2749},{},[2750],{"type":52,"value":2751},"        if err := processFile(path); err != nil { return err }\n",{"type":46,"tag":545,"props":2753,"children":2754},{"class":547,"line":1952},[2755],{"type":46,"tag":545,"props":2756,"children":2757},{},[2758],{"type":52,"value":2699},{"type":46,"tag":545,"props":2760,"children":2761},{"class":547,"line":1961},[2762],{"type":46,"tag":545,"props":2763,"children":2764},{},[2765],{"type":52,"value":2707},{"type":46,"tag":545,"props":2767,"children":2769},{"class":547,"line":2768},16,[2770],{"type":46,"tag":545,"props":2771,"children":2772},{},[2773],{"type":52,"value":1060},{"type":46,"tag":545,"props":2775,"children":2777},{"class":547,"line":2776},17,[2778],{"type":46,"tag":545,"props":2779,"children":2780},{"emptyLinePlaceholder":604},[2781],{"type":52,"value":607},{"type":46,"tag":545,"props":2783,"children":2785},{"class":547,"line":2784},18,[2786],{"type":46,"tag":545,"props":2787,"children":2788},{},[2789],{"type":52,"value":2790},"func processFile(path string) error {\n",{"type":46,"tag":545,"props":2792,"children":2794},{"class":547,"line":2793},19,[2795],{"type":46,"tag":545,"props":2796,"children":2797},{},[2798],{"type":52,"value":2799},"    f, err := os.Open(path)\n",{"type":46,"tag":545,"props":2801,"children":2803},{"class":547,"line":2802},20,[2804],{"type":46,"tag":545,"props":2805,"children":2806},{},[2807],{"type":52,"value":2808},"    if err != nil { return err }\n",{"type":46,"tag":545,"props":2810,"children":2812},{"class":547,"line":2811},21,[2813],{"type":46,"tag":545,"props":2814,"children":2815},{},[2816],{"type":52,"value":2817},"    defer f.Close()\n",{"type":46,"tag":545,"props":2819,"children":2821},{"class":547,"line":2820},22,[2822],{"type":46,"tag":545,"props":2823,"children":2824},{},[2825],{"type":52,"value":2707},{"type":46,"tag":545,"props":2827,"children":2829},{"class":547,"line":2828},23,[2830],{"type":46,"tag":545,"props":2831,"children":2832},{},[2833],{"type":52,"value":1060},{"type":46,"tag":67,"props":2835,"children":2837},{"id":2836},"the-container-restart-mask",[2838],{"type":52,"value":2839},"The Container Restart Mask",{"type":46,"tag":55,"props":2841,"children":2842},{},[2843],{"type":52,"value":2844},"Containers mask leaks. A 20MB\u002Fhour leak in a 512MB pod OOM-restarts every ~24 hours -- teams see one restart a day and call it \"container flakiness.\" It persists for months until a traffic increase makes it OOM every 6 hours and someone investigates.",{"type":46,"tag":55,"props":2846,"children":2847},{},[2848,2853],{"type":46,"tag":61,"props":2849,"children":2850},{},[2851],{"type":52,"value":2852},"Periodic restarts at a regular interval = suspect a memory leak.",{"type":52,"value":2854}," Plot memory over time -- a linear upward trend is the signature.",{"type":46,"tag":67,"props":2856,"children":2858},{"id":2857},"anti-patterns",[2859],{"type":52,"value":2860},"Anti-Patterns",{"type":46,"tag":534,"props":2862,"children":2864},{"className":536,"code":2863,"language":538,"meta":539,"style":539},"\u002F\u002F Unbounded Map: grows until OOM\nconst cache = new Map\u003Cstring, any>();\nfunction getItem(key) { if (!cache.has(key)) cache.set(key, fetchItem(key)); }\n\n\u002F\u002F Listener leak: new listener per connection, never removed\neventBus.on(\"event\", (data) => ws.send(data)); \u002F\u002F in a per-connection handler\n\n\u002F\u002F Timer leak: no clearInterval anywhere\nsetInterval(() => refreshData(), 60_000);\n\n\u002F\u002F Closure capture: pins 500MB dataset via scope\nconst data = await fetchLargeDataset();\nconst summary = summarize(data);\nscheduler.later(() => log(`Done: ${summary}`)); \u002F\u002F data is pinned\n",[2865],{"type":46,"tag":79,"props":2866,"children":2867},{"__ignoreMap":539},[2868,2876,2930,3050,3057,3065,3145,3152,3160,3205,3212,3220,3253,3282],{"type":46,"tag":545,"props":2869,"children":2870},{"class":547,"line":33},[2871],{"type":46,"tag":545,"props":2872,"children":2873},{"style":1471},[2874],{"type":52,"value":2875},"\u002F\u002F Unbounded Map: grows until OOM\n",{"type":46,"tag":545,"props":2877,"children":2878},{"class":547,"line":600},[2879,2883,2888,2892,2896,2901,2905,2909,2913,2918,2922,2926],{"type":46,"tag":545,"props":2880,"children":2881},{"style":613},[2882],{"type":52,"value":616},{"type":46,"tag":545,"props":2884,"children":2885},{"style":563},[2886],{"type":52,"value":2887}," cache ",{"type":46,"tag":545,"props":2889,"children":2890},{"style":557},[2891],{"type":52,"value":626},{"type":46,"tag":545,"props":2893,"children":2894},{"style":557},[2895],{"type":52,"value":631},{"type":46,"tag":545,"props":2897,"children":2898},{"style":634},[2899],{"type":52,"value":2900}," Map",{"type":46,"tag":545,"props":2902,"children":2903},{"style":557},[2904],{"type":52,"value":641},{"type":46,"tag":545,"props":2906,"children":2907},{"style":644},[2908],{"type":52,"value":647},{"type":46,"tag":545,"props":2910,"children":2911},{"style":557},[2912],{"type":52,"value":652},{"type":46,"tag":545,"props":2914,"children":2915},{"style":644},[2916],{"type":52,"value":2917}," any",{"type":46,"tag":545,"props":2919,"children":2920},{"style":557},[2921],{"type":52,"value":662},{"type":46,"tag":545,"props":2923,"children":2924},{"style":563},[2925],{"type":52,"value":1204},{"type":46,"tag":545,"props":2927,"children":2928},{"style":557},[2929],{"type":52,"value":597},{"type":46,"tag":545,"props":2931,"children":2932},{"class":547,"line":29},[2933,2937,2942,2946,2951,2955,2959,2964,2968,2973,2978,2982,2987,2991,2995,3000,3004,3008,3012,3016,3020,3024,3029,3033,3037,3041,3045],{"type":46,"tag":545,"props":2934,"children":2935},{"style":613},[2936],{"type":52,"value":488},{"type":46,"tag":545,"props":2938,"children":2939},{"style":634},[2940],{"type":52,"value":2941}," getItem",{"type":46,"tag":545,"props":2943,"children":2944},{"style":557},[2945],{"type":52,"value":667},{"type":46,"tag":545,"props":2947,"children":2948},{"style":778},[2949],{"type":52,"value":2950},"key",{"type":46,"tag":545,"props":2952,"children":2953},{"style":557},[2954],{"type":52,"value":735},{"type":46,"tag":545,"props":2956,"children":2957},{"style":557},[2958],{"type":52,"value":560},{"type":46,"tag":545,"props":2960,"children":2961},{"style":551},[2962],{"type":52,"value":2963}," if",{"type":46,"tag":545,"props":2965,"children":2966},{"style":675},[2967],{"type":52,"value":882},{"type":46,"tag":545,"props":2969,"children":2970},{"style":557},[2971],{"type":52,"value":2972},"!",{"type":46,"tag":545,"props":2974,"children":2975},{"style":563},[2976],{"type":52,"value":2977},"cache",{"type":46,"tag":545,"props":2979,"children":2980},{"style":557},[2981],{"type":52,"value":847},{"type":46,"tag":545,"props":2983,"children":2984},{"style":634},[2985],{"type":52,"value":2986},"has",{"type":46,"tag":545,"props":2988,"children":2989},{"style":675},[2990],{"type":52,"value":667},{"type":46,"tag":545,"props":2992,"children":2993},{"style":563},[2994],{"type":52,"value":2950},{"type":46,"tag":545,"props":2996,"children":2997},{"style":675},[2998],{"type":52,"value":2999},")) ",{"type":46,"tag":545,"props":3001,"children":3002},{"style":563},[3003],{"type":52,"value":2977},{"type":46,"tag":545,"props":3005,"children":3006},{"style":557},[3007],{"type":52,"value":847},{"type":46,"tag":545,"props":3009,"children":3010},{"style":634},[3011],{"type":52,"value":1010},{"type":46,"tag":545,"props":3013,"children":3014},{"style":675},[3015],{"type":52,"value":667},{"type":46,"tag":545,"props":3017,"children":3018},{"style":563},[3019],{"type":52,"value":2950},{"type":46,"tag":545,"props":3021,"children":3022},{"style":557},[3023],{"type":52,"value":652},{"type":46,"tag":545,"props":3025,"children":3026},{"style":634},[3027],{"type":52,"value":3028}," fetchItem",{"type":46,"tag":545,"props":3030,"children":3031},{"style":675},[3032],{"type":52,"value":667},{"type":46,"tag":545,"props":3034,"children":3035},{"style":563},[3036],{"type":52,"value":2950},{"type":46,"tag":545,"props":3038,"children":3039},{"style":675},[3040],{"type":52,"value":1350},{"type":46,"tag":545,"props":3042,"children":3043},{"style":557},[3044],{"type":52,"value":1468},{"type":46,"tag":545,"props":3046,"children":3047},{"style":557},[3048],{"type":52,"value":3049}," }\n",{"type":46,"tag":545,"props":3051,"children":3052},{"class":547,"line":742},[3053],{"type":46,"tag":545,"props":3054,"children":3055},{"emptyLinePlaceholder":604},[3056],{"type":52,"value":607},{"type":46,"tag":545,"props":3058,"children":3059},{"class":547,"line":750},[3060],{"type":46,"tag":545,"props":3061,"children":3062},{"style":1471},[3063],{"type":52,"value":3064},"\u002F\u002F Listener leak: new listener per connection, never removed\n",{"type":46,"tag":545,"props":3066,"children":3067},{"class":547,"line":821},[3068,3073,3077,3081,3085,3089,3093,3097,3101,3105,3110,3114,3118,3123,3127,3131,3136,3140],{"type":46,"tag":545,"props":3069,"children":3070},{"style":563},[3071],{"type":52,"value":3072},"eventBus",{"type":46,"tag":545,"props":3074,"children":3075},{"style":557},[3076],{"type":52,"value":847},{"type":46,"tag":545,"props":3078,"children":3079},{"style":634},[3080],{"type":52,"value":1225},{"type":46,"tag":545,"props":3082,"children":3083},{"style":563},[3084],{"type":52,"value":667},{"type":46,"tag":545,"props":3086,"children":3087},{"style":557},[3088],{"type":52,"value":592},{"type":46,"tag":545,"props":3090,"children":3091},{"style":584},[3092],{"type":52,"value":1255},{"type":46,"tag":545,"props":3094,"children":3095},{"style":557},[3096],{"type":52,"value":592},{"type":46,"tag":545,"props":3098,"children":3099},{"style":557},[3100],{"type":52,"value":652},{"type":46,"tag":545,"props":3102,"children":3103},{"style":557},[3104],{"type":52,"value":882},{"type":46,"tag":545,"props":3106,"children":3107},{"style":778},[3108],{"type":52,"value":3109},"data",{"type":46,"tag":545,"props":3111,"children":3112},{"style":557},[3113],{"type":52,"value":735},{"type":46,"tag":545,"props":3115,"children":3116},{"style":613},[3117],{"type":52,"value":1264},{"type":46,"tag":545,"props":3119,"children":3120},{"style":563},[3121],{"type":52,"value":3122}," ws",{"type":46,"tag":545,"props":3124,"children":3125},{"style":557},[3126],{"type":52,"value":847},{"type":46,"tag":545,"props":3128,"children":3129},{"style":634},[3130],{"type":52,"value":1319},{"type":46,"tag":545,"props":3132,"children":3133},{"style":563},[3134],{"type":52,"value":3135},"(data))",{"type":46,"tag":545,"props":3137,"children":3138},{"style":557},[3139],{"type":52,"value":1468},{"type":46,"tag":545,"props":3141,"children":3142},{"style":1471},[3143],{"type":52,"value":3144}," \u002F\u002F in a per-connection handler\n",{"type":46,"tag":545,"props":3146,"children":3147},{"class":547,"line":871},[3148],{"type":46,"tag":545,"props":3149,"children":3150},{"emptyLinePlaceholder":604},[3151],{"type":52,"value":607},{"type":46,"tag":545,"props":3153,"children":3154},{"class":547,"line":908},[3155],{"type":46,"tag":545,"props":3156,"children":3157},{"style":1471},[3158],{"type":52,"value":3159},"\u002F\u002F Timer leak: no clearInterval anywhere\n",{"type":46,"tag":545,"props":3161,"children":3162},{"class":547,"line":995},[3163,3167,3171,3175,3179,3184,3188,3192,3197,3201],{"type":46,"tag":545,"props":3164,"children":3165},{"style":634},[3166],{"type":52,"value":275},{"type":46,"tag":545,"props":3168,"children":3169},{"style":563},[3170],{"type":52,"value":667},{"type":46,"tag":545,"props":3172,"children":3173},{"style":557},[3174],{"type":52,"value":1204},{"type":46,"tag":545,"props":3176,"children":3177},{"style":613},[3178],{"type":52,"value":1264},{"type":46,"tag":545,"props":3180,"children":3181},{"style":634},[3182],{"type":52,"value":3183}," refreshData",{"type":46,"tag":545,"props":3185,"children":3186},{"style":563},[3187],{"type":52,"value":1204},{"type":46,"tag":545,"props":3189,"children":3190},{"style":557},[3191],{"type":52,"value":652},{"type":46,"tag":545,"props":3193,"children":3194},{"style":686},[3195],{"type":52,"value":3196}," 60_000",{"type":46,"tag":545,"props":3198,"children":3199},{"style":563},[3200],{"type":52,"value":735},{"type":46,"tag":545,"props":3202,"children":3203},{"style":557},[3204],{"type":52,"value":597},{"type":46,"tag":545,"props":3206,"children":3207},{"class":547,"line":1037},[3208],{"type":46,"tag":545,"props":3209,"children":3210},{"emptyLinePlaceholder":604},[3211],{"type":52,"value":607},{"type":46,"tag":545,"props":3213,"children":3214},{"class":547,"line":1054},[3215],{"type":46,"tag":545,"props":3216,"children":3217},{"style":1471},[3218],{"type":52,"value":3219},"\u002F\u002F Closure capture: pins 500MB dataset via scope\n",{"type":46,"tag":545,"props":3221,"children":3222},{"class":547,"line":1831},[3223,3227,3232,3236,3240,3245,3249],{"type":46,"tag":545,"props":3224,"children":3225},{"style":613},[3226],{"type":52,"value":616},{"type":46,"tag":545,"props":3228,"children":3229},{"style":563},[3230],{"type":52,"value":3231}," data ",{"type":46,"tag":545,"props":3233,"children":3234},{"style":557},[3235],{"type":52,"value":626},{"type":46,"tag":545,"props":3237,"children":3238},{"style":551},[3239],{"type":52,"value":927},{"type":46,"tag":545,"props":3241,"children":3242},{"style":634},[3243],{"type":52,"value":3244}," fetchLargeDataset",{"type":46,"tag":545,"props":3246,"children":3247},{"style":563},[3248],{"type":52,"value":1204},{"type":46,"tag":545,"props":3250,"children":3251},{"style":557},[3252],{"type":52,"value":597},{"type":46,"tag":545,"props":3254,"children":3255},{"class":547,"line":1895},[3256,3260,3265,3269,3273,3278],{"type":46,"tag":545,"props":3257,"children":3258},{"style":613},[3259],{"type":52,"value":616},{"type":46,"tag":545,"props":3261,"children":3262},{"style":563},[3263],{"type":52,"value":3264}," summary ",{"type":46,"tag":545,"props":3266,"children":3267},{"style":557},[3268],{"type":52,"value":626},{"type":46,"tag":545,"props":3270,"children":3271},{"style":634},[3272],{"type":52,"value":1606},{"type":46,"tag":545,"props":3274,"children":3275},{"style":563},[3276],{"type":52,"value":3277},"(data)",{"type":46,"tag":545,"props":3279,"children":3280},{"style":557},[3281],{"type":52,"value":597},{"type":46,"tag":545,"props":3283,"children":3284},{"class":547,"line":1952},[3285,3290,3294,3299,3303,3307,3311,3316,3320,3324,3329,3333,3337,3341,3345,3349],{"type":46,"tag":545,"props":3286,"children":3287},{"style":563},[3288],{"type":52,"value":3289},"scheduler",{"type":46,"tag":545,"props":3291,"children":3292},{"style":557},[3293],{"type":52,"value":847},{"type":46,"tag":545,"props":3295,"children":3296},{"style":634},[3297],{"type":52,"value":3298},"later",{"type":46,"tag":545,"props":3300,"children":3301},{"style":563},[3302],{"type":52,"value":667},{"type":46,"tag":545,"props":3304,"children":3305},{"style":557},[3306],{"type":52,"value":1204},{"type":46,"tag":545,"props":3308,"children":3309},{"style":613},[3310],{"type":52,"value":1264},{"type":46,"tag":545,"props":3312,"children":3313},{"style":634},[3314],{"type":52,"value":3315}," log",{"type":46,"tag":545,"props":3317,"children":3318},{"style":563},[3319],{"type":52,"value":667},{"type":46,"tag":545,"props":3321,"children":3322},{"style":557},[3323],{"type":52,"value":1674},{"type":46,"tag":545,"props":3325,"children":3326},{"style":584},[3327],{"type":52,"value":3328},"Done: ",{"type":46,"tag":545,"props":3330,"children":3331},{"style":557},[3332],{"type":52,"value":1684},{"type":46,"tag":545,"props":3334,"children":3335},{"style":563},[3336],{"type":52,"value":1707},{"type":46,"tag":545,"props":3338,"children":3339},{"style":557},[3340],{"type":52,"value":1712},{"type":46,"tag":545,"props":3342,"children":3343},{"style":563},[3344],{"type":52,"value":1350},{"type":46,"tag":545,"props":3346,"children":3347},{"style":557},[3348],{"type":52,"value":1468},{"type":46,"tag":545,"props":3350,"children":3351},{"style":1471},[3352],{"type":52,"value":3353}," \u002F\u002F data is pinned\n",{"type":46,"tag":67,"props":3355,"children":3357},{"id":3356},"related-traps",[3358],{"type":52,"value":3359},"Related Traps",{"type":46,"tag":3361,"props":3362,"children":3363},"ul",{},[3364,3374,3384],{"type":46,"tag":339,"props":3365,"children":3366},{},[3367,3372],{"type":46,"tag":61,"props":3368,"children":3369},{},[3370],{"type":52,"value":3371},"Cache Invalidation",{"type":52,"value":3373}," -- unbounded caches are the most common source of memory leaks. Every cache needs a max size and eviction policy. See the Cache Invalidation skill.",{"type":46,"tag":339,"props":3375,"children":3376},{},[3377,3382],{"type":46,"tag":61,"props":3378,"children":3379},{},[3380],{"type":52,"value":3381},"Backpressure",{"type":52,"value":3383}," -- unbounded buffers (queues, arrays) that grow because the consumer can't keep up are both a backpressure failure and a memory leak. Apply backpressure before the buffer exhausts memory.",{"type":46,"tag":339,"props":3385,"children":3386},{},[3387,3392],{"type":46,"tag":61,"props":3388,"children":3389},{},[3390],{"type":52,"value":3391},"Thundering Herd",{"type":52,"value":3393}," -- when an OOM-killed process restarts with cold caches, the sudden spike in cache misses can cause a thundering herd on the database.",{"type":46,"tag":3395,"props":3396,"children":3397},"style",{},[3398],{"type":52,"value":3399},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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);}",{"items":3401,"total":2768},[3402,3413,3426,3436,3446,3459,3471],{"slug":3403,"name":3403,"fn":3404,"description":3405,"org":3406,"tags":3407,"stars":29,"repoUrl":30,"updatedAt":3412},"staff-engineering-skills-backpressure","implement backpressure in streaming pipelines","Prevent unbounded resource growth when producers outpace consumers. Use when writing producer-consumer code, queue processing, batch operations, fan-out patterns, streaming pipelines, or any code where work is generated faster than it can be processed. Activates on patterns like Promise.all on dynamic-sized arrays, unbounded in-memory queues, producer loops without depth checks, fire-and-forget async calls in loops, or any buffer between a producer and consumer without a size limit.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3408,3411],{"name":3409,"slug":3410,"type":16},"Architecture","architecture",{"name":14,"slug":15,"type":16},"2026-06-17T08:40:42.723559",{"slug":3414,"name":3414,"fn":3415,"description":3416,"org":3417,"tags":3418,"stars":29,"repoUrl":30,"updatedAt":3425},"staff-engineering-skills-cache-invalidation","implement cache invalidation strategies","Prevent stale data bugs caused by missing or incomplete cache invalidation. Use when adding caching layers (Redis, in-memory Map, CDN, HTTP cache headers), optimizing read performance, or reviewing code that caches query results, API responses, or computed values. Activates on patterns like cache.set without cache.delete on write paths, unbounded Map\u002Fobject caches, TTL-only invalidation on security-sensitive data, Cache-Control headers on mutable content, or any caching where the write path doesn't invalidate the read cache.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3419,3420,3423,3424],{"name":3409,"slug":3410,"type":16},{"name":3421,"slug":3422,"type":16},"Caching","caching",{"name":18,"slug":19,"type":16},{"name":14,"slug":15,"type":16},"2026-06-17T08:40:45.194583",{"slug":3427,"name":3427,"fn":3428,"description":3429,"org":3430,"tags":3431,"stars":29,"repoUrl":30,"updatedAt":3435},"staff-engineering-skills-cardinality","prevent cardinality traps in systems code","Detect and prevent cardinality traps in systems code. Use when writing code that iterates over collections, stores items in memory, creates per-entity resources, or fans out operations across a set of items. Activates on patterns like loops over query results, in-memory Maps\u002FSets populated from databases, or \"one X per Y\" resource allocation.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3432,3433,3434],{"name":3409,"slug":3410,"type":16},{"name":18,"slug":19,"type":16},{"name":14,"slug":15,"type":16},"2026-06-17T08:40:40.264608",{"slug":3437,"name":3437,"fn":3438,"description":3439,"org":3440,"tags":3441,"stars":29,"repoUrl":30,"updatedAt":3445},"staff-engineering-skills-clock-skew","prevent clock skew bugs in distributed systems","Prevent bugs caused by assuming clocks are synchronized or monotonic. Use when writing code that compares timestamps across machines, measures durations, sets lock expiry, orders distributed events, deduplicates by time window, or uses Date.now() for anything other than logging or display. Activates on patterns like Date.now() used for duration measurement, absolute timestamp expiry shared across machines, wall clock timestamps for event ordering, last-write-wins conflict resolution with timestamps, or timeout calculations using wall clock time.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3442,3443,3444],{"name":3409,"slug":3410,"type":16},{"name":24,"slug":25,"type":16},{"name":18,"slug":19,"type":16},"2026-06-17T08:40:37.803541",{"slug":3447,"name":3447,"fn":3448,"description":3449,"org":3450,"tags":3451,"stars":29,"repoUrl":30,"updatedAt":3458},"staff-engineering-skills-consistency-models","manage consistency models in distributed systems","Prevent stale read bugs caused by replica lag, cache staleness, and index delay. Use when writing code that reads data after writing it, uses read replicas, caches query results, reads from search indexes, or builds event-driven read models. Activates on patterns like create-then-redirect, update-then-read, cache-aside with TTL, search-after-create, or any write followed by a read that might hit a different data source.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3452,3453,3456,3457],{"name":3409,"slug":3410,"type":16},{"name":3454,"slug":3455,"type":16},"Database","database",{"name":18,"slug":19,"type":16},{"name":14,"slug":15,"type":16},"2026-06-17T08:40:46.442182",{"slug":3460,"name":3460,"fn":3461,"description":3462,"org":3463,"tags":3464,"stars":29,"repoUrl":30,"updatedAt":3470},"staff-engineering-skills-denormalization","prevent data model denormalization traps","Detect and prevent denormalization traps when designing data models. Use when writing code that copies fields between tables, embeds related data in documents, caches composed objects, or adds redundant columns to avoid joins. Activates on patterns like storing derived\u002Fcopied data, syncing fields across tables, or embedding nested objects in document stores.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3465,3466,3469],{"name":3409,"slug":3410,"type":16},{"name":3467,"slug":3468,"type":16},"Data Modeling","data-modeling",{"name":3454,"slug":3455,"type":16},"2026-06-17T08:40:53.835868",{"slug":3472,"name":3472,"fn":3473,"description":3474,"org":3475,"tags":3476,"stars":29,"repoUrl":30,"updatedAt":3482},"staff-engineering-skills-distributed-system-fallacies","design resilient distributed systems","Prevent failures caused by treating network calls like function calls. Use when writing code that calls external services, splits a monolith into microservices, chains multiple API calls, orchestrates distributed workflows, or handles requests that depend on other services. Activates on patterns like sequential service calls without timeouts, fetch\u002Faxios calls without error handling, multi-service writes without compensation, hardcoded service URLs, or any code that assumes the network is reliable, fast, or free.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3477,3480,3481],{"name":3478,"slug":3479,"type":16},"API Development","api-development",{"name":3409,"slug":3410,"type":16},{"name":18,"slug":19,"type":16},"2026-06-17T08:40:47.666795",{"items":3484,"total":3638},[3485,3504,3517,3527,3544,3559,3573,3590,3603,3615,3626,3631],{"slug":3486,"name":3486,"fn":3487,"description":3488,"org":3489,"tags":3490,"stars":3501,"repoUrl":3502,"updatedAt":3503},"trigger-authoring-chat-agent","author durable AI chat agents with Trigger.dev","Author and run a durable AI chat agent with chat.agent from @trigger.dev\u002Fsdk\u002Fai: the per-turn run loop, why you MUST spread ...chat.toStreamTextOptions() first, returning a StreamTextResult vs calling chat.pipe(), the two server actions (chat.createStartSessionAction + auth.createPublicToken), and wiring useChat to useTriggerChatTransport. Load this when building, modifying, or debugging a chat backend (the agent task or its lifecycle hooks) or its React transport, when declaring typed tools or custom data parts, or when migrating a plain AI SDK streamText route to chat.agent.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3491,3494,3497,3498],{"name":3492,"slug":3493,"type":16},"Agents","agents",{"name":3495,"slug":3496,"type":16},"SDK","sdk",{"name":9,"slug":8,"type":16},{"name":3499,"slug":3500,"type":16},"Workflow Automation","workflow-automation",14401,"https:\u002F\u002Fgithub.com\u002Ftriggerdotdev\u002Ftrigger.dev","2026-07-02T17:12:52.307135",{"slug":3505,"name":3505,"fn":3506,"description":3507,"org":3508,"tags":3509,"stars":3501,"repoUrl":3502,"updatedAt":3516},"trigger-authoring-tasks","author backend Trigger.dev tasks","Covers writing backend Trigger.dev tasks with @trigger.dev\u002Fsdk: defining task() and schemaTask(), the run function and its ctx, retries, waits, queues and concurrency, idempotency keys, run metadata, logging, triggering other tasks (and the Result shape), scheduled\u002Fcron tasks, and the essentials of trigger.config.ts. Load this whenever you are authoring or editing code inside a \u002Ftrigger directory, defining a task, or writing backend code that triggers tasks. Realtime\u002FReact hooks and AI chat are covered by separate skills.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3510,3513,3514,3515],{"name":3511,"slug":3512,"type":16},"Backend","backend",{"name":3495,"slug":3496,"type":16},{"name":9,"slug":8,"type":16},{"name":3499,"slug":3500,"type":16},"2026-07-02T17:12:48.396964",{"slug":3518,"name":3518,"fn":3519,"description":3520,"org":3521,"tags":3522,"stars":3501,"repoUrl":3502,"updatedAt":3526},"trigger-chat-agent-advanced","manage Trigger.dev chat sessions and transports","Advanced and operational chat.agent capabilities for Trigger.dev, loaded on demand. Load this when working on the raw Sessions primitive (sessions \u002F SessionHandle), a custom chat transport or the realtime wire protocol, durable sub-agents (AgentChat, chat.stream.writer), human-in-the-loop, steering, actions, background injection (chat.defer \u002F chat.inject), fast starts (preload, Head Start via @trigger.dev\u002Fsdk\u002Fchat-server), context resilience (compaction, recovery boot, OOM, large payloads), chat.local run-scoped state, offline testing with mockChatAgent, or prerelease\u002Fversion upgrades. For the everyday chat.agent({...}) definition and the useTriggerChatTransport happy path, use the trigger-authoring-chat-agent skill instead.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3523,3524,3525],{"name":3492,"slug":3493,"type":16},{"name":9,"slug":8,"type":16},{"name":3499,"slug":3500,"type":16},"2026-07-02T17:12:51.03018",{"slug":3528,"name":3528,"fn":3529,"description":3530,"org":3531,"tags":3532,"stars":3501,"repoUrl":3502,"updatedAt":3543},"trigger-realtime-and-frontend","subscribe to Trigger.dev runs in realtime","Trigger.dev client\u002Ffrontend surface: subscribe to runs in realtime (runs.subscribeToRun and the @trigger.dev\u002Freact-hooks hook useRealtimeRun), consume metadata and AI\u002Ftext streams in React (useRealtimeStream), trigger tasks from the browser (useTaskTrigger, useRealtimeTaskTrigger), and mint scoped frontend credentials with auth.createPublicToken \u002F auth.createTriggerPublicToken. Load when wiring a frontend (React\u002FNext.js\u002FRemix) or backend-for-frontend to show live run progress, status badges, token streams, trigger buttons, or wait-token approval UIs. NOT for writing the backend task itself (streams.define \u002F metadata.set is trigger-authoring-tasks territory); this is the consumer side.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3533,3536,3539,3542],{"name":3534,"slug":3535,"type":16},"Frontend","frontend",{"name":3537,"slug":3538,"type":16},"React","react",{"name":3540,"slug":3541,"type":16},"Real-time","real-time",{"name":9,"slug":8,"type":16},"2026-07-02T17:12:49.717706",{"slug":3545,"name":3545,"fn":3546,"description":3547,"org":3548,"tags":3549,"stars":3556,"repoUrl":3557,"updatedAt":3558},"trigger-agents","orchestrate AI agents with Trigger.dev","AI agent patterns with Trigger.dev - orchestration, parallelization, routing, evaluator-optimizer, and human-in-the-loop. Use when building LLM-powered tasks that need parallel workers, approval gates, tool calling, or multi-step agent workflows.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3550,3551,3554,3555],{"name":3492,"slug":3493,"type":16},{"name":3552,"slug":3553,"type":16},"Multi-Agent","multi-agent",{"name":9,"slug":8,"type":16},{"name":3499,"slug":3500,"type":16},30,"https:\u002F\u002Fgithub.com\u002Ftriggerdotdev\u002Fskills","2026-04-06T18:54:46.023553",{"slug":3560,"name":3560,"fn":3561,"description":3562,"org":3563,"tags":3564,"stars":3556,"repoUrl":3557,"updatedAt":3572},"trigger-config","configure Trigger.dev project settings","Configure Trigger.dev projects with trigger.config.ts. Use when setting up build extensions for Prisma, Playwright, FFmpeg, Python, or customizing deployment settings.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3565,3568,3571],{"name":3566,"slug":3567,"type":16},"Configuration","configuration",{"name":3569,"slug":3570,"type":16},"Deployment","deployment",{"name":9,"slug":8,"type":16},"2026-04-06T18:54:44.764258",{"slug":3574,"name":3574,"fn":3575,"description":3576,"org":3577,"tags":3578,"stars":3556,"repoUrl":3557,"updatedAt":3589},"trigger-cost-savings","optimize Trigger.dev task costs","Analyze Trigger.dev tasks, schedules, and runs for cost optimization opportunities. Use when asked to reduce spend, optimize costs, audit usage, right-size machines, or review task efficiency. Requires Trigger.dev MCP tools for run analysis.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3579,3582,3585,3588],{"name":3580,"slug":3581,"type":16},"Analytics","analytics",{"name":3583,"slug":3584,"type":16},"Cost Optimization","cost-optimization",{"name":3586,"slug":3587,"type":16},"Operations","operations",{"name":9,"slug":8,"type":16},"2026-04-06T18:54:48.555552",{"slug":3591,"name":3591,"fn":3592,"description":3593,"org":3594,"tags":3595,"stars":3556,"repoUrl":3557,"updatedAt":3602},"trigger-realtime","monitor Trigger.dev tasks in real-time","Subscribe to Trigger.dev task runs in real-time from frontend and backend. Use when building progress indicators, live dashboards, streaming AI\u002FLLM responses, or React components that display task status.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3596,3597,3600,3601],{"name":3534,"slug":3535,"type":16},{"name":3598,"slug":3599,"type":16},"Observability","observability",{"name":3540,"slug":3541,"type":16},{"name":9,"slug":8,"type":16},"2026-04-06T18:54:47.293822",{"slug":3604,"name":3604,"fn":3605,"description":3606,"org":3607,"tags":3608,"stars":3556,"repoUrl":3557,"updatedAt":3614},"trigger-setup","set up Trigger.dev in projects","Set up Trigger.dev in your project. Use when adding Trigger.dev for the first time, creating trigger.config.ts, or initializing the trigger directory.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3609,3610,3613],{"name":3566,"slug":3567,"type":16},{"name":3611,"slug":3612,"type":16},"Local Development","local-development",{"name":9,"slug":8,"type":16},"2026-04-06T18:54:42.280816",{"slug":3616,"name":3616,"fn":3617,"description":3618,"org":3619,"tags":3620,"stars":3556,"repoUrl":3557,"updatedAt":3625},"trigger-tasks","build durable background tasks with Trigger.dev","Build AI agents, workflows and durable background tasks with Trigger.dev. Use when creating tasks, triggering jobs, handling retries, scheduling cron jobs, or implementing queues and concurrency control.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3621,3622,3623,3624],{"name":3492,"slug":3493,"type":16},{"name":3511,"slug":3512,"type":16},{"name":9,"slug":8,"type":16},{"name":3499,"slug":3500,"type":16},"2026-04-06T18:54:43.514369",{"slug":3403,"name":3403,"fn":3404,"description":3405,"org":3627,"tags":3628,"stars":29,"repoUrl":30,"updatedAt":3412},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3629,3630],{"name":3409,"slug":3410,"type":16},{"name":14,"slug":15,"type":16},{"slug":3414,"name":3414,"fn":3415,"description":3416,"org":3632,"tags":3633,"stars":29,"repoUrl":30,"updatedAt":3425},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3634,3635,3636,3637],{"name":3409,"slug":3410,"type":16},{"name":3421,"slug":3422,"type":16},{"name":18,"slug":19,"type":16},{"name":14,"slug":15,"type":16},26]