Wie eine einzige Kafka-Connection unsere Node.js OOM-Kills gestoppt hat

Wie eine einzige Kafka-Connection unsere Node.js OOM-Kills gestoppt hat

Christian Bielak

5. März 2026

nodejs

backend

typescript

apache kafka

Wie eine einzige Kafka-Connection unsere Node.js OOM-Kills gestoppt hat

Wir hatten in letzter Zeit immer wieder mit unerklärlichen Out-of-Memory-Kills (OOM) in einem unserer Node.js-Services zu kämpfen. Der Service basiert auf Koa und schiebt kontinuierlich Events in Richtung Apache Kafka. Nach ein paar Tagen intensiven Debuggings und der entsprechenden Frustration haben wir den Übeltäter endlich gefunden. Ursprünglich hatten wir das Setup etwas naiv gebaut: Für jedes zu verschickende Event wurde eine neue Kafka-Verbindung aufgebaut, kurz genutzt und danach wieder weggeworfen. Bei geringer Last fällt das kaum auf. Aber sobald der Service wirklich Traffic bekam und hunderte oder tausende Events pro Minute verarbeiten musste, rächte sich das massiv. Obwohl Kafka-Clients recht performant sind, ist das ständige Öffnen und Schließen von Verbindungen in Node.js pures Gift für das Speichermanagement. Es entstanden schlichtweg zu viele Verbindungen in zu kurzer Zeit. Der Garbage Collector kam einfach nicht mehr hinterher, die Event-Loop blockierte und irgendwann zog der Kubernetes-OOM-Killer unserem Pod den Stecker. Die Lösung war am Ende fast peinlich simpel: Wir machen jetzt pro Pod beim Start genau eine einzige Kafka-Verbindung auf und halten sie offen. Alle Events, die der Pod verarbeitet, nutzen diese selbe Connection (im Grunde ein simples Singleton-Pattern). Wenn der Pod regulär beendet wird oder abstürzt, räumt ein sauberer Shutdown-Hook die Verbindung ordentlich ab, sodass keine Leichen zurückbleiben. Seit diesem kleinen Refactoring ist die Speichernutzung komplett flach. Keine Memory-Spikes mehr, keine Abstürze durch "Too many open connections". Ein toller Nebeneffekt: Die Latenz ist gesunken, weil der ständige Handshake-Overhead beim Verbindungsaufbau wegfällt, und unser Kafka-Broker freut sich ebenfalls über weniger Last. Man vergisst im Alltag leicht, dass Netzwerkverbindungen teuer sind. Wenn dein Node-Service unter Last wegbricht und Kafka im Spiel ist, schau dir definitiv mal das Verbindungs-Handling an.