[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"public-branding":3,"category-de-engineering":8},{"siteName":4,"primaryColor":5,"accentColor":6,"faviconUrl":7,"logoUrl":7},"KiroCloud","#ffffff","#888888","",[9],{"id":10,"title":11,"author":12,"body":13,"category":649,"description":650,"extension":651,"lastUpdated":652,"meta":653,"navigation":242,"order":246,"path":654,"readTime":655,"seo":656,"stem":657,"__hash__":658},"docs\u002Fdocs\u002Fde\u002Fnodejs-gc-tuning.md","Node.js Garbage Collection Tuning für Bots im 24\u002F7 Dauerbetrieb","Luca Lichtenwald",{"type":14,"value":15,"toc":638},"minimark",[16,20,29,32,35,40,43,95,104,106,110,113,121,124,154,160,167,170,186,188,192,199,533,539,541,545,552,608,634],[17,18,11],"h1",{"id":19},"nodejs-garbage-collection-tuning-für-bots-im-247-dauerbetrieb",[21,22,23,24,28],"p",{},"In vielen Discord-Bot-Umgebungen führt der standardmäßige Garbage-Collection-Zyklus von Node.js zu unvorhersehbaren Verzögerungen (GC-Pauses). Wenn die V8-Engine einen vollständigen Mark-Sweep-Compact-Durchlauf startet, stoppt der JavaScript-Event-Loop für mehrere Dutzend bis Hunderte Millisekunden. Für Discord-Bots bedeutet das: verpasste Heartbeats, steigender Gateway-Ping und im schlimmsten Fall Verbindungsabbrüche mit Code ",[25,26,27],"code",{},"1006"," (Abnormal Closure).",[21,30,31],{},"In diesem Guide erklären wir die V8-Speicherarchitektur und wie du Node.js mit gezielten Flags für minimale Latenz und stabilen Dauerbetrieb konfigurierst.",[33,34],"hr",{},[36,37,39],"h2",{"id":38},"_1-v8-speicherarchitektur-new-space-vs-old-space","1. V8 Speicherarchitektur: New Space vs. Old Space",[21,41,42],{},"Der V8-Heap ist in zwei Hauptbereiche unterteilt:",[44,45,46,74],"ol",{},[47,48,49,53],"li",{},[50,51,52],"strong",{},"Young Generation (New Space):",[54,55,56,59,66],"ul",{},[47,57,58],{},"Hier landen alle neu erstellten Objekte (Nachrichten, Events, Strings).",[47,60,61,62,65],{},"Der Bereich ist klein (typischerweise 16–64 MB) und wird extrem schnell mit dem ",[50,63,64],{},"Scavenger-Algorithmus"," bereinigt.",[47,67,68,69,73],{},"Objekte, die zwei Scavenge-Zyklen überleben, werden in den ",[70,71,72],"em",{},"Old Space"," befördert.",[47,75,76,79],{},[50,77,78],{},"Old Generation (Old Space):",[54,80,81,84],{},[47,82,83],{},"Enthält langlebige Objekte (Bot-Client, Modul-Singletons, Langzeit-Caches).",[47,85,86,87,90,91,94],{},"Die Bereinigung erfordert teure ",[50,88,89],{},"Mark-Sweep-"," und ",[50,92,93],{},"Mark-Compact-Zyklen",", die Stop-the-World Pausen verursachen.",[96,97,102],"pre",{"className":98,"code":100,"language":101},[99],"language-text","┌────────────────────────────────────────────────────────┐\n│                   V8 Process Memory                    │\n├──────────────────────────┬─────────────────────────────┤\n│  New Space (16-64 MB)    │   Old Space (up to max-old) │\n│  ┌────────────┬────────┐ │   ┌───────────────────────┐ │\n│  │ Semi-Space │ To-    │ │   │ Long-Lived Objects    │ │\n│  │ From-Space │ Space  │ │   │ Bot Client, Caches    │ │\n│  └────────────┴────────┘ │   └───────────────────────┘ │\n│      [Scavenge GC]       │      [Mark-Sweep-Compact]   │\n└──────────────────────────┴─────────────────────────────┘\n","text",[25,103,100],{"__ignoreMap":7},[33,105],{},[36,107,109],{"id":108},"_2-die-wichtigsten-v8-flags-für-discord-bots","2. Die wichtigsten V8 Flags für Discord-Bots",[21,111,112],{},"Beim Start deines Node.js-Prozesses kannst du das Verhalten des Garbage Collectors über Runtime-Flags steuern:",[114,115,117,118],"h3",{"id":116},"a-heap-limit-explizit-setzen-max-old-space-size","A. Heap-Limit explizit setzen: ",[25,119,120],{},"--max-old-space-size",[21,122,123],{},"Standardmäßig allokiert Node.js auf 64-Bit-Systemen bis zu 2 oder 4 GB Speicher, bevor aggressiv aufgeräumt wird. Für Bots führt dies dazu, dass Müll lange im RAM verbleibt:",[96,125,129],{"className":126,"code":127,"language":128,"meta":7,"style":7},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# Auf einem Server mit 1 GB RAM-Zuweisung:\nnode --max-old-space-size=512 dist\u002Findex.js\n","bash",[25,130,131,140],{"__ignoreMap":7},[132,133,136],"span",{"class":134,"line":135},"line",1,[132,137,139],{"class":138},"sHwdD","# Auf einem Server mit 1 GB RAM-Zuweisung:\n",[132,141,143,147,151],{"class":134,"line":142},2,[132,144,146],{"class":145},"sBMFI","node",[132,148,150],{"class":149},"sfazB"," --max-old-space-size=512",[132,152,153],{"class":149}," dist\u002Findex.js\n",[21,155,156,159],{},[70,157,158],{},"Effekt:"," V8 startet Aufräumzyklen deutlich früher, bevor das System in Swap-Memory gerät oder der Linux OOM-Killer den Prozess terminiert.",[114,161,163,164],{"id":162},"b-inkrementelles-paralleles-marking-max-semi-space-size","B. Inkrementelles & Paralleles Marking: ",[25,165,166],{},"--max-semi-space-size",[21,168,169],{},"Vergrößert den New-Space, sodass kurzlebige Objekte (wie Payload-Parsing von Discord-Nachrichten) komplett im schnellen New-Space abgeräumt werden, ohne jemals in den Old-Space zu wandern:",[96,171,173],{"className":126,"code":172,"language":128,"meta":7,"style":7},"node --max-semi-space-size=64 --max-old-space-size=512 dist\u002Findex.js\n",[25,174,175],{"__ignoreMap":7},[132,176,177,179,182,184],{"class":134,"line":135},[132,178,146],{"class":145},[132,180,181],{"class":149}," --max-semi-space-size=64",[132,183,150],{"class":149},[132,185,153],{"class":149},[33,187],{},[36,189,191],{"id":190},"_3-gc-metriken-im-laufenden-betrieb-protokollieren","3. GC-Metriken im laufenden Betrieb protokollieren",[21,193,194,195,198],{},"Mit dem nativen ",[25,196,197],{},"perf_hooks","-Modul von Node.js kannst du die genaue Dauer jeder GC-Pause in Mikrosekunden messen:",[96,200,204],{"className":201,"code":202,"language":203,"meta":7,"style":7},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { PerformanceObserver } from 'node:perf_hooks';\n\nexport function setupGCMonitoring() {\n  const obs = new PerformanceObserver((list) => {\n    const entries = list.getEntries();\n    for (const entry of entries) {\n      const durationMs = entry.duration;\n      \u002F\u002F entry.detail enthält den GC-Typ: 1 = Scavenge, 2 = Mark-Sweep-Compact, 4 = Incremental\n      if (durationMs > 25) {\n        console.warn(`[GC Warning] Lange GC-Pause erkannt: ${durationMs.toFixed(2)} ms (Typ: ${entry.name})`);\n      }\n    }\n  });\n\n  obs.observe({ entryTypes: ['gc'] });\n}\n","typescript",[25,205,206,238,244,264,299,323,349,369,375,397,459,465,471,481,486,527],{"__ignoreMap":7},[132,207,208,212,216,220,223,226,229,232,235],{"class":134,"line":135},[132,209,211],{"class":210},"s7zQu","import",[132,213,215],{"class":214},"sMK4o"," {",[132,217,219],{"class":218},"sTEyZ"," PerformanceObserver",[132,221,222],{"class":214}," }",[132,224,225],{"class":210}," from",[132,227,228],{"class":214}," '",[132,230,231],{"class":149},"node:perf_hooks",[132,233,234],{"class":214},"'",[132,236,237],{"class":214},";\n",[132,239,240],{"class":134,"line":142},[132,241,243],{"emptyLinePlaceholder":242},true,"\n",[132,245,247,250,254,258,261],{"class":134,"line":246},3,[132,248,249],{"class":210},"export",[132,251,253],{"class":252},"spNyl"," function",[132,255,257],{"class":256},"s2Zo4"," setupGCMonitoring",[132,259,260],{"class":214},"()",[132,262,263],{"class":214}," {\n",[132,265,267,270,273,276,279,281,285,287,291,294,297],{"class":134,"line":266},4,[132,268,269],{"class":252},"  const",[132,271,272],{"class":218}," obs",[132,274,275],{"class":214}," =",[132,277,278],{"class":214}," new",[132,280,219],{"class":256},[132,282,284],{"class":283},"swJcz","(",[132,286,284],{"class":214},[132,288,290],{"class":289},"sHdIc","list",[132,292,293],{"class":214},")",[132,295,296],{"class":252}," =>",[132,298,263],{"class":214},[132,300,302,305,308,310,313,316,319,321],{"class":134,"line":301},5,[132,303,304],{"class":252},"    const",[132,306,307],{"class":218}," entries",[132,309,275],{"class":214},[132,311,312],{"class":218}," list",[132,314,315],{"class":214},".",[132,317,318],{"class":256},"getEntries",[132,320,260],{"class":283},[132,322,237],{"class":214},[132,324,326,329,332,335,338,341,343,346],{"class":134,"line":325},6,[132,327,328],{"class":210},"    for",[132,330,331],{"class":283}," (",[132,333,334],{"class":252},"const",[132,336,337],{"class":218}," entry",[132,339,340],{"class":214}," of",[132,342,307],{"class":218},[132,344,345],{"class":283},") ",[132,347,348],{"class":214},"{\n",[132,350,352,355,358,360,362,364,367],{"class":134,"line":351},7,[132,353,354],{"class":252},"      const",[132,356,357],{"class":218}," durationMs",[132,359,275],{"class":214},[132,361,337],{"class":218},[132,363,315],{"class":214},[132,365,366],{"class":218},"duration",[132,368,237],{"class":214},[132,370,372],{"class":134,"line":371},8,[132,373,374],{"class":138},"      \u002F\u002F entry.detail enthält den GC-Typ: 1 = Scavenge, 2 = Mark-Sweep-Compact, 4 = Incremental\n",[132,376,378,381,383,386,389,393,395],{"class":134,"line":377},9,[132,379,380],{"class":210},"      if",[132,382,331],{"class":283},[132,384,385],{"class":218},"durationMs",[132,387,388],{"class":214}," >",[132,390,392],{"class":391},"sbssI"," 25",[132,394,345],{"class":283},[132,396,348],{"class":214},[132,398,400,403,405,408,410,413,416,419,421,423,426,428,431,433,436,439,441,444,446,449,451,453,455,457],{"class":134,"line":399},10,[132,401,402],{"class":218},"        console",[132,404,315],{"class":214},[132,406,407],{"class":256},"warn",[132,409,284],{"class":283},[132,411,412],{"class":214},"`",[132,414,415],{"class":149},"[GC Warning] Lange GC-Pause erkannt: ",[132,417,418],{"class":214},"${",[132,420,385],{"class":218},[132,422,315],{"class":214},[132,424,425],{"class":256},"toFixed",[132,427,284],{"class":218},[132,429,430],{"class":391},"2",[132,432,293],{"class":218},[132,434,435],{"class":214},"}",[132,437,438],{"class":149}," ms (Typ: ",[132,440,418],{"class":214},[132,442,443],{"class":218},"entry",[132,445,315],{"class":214},[132,447,448],{"class":218},"name",[132,450,435],{"class":214},[132,452,293],{"class":149},[132,454,412],{"class":214},[132,456,293],{"class":283},[132,458,237],{"class":214},[132,460,462],{"class":134,"line":461},11,[132,463,464],{"class":214},"      }\n",[132,466,468],{"class":134,"line":467},12,[132,469,470],{"class":214},"    }\n",[132,472,474,477,479],{"class":134,"line":473},13,[132,475,476],{"class":214},"  }",[132,478,293],{"class":283},[132,480,237],{"class":214},[132,482,484],{"class":134,"line":483},14,[132,485,243],{"emptyLinePlaceholder":242},[132,487,489,492,494,497,499,502,505,508,511,513,516,518,521,523,525],{"class":134,"line":488},15,[132,490,491],{"class":218},"  obs",[132,493,315],{"class":214},[132,495,496],{"class":256},"observe",[132,498,284],{"class":283},[132,500,501],{"class":214},"{",[132,503,504],{"class":283}," entryTypes",[132,506,507],{"class":214},":",[132,509,510],{"class":283}," [",[132,512,234],{"class":214},[132,514,515],{"class":149},"gc",[132,517,234],{"class":214},[132,519,520],{"class":283},"] ",[132,522,435],{"class":214},[132,524,293],{"class":283},[132,526,237],{"class":214},[132,528,530],{"class":134,"line":529},16,[132,531,532],{"class":214},"}\n",[21,534,535,536,538],{},"Wenn du in den Logs regelmäßige Spitzen von über 50 ms siehst, bedeutet dies, dass zu viele temporäre Objekte in den ",[70,537,72],{}," befördert werden.",[33,540],{},[36,542,544],{"id":543},"_4-empfohlene-produktions-startparameter","4. Empfohlene Produktions-Startparameter",[21,546,547,548,551],{},"Für Container- und Cloud-Deployments auf KiroCloud empfehlen wir folgende Kombination im ",[25,549,550],{},"package.json"," Startskript:",[96,553,557],{"className":554,"code":555,"language":556,"meta":7,"style":7},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"scripts\": {\n    \"start:prod\": \"node --max-semi-space-size=64 --max-old-space-size=768 --enable-source-maps dist\u002Findex.js\"\n  }\n}\n","json",[25,558,559,563,578,599,604],{"__ignoreMap":7},[132,560,561],{"class":134,"line":135},[132,562,348],{"class":214},[132,564,565,568,571,574,576],{"class":134,"line":142},[132,566,567],{"class":214},"  \"",[132,569,570],{"class":252},"scripts",[132,572,573],{"class":214},"\"",[132,575,507],{"class":214},[132,577,263],{"class":214},[132,579,580,583,586,588,590,593,596],{"class":134,"line":246},[132,581,582],{"class":214},"    \"",[132,584,585],{"class":145},"start:prod",[132,587,573],{"class":214},[132,589,507],{"class":214},[132,591,592],{"class":214}," \"",[132,594,595],{"class":149},"node --max-semi-space-size=64 --max-old-space-size=768 --enable-source-maps dist\u002Findex.js",[132,597,598],{"class":214},"\"\n",[132,600,601],{"class":134,"line":266},[132,602,603],{"class":214},"  }\n",[132,605,606],{"class":134,"line":301},[132,607,532],{"class":214},[54,609,610,618,626],{},[47,611,612,617],{},[50,613,614],{},[25,615,616],{},"--max-semi-space-size=64",": Hält JSON-WebSocket-Payloads im schnellen Young-Space.",[47,619,620,625],{},[50,621,622],{},[25,623,624],{},"--max-old-space-size=768",": Verhindert, dass der Prozess das 1-GB-Containerlimit überschreitet.",[47,627,628,633],{},[50,629,630],{},[25,631,632],{},"--enable-source-maps",": Präzise Stack-Traces bei Fehlern ohne Performance-Verlust.",[635,636,637],"style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":7,"searchDepth":142,"depth":142,"links":639},[640,641,647,648],{"id":38,"depth":142,"text":39},{"id":108,"depth":142,"text":109,"children":642},[643,645],{"id":116,"depth":246,"text":644},"A. Heap-Limit explizit setzen: --max-old-space-size",{"id":162,"depth":246,"text":646},"B. Inkrementelles & Paralleles Marking: --max-semi-space-size",{"id":190,"depth":142,"text":191},{"id":543,"depth":142,"text":544},"engineering","Tiefgehende Optimierung der V8-Engine für Node.js Cloud-Bots. Scavenge vs. Mark-Sweep, Heap-Limits, GC-Flags und Latenzreduktion.","md","2026-10-09",{},"\u002Fdocs\u002Fde\u002Fnodejs-gc-tuning","11 min",{"title":11,"description":650},"docs\u002Fde\u002Fnodejs-gc-tuning","Gum8zOayrLqzwLvsVkVJKtylMmxiOij8pRFDUIxkF-Y"]