...

Load Average richtig interpretieren: Missverständnisse im Hosting

Load Average zeigt an, wie viele Prozesse gerade laufen oder auf CPU-Zeit warten – nicht, wie hoch die CPU in Prozent steht. Wer den Wert ohne Kontext liest, reagiert oft mit Panik oder falschen Upgrades; ich erkläre, wie ich ihn sauber einordne und daraus sinnvolle Hosting-Entscheidungen ableite.

Zentrale Punkte

  • Kein CPU%: Load zählt Prozesse in der Run-Queue.
  • Pro Kern denken: Load durch Kernzahl teilen.
  • I/O-Wait treibt Last oft stärker als CPU.
  • 1/5/15-Minuten-Mittel glätten Spitzen.
  • Kontext vor Maßnahmen: Uhrzeit, Jobs, Traffic.

Was der Load Average wirklich misst

Ich lese den Wert als durchschnittliche Anzahl der Prozesse, die über 1, 5 und 15 Minuten aktiv laufen oder in der Run-Queue warten. Viele verwechseln ihn mit CPU-Last in Prozent, doch der Zähler kennt lediglich Warteschlangen, nicht Rechenzeit. Ein Load von 1,0 bedeutet auf einem Ein-Kern-System dauerhafte Vollauslastung, während derselbe Wert auf vier Kernen entspannt bleibt. Ich vergleiche den Load deshalb immer relativ zur Kernzahl und bewerte erst dann, ob echte Überlast vorliegt. Der 15-Minuten-Schnitt zeigt Trends und hilft mir, kurzlebige Spitzen von anhaltender Last zu unterscheiden.

Warum hohe Werte oft I/O-Probleme zeigen

Ein hoher Load kann entstehen, obwohl die CPU kaum arbeitet – I/O-Warteschlangen blockieren dann Threads. Ich prüfe mit top oder htop den Anteil %wa (I/O-Wait) und schaue mit iotop, welche Prozesse das Storage ausbremsen. Häufig sind langsam reagierende Datenbanken, Backup-Jobs oder überlastete Netzlaufwerke die Ursache. Wenn %wa steigt, bringt ein CPU-Upgrade wenig; schneller Storage, Caching und weniger Sync-Flushes wirken stärker. Eine gute Vertiefung liefert der Beitrag I/O-Wait verstehen, den ich bei hartnäckigen Wartezeiten zu Rate ziehe.

Missverständnis: Load ist gleich CPU-Auslastung

Ich trenne strikt zwischen Prozentwerten der CPU und dem Load Average als Warteschlangen-Metrik. Ein Load von 8 auf einem 8-Kern-Server kann normal sein, wenn alle Kerne arbeiten und nichts wartet. Kritisch wird es, wenn Load deutlich über der Kernzahl liegt und gleichzeitig die 15-Minuten-Kurve ansteigt. Um Korrelationen zu sehen, lege ich CPU%, I/O-Wait, Scheduler-Zeiten und Prozesslisten nebeneinander. Erst das Zusammenspiel dieser Signale erklärt mir, ob die Maschine rechnet, blockiert oder schlicht viele kurzlebige Jobs abarbeitet.

Spitzen richtig einordnen statt Alarm

Kurze Lastspitzen durch Cron, Logrotation oder Backups gehören zum Alltag und bedeuten nicht automatisch Störung. Ich bewerte immer die Tageszeit, die Dauer und die 15-Minuten-Linie, bevor ich Alarme auslöse oder Kapazität nachschiebe. Schwellen skaliere ich mit der Kernzahl, z. B. Alarm erst bei Load > 2× Cores über mehrere Minuten. Unregelmäßige Peaks bei Content-Management-Systemen prüfe ich zusätzlich auf Hintergrundaufgaben; zu WordPress passt der Hinweis WP-Cronjobs und Last. So verhindere ich blinde Reaktionen und priorisiere Maßnahmen mit Nutzen.

Load Average im Hosting-Alltag lesen

Ich starte mit uptime für einen schnellen Blick und öffne dann htop, um Prozesse, CPU-Verteilung, RAM und I/O zu sehen. Bleibt der 15-Minuten-Load hoch, suche ich mit iotop oder pidstat nach Übeltätern. Bei Datenbank-lastigen Workloads prüfe ich Query-Latenzen, Indexe und Cache-Treffer. Auf Webservern schaue ich, ob zu viele gleichzeitige PHP-Worker warten oder wenn nötig der OpCache greift. Diese Routine trennt Symptome von Ursachen und spart mir teure, wirkungslose Hardware-Upgrades.

