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