Metrik Alltag Warnsignal (4 Kerne) Nächster Schritt
Load 1min <4 >8 über 3–5 min Top-Prozesse prüfen
Load 15min <3 >6 ansteigend Kapazität/Architektur planen
CPU% <80% >95% dauerhaft Code/Worker optimieren
I/O-Wait <10% >20% Spitzen Storage/Caching prüfen

Werkzeuge für sauberes Hosting-Monitoring

Ich kombiniere Metriken aus Agenten mit Logs und Traces, um Ursachen schneller zu finden. Für Zeitreihen nutze ich Prometheus oder alternativen Sammler, visualisiert in Grafana. Infrastrukturell helfen mir Zabbix für Checks und flexible Alarmregeln sowie SaaS-Dienste für schnelle Dashboards. Wichtig ist eine einheitliche Sicht auf Load, CPU%, RAM, Swap, Disk-Latenzen und Netzwerk. Ohne gemeinsame Zeitleiste bleibt die Interpretation von Lastwerten Stückwerk.

Kategorie Beispiel Stärken
Open-Source Zabbix Checks, Agent, Alarmlogik
Time-Series Prometheus Pull-Modell, PromQL
Visualisierung Grafana Dashboards, Alerting
SaaS Datadog Integrationen, APM

Optimieren bei dauerhaft hohem Load

Ich beginne mit dem größten Schmerz: langsame Queries, blockierende I/O-Pfade oder zu viele gleichzeitige Worker. Datenbank-Indizes, Connection-Pools und Query-Caches wie Redis oder Memcached reduzieren Wartezeit spürbar. Auf Applikationsebene entlaste ich den Ursprung: Caching von Seiten, Fragmenten und Objekten sowie saubere Queue-Verarbeitung. Auf dem System stelle ich vm.swappiness passend ein, prüfe Huge Pages und setze sinnvolle Limits für Dienste. Erst wenn Softwareseitiges erschöpft ist, skaliere ich vertikal (mehr RAM/CPU) oder horizontal (mehr Instanzen mit Load Balancer).

Load Average auf Multi-Core-Systemen

Ich rechne den Load immer relativ zu Kernen: Load 16 kann auf 16 physischen Kernen okay sein. Hyper-Threading verdoppelt die logischen CPUs, doch echte Performance folgt nicht immer linear; ich bewerte deshalb zusätzlich die Latenzen. In Containern oder VMs spielen CPU-Shares, CFS-Quotas und Limits hinein, was scheinbar „normale“ Werte verfälscht. Ein Blick auf CPU-Throttling und Scheduler-Wartezeiten trennt harte Limits von echten Kapazitätsproblemen. Für klare Entscheidungen hilft mir die 15-Minuten-Kurve als Trendanker.

Shared Hosting, Nachbarn und versteckte Engpässe

In geteilten Umgebungen wirkt der Einfluss von Nachbarn oft stärker als die eigene App. Ich beobachte deshalb zusätzlich CPU-Steal, Ready-Zeiten und Storage-Contention, um fremde Last zu erkennen. Werden Kerne „gestohlen“, steigt der Load trotz eigener Optimierungen weiter an. Als Entscheidungsgrundlage nutze ich den Leitfaden zu CPU Steal Time und plane bei Bedarf dedizierte Ressourcen. So sichere ich planbare Performance statt in einem Engpass zu verharren.

Trends, Schwellen und Alarme richtig setzen

Ich kalibriere Schwellen pro Kern und setze Hysterese, damit Alarme nicht bei jeder Spitze feuern. Für 4 Kerne starte ich bei Alarmen etwa bei Load > 8 über mehrere Minuten und bestätige mit 15-Minuten-Trend. Wartungsfenster und Batch-Zeiten nehme ich aus der Bewertung heraus, damit Charts keine falschen Storys erzählen. Zusätzlich nutze ich Anomalie-Erkennung gegenüber dem eigenen historischen Median, statt harte Fixwerte zu verewigen. So reagiere ich früh auf echte Veränderungen, ohne das Team mit Fehlalarmen zu ermüden.

Wie Linux den Load wirklich zählt

Ich schaue bei Bedarf unter die Haube: Der Kernel mittelt die Länge der Run-Queue und zählt dabei nicht nur aktiv laufende Threads (State „R“), sondern auch solche in ununterbrechbarem Schlaf („D“, meist I/O‑Wartezustand). Genau das erklärt hohe Load-Werte bei niedriger CPU-Auslastung: viele Threads blockieren im Kernel auf langsame Disks, Netz- oder NFS-Zugriffe. In /proc/loadavg sehe ich die drei Durchschnitte und zusätzlich „laufende/gesamte“ Threads sowie die letzte PID. Zombies spielen dabei keine Rolle, dafür fließen Kernel-Threads und User-Threads gleichermaßen ein. Auf Systemen mit vielen kurzlebigen Tasks (Builds, Worker) springt der 1‑Minuten-Wert naturgemäß stärker, der 15‑Minuten-Wert bleibt mein Stabilitätsanker.

Wichtig ist für mich die Übersetzung von „Load“ zu „Wartezeit“: Liegt der Load deutlich oberhalb der Kernzahl, bilden sich Schlangen. Das muss nicht schlecht sein, wenn es sich um kurzlebige Jobs handelt, aber steigt gleichzeitig die Latenz von Anfragen, kippt das System in Überlast. Ich betrachte deshalb Load immer zusammen mit Laufzeit‑Metriken (Req-Latency, ttfb), um Warteschlangen nicht nur zahlen-, sondern wirkungsorientiert zu bewerten.

Speicherdruck, Swap und versteckte Blockaden

Konstante hohe Load-Werte sehe ich oft bei Speicherdruck. Wenn der Page Cache schrumpft oder kswapd Seiten schiebt, geraten Prozesse in Wartezustände. Swapping erzeugt I/O und bremst alles aus. Ich prüfe vmstat (si/so), Major Page Faults, /proc/meminfo (Cached, Dirty, Writeback) und beobachte, ob die I/O-Latenzen gleichzeitig steigen. Hoher Load bei moderater CPU% und zunehmender Disk-„await“ ist für mich ein klares Zeichen: RAM fehlt oder der Datensatz passt nicht in Cache.

Ich reagiere in Stufen: erst RAM-Hotspots identifizieren (z. B. große Sorts, ungecachte Queries, riesige PHP-Arrays), dann Caches stärken und vm.swappiness so einstellen, dass Arbeitsspeicher nicht zu früh verdrängt wird. Swap ganz abzuschalten ist selten klug – ein kleiner, schneller Swap (NVMe) mit disziplinierter Nutzung verhindert OOM-Killer-Peaks. Werden Writebacks zum Flaschenhals, entschärfe ich Sync-Wellen (Batching, Journaling-Optionen, asynchrone Flushes) und reduziere gleichzeitige Writer.

Container, Cgroups und CPU-Throttling

In Containern interpretiere ich Load mit Blick auf cgroups. CFS-Quotas begrenzen CPU-Zeit pro Periode; wird das Limit erreicht, zeigt der Container weiterhin hohe Load-Werte, obwohl er schlicht gedrosselt wird. Ich prüfe cpu.max (cgroup v2) bzw. cfs_quota_us/cfs_period_us (v1) und den Throttle-Zähler (cpu.stat). Steigt „throttled_time“ an, ist nicht fehlende Rechenleistung die Ursache, sondern harte Limits. In Kubernetes unterscheide ich strikt zwischen „Requests“ (Scheduling) und „Limits“ (Drosselung) – falsch gesetzte Limits erzeugen künstliche Warteschlangen.

Auch CPU-Affinität und NUMA beeinflussen das Bild: Werden Threads auf wenige Kerne gepinnt oder auf einem NUMA-Node geparkt, kann sich Load lokal stauen, während globale CPU% okay aussieht. Ich verteile Hot-Threads gezielt, prüfe IRQ-Balancing und achte darauf, dass Container nicht alle auf dieselben physischen Kerne gedrückt werden. So reduziere ich Wartezeiten ohne Hardware aufzurüsten.

Schnelle Entscheidungs-Checkliste

  • Load relativ zu Kernen bewerten (Load/Kerne ≈ 1 gut, ≫1 kritisch).
  • CPU% und I/O‑Wait dagegenlegen: rechnet die Kiste oder wartet sie?
  • 15‑Minuten-Trend prüfen: anhaltende Überlast vs. kurzer Peak.
  • Top-Prozesse und States (R/D/S/Z) ansehen; viele D‑States = I/O‑Engpass.
  • Disk-Latenzen, Queue Depth und %util messen; NFS/Netzpfade mitprüfen.
  • RAM: Page Faults, Swap-Aktivität, kswapd – Speicherdruck entschärfen.
  • Limits in Containern/VMs prüfen: Quotas, Shares, Steal, Throttling.
  • Concurrency drosseln: Worker/Threads, Queues, Backpressure.
  • Spitzen zeitlich verlagern: Cron, Backups, Indizes, ETL.
  • Nachjustieren, dann erneut messen – Wirkung vor Hardware.

Konkrete Tuning-Beispiele aus dem Hosting

Auf Web-/PHP-Stacks ist Concurrency der größte Hebel. Ich setze bei PHP‑FPM realistische pm.max_children, damit Requests nicht parallel die Datenbank überrennen. In nginx oder Apache begrenze ich gleichzeitige Upstream-Verbindungen, aktiviere Keep‑Alive sinnvoll und lasse statische Assets aggressiv cachen. Der OpCache verhindert Warmup-Stürme, während ein Object‑Cache (Redis/Memcached) Query-Last massiv reduziert.

Bei Datenbanken beginne ich mit Indexierung und Plans. Statt blind Connections zu erhöhen, nutze ich Connection-Pools und limitiere gleichzeitige teure Queries. Ich beobachte Buffer Pool Hitratios, Lock-Wartezeiten und Temp-Table‑Spills. Große Reports oder Migrationsjobs laufen asynchron und batchweise – lieber konstante 60% Load als 5 Minuten 200% und danach Stillstand.

Für speicherhungrige Runner (z. B. Bild-/Videoverarbeitung) definiere ich pro Host eine Obergrenze an gleichzeitigen Jobs. Ich setze nice und ionice, damit Batch-Prozesse interaktive Latenzen nicht zerstören. Auf schnellen NVMe-Disks halte ich die Scheduler-Konfiguration schlank, sorge für ausreichende Queue‑Depth und vermeide Chatty‑Syncs. So verschwinden D‑State-Lawinen, und der Load sinkt, ohne dass CPU% steigt – die Maschine wartet einfach weniger.

Build- und Batch-Workloads planvoll fahren

Beim Kompilieren oder Rendern korreliert Load stark mit der Job-Parallelität. Ich wähle -j bewusst: Kerne × (0,8–1,2) ist ein guter Start, doch ich beziehe RAM ein – lieber weniger parallele Jobs stabil, als Swap-Stürme mit Load-Spitzen. Artefakt-Caches, inkrementelle Builds und dedizierte I/O‑Volumes verhindern, dass D‑States durch viele kleine Dateien die Queue aufblähen.

Batch-Fenster plane ich belastungsarm. Rotationen, Backups, ETL und Reindexing laufen gestaffelt, nicht alles zur vollen Stunde. Workqueues erhalten Backpressure: Nur neue Jobs, wenn Slots frei sind, statt stumpf „Fire‑and‑Forget“. So bleiben Load und Latenzen kontrollierbar, und Peaks werden berechenbar.

PSI: Pressure Stall Information als Frühwarnsystem

Neben dem klassischen Load nutze ich die Pressure Stall Information (PSI) von Linux in /proc/pressure/cpu, .../io und .../memory. PSI zeigt, wie lange Tasks kollektiv warten mussten – ideal, um Überlast früh zu erkennen. Wenn die CPU‑Pressure über Minuten steigt, obwohl CPU% moderat ist, weiß ich: die Run‑Queue staut sich. Bei I/O‑Pressure sehe ich, ob Storage-Latenzen systemweit wirken, selbst wenn einzelne iotop-Werte harmlos aussehen.

Ich kombiniere PSI mit dem 15‑Minuten‑Load: Steigen beide, ist echte Sättigung da. Steigt nur Load, aber PSI bleibt ruhig, laufen möglicherweise viele kurze Jobs, die die Nutzer nicht spüren. Daraus entstehen sauberere Alarme und bessere Entscheidungen: Limits anheben, Jobs entzerren oder gezielt Hardware dort verstärken, wo Engpässe messbar sind.

Kurzer Überblick zum Mitnehmen

Ich lese den Load nie isoliert, sondern im Kontext von Kernen, I/O-Wait, CPU% und der 15-Minuten-Kurve. Hohe Werte deute ich erst nach Blick auf Storage- und Netzwerk-Latenzen, denn dort steckt häufig die eigentliche Bremse. Für Maßnahmen priorisiere ich sichtbare Wirkhebel: Queries, Caching, Worker, Limits – erst danach Hardware. In geteilten Umgebungen prüfe ich parasitäre Effekte wie Steal und plane bei Bedarf dedizierte Ressourcen. Mit diesen Regeln treffe ich ruhige, solide Entscheidungen und halte Hosting-Setups zuverlässig und schnell.

Aktuelle Artikel