Grundlagen

Coordinated Omission: was es ist und wie man es vermeidet

7 Min. Lesezeit

Coordinated Omission ist ein Messfehler: Ein Lastgenerator wartet auf jede langsame Antwort, bevor er die nächste Anfrage sendet, schickt also gerade dann weniger, wenn das System langsam ist, und erfasst zu wenige der schlechten Momente. Die Perzentile, die Sie danach ablesen, sehen deshalb besser aus als das, was die Nutzer erlebt haben. Sie vermeiden ihn, indem Sie Anfragen nach einem Zeitplan senden, der Antwortzeiten ignoriert, und jede Anfrage ab dem Moment messen, zu dem sie hätte rausgehen sollen.

Die Fakten zu den Tools stammen aus der Dokumentation oder dem Repository des jeweiligen Projekts, geprüft am 9. Oktober 2026.

ToolWas es bietetWas Sie prüfen sollten
wrk2Konstante Rate (-R), Latenz ab dem geplanten Sendezeitpunkt--u_latency zeigt zusätzlich die unkorrigierte Sicht
HdrHistogramZwei Methoden, die fehlende Messwerte auffüllenNur eine davon anwenden, nie beide
k6Arrival-Rate-ExecutorsDen Zähler dropped_iterations
GatlinginjectOpen-Schritte wie constantUsersPerSecDie Schritte stehen in injectOpen
Locustconstant_throughput taktet jeden NutzerDie erreichte Rate im Vergleich zum Ziel
JMeterOpen Model Thread Group (ab 5.5, experimentell)Eine normale Thread Group ist ein geschlossener Pool

Was ist Coordinated Omission?

Der Fehler entsteht, wenn die messende Seite keine Messwerte mehr erfasst, weil das System langsam ist, sodass genau die langsamen Messwerte fehlen. Zufällig verlorene Messwerte verschieben ein Perzentil kaum; gehen sie im Gleichschritt mit einer Verlangsamung verloren, verzerrt das alle Perzentile.

Der Name stammt von Gil Tene, dessen Beitrag auf einer Mailingliste von 2013 genau diese Grenze zieht. Er ist der ursprüngliche Autor von HdrHistogram, wrk2 liegt in seinem GitHub-Konto, und die Dokumentation beider Projekte erklärt den Effekt (geprüft am 9. Oktober 2026). Die k6-Dokumentation verwendet den Begriff für ein geschlossenes Lastmodell, das seine eigene Last drosselt, eine häufige Ursache. Unser Artikel zum offenen vs geschlossenen Lastmodell behandelt diese Wahl, hier geht es um die Messung.

Wie verbirgt ein Lasttest langsame Antworten?

Ein Generator mit geschlossener Schleife sendet die nächste Anfrage auf einer Verbindung erst, wenn die vorherige Antwort da ist. Dauert eine Antwort eine Sekunde, sendet diese Verbindung eine Sekunde lang nichts, und die Anfragen, die sie in dieser Zeit gesendet hätte, bekommen nie eine Antwortzeit.

Das README von wrk2 sagt das über das Modell von wrk, das jede Anfrage vom ersten gesendeten Byte bis zur vollständigen Antwort misst: Weil eine Verbindung erst nach einer Antwort sendet, stimmt sich der Generator mit dem Server ab und misst in Phasen hoher Latenz nicht (geprüft am 9. Oktober 2026).

Das README von HdrHistogram bietet ein Gedankenexperiment. Ein System, das alle 10 ms gemessen wird, antwortet 100 Sekunden lang in 1 ms und hängt dann 100 Sekunden lang, wobei ein einziger Messwert von 100 Sekunden entsteht. Das Roh-Histogramm zeigt etwa 99,99 % der Ergebnisse bei 1 ms oder darunter; korrigiert um die blockierten Messwerte ist es nur etwa die Hälfte.

Woran erkennen Sie Coordinated Omission in Ihren Ergebnissen?

Vergleichen Sie die gesendete Rate mit der geplanten. Ist die Anfragerate gefallen, während die Antwortzeiten stiegen, hat der Generator zurückgesteckt, und die langsame Phase ist unterrepräsentiert.

  • Die Last war als Nutzer oder Verbindungen ohne Rate definiert. Jede geschlossene Schleife kann den Fehler auslösen.
  • Die Anfragerate sinkt dort, wo die Antwortzeiten steigen. Ein Einbruch der Rate während einer Spitze heißt, dass Anfragen nie gesendet wurden.
  • Das Maximum stellt das 99. Perzentil weit in den Schatten. Ein paar riesige Messwerte zwischen Tausenden schnellen sind das Beispiel oben im Kleinen. Lesen Sie die gesamte Antwortzeitverteilung und denken Sie daran, dass sie nur gesendete Anfragen zählt.
  • Dem Lastgenerator fehlte CPU. LoadFocus dokumentiert, dass eine Engine nahe 100 % CPU nicht mit der eingestellten Rate senden kann, und die Ergebnisse zeigen eine Warnung zur Sättigung des Lastgenerators, wenn eine Engine in der Spitze 80 % CPU oder mehr erreicht hat.

Wie vermeidet wrk2 Coordinated Omission?

Es sendet mit konstanter Rate und misst jede Anfrage ab dem Zeitpunkt, zu dem sie laut Plan hätte rausgehen sollen. Eine Anfrage, die zu spät losgeht, weil ihre Verbindung belegt war, bekommt die Wartezeit angerechnet.

wrk2 ergänzt wrk um ein Raten-Argument (-R, Anfragen pro Sekunde insgesamt) und erfasst Latenzen in einem HdrHistogram. --u_latency fügt dem Bericht das unkorrigierte Histogramm hinzu, markiert mit CO, wie im Beispiel aus dem README:

wrk -t2 -c100 -d30s -R2000 --u_latency http://127.0.0.1:80/index.html

Im zweiten Beispiel des README machte eine Serverpause von 1,4 Sekunden während eines 30-Sekunden-Laufs das korrigierte 99. Perzentil 200-mal so groß wie das unkorrigierte. Das README nennt das Projekt außerdem experimentell und warnt, dass Läufe unter 10 bis 20 Sekunden womöglich nichts Brauchbares liefern (geprüft am 9. Oktober 2026). Unser Überblick über HTTP-Benchmark-Tools vergleicht wrk2 mit hey, oha und weiteren Tools.

Wie korrigiert HdrHistogram aufgezeichnete Latenzen?

Wenn Sie das Intervall kennen, in dem Anfragen rausgehen sollten, ergänzt es die Messwerte, die eine lange Antwort blockiert hat. Die Korrektur geht beim Aufzeichnen oder nachträglich an einer Kopie.

recordValueWithExpectedInterval zeichnet einen Wert auf und fügt, wenn er das Intervall übersteigt, Werte hinzu, die in Schritten dieses Intervalls kleiner werden. copyCorrectedForCoordinatedOmission liefert eine korrigierte Kopie eines fertigen Histogramms. Das JavaDoc nennt die beiden Methoden gegenseitig ausschließend (geprüft am 9. Oktober 2026).

// geplantes Intervall: 10 ms, Werte in Mikrosekunden
Histogram h = new Histogram(3);
h.recordValueWithExpectedInterval(latencyUs, 10_000);

// oder nach dem Lauf, an einem Roh-Histogramm:
Histogram fixed = raw.copyCorrectedForCoordinatedOmission(10_000);

Die Korrektur ist nur so gut wie das Intervall, das Sie übergeben. Sie passt also zu einem Generator, der in gleichmäßigem Takt senden sollte.

Wie gehen k6, Gatling, Locust und JMeter damit um?

k6, Gatling und JMeter können Arbeit nach einem Zeitplan starten, der nicht auf Antworten wartet. Locust taktet jeden Nutzer, kann aber keine zusätzlichen Nutzer starten, um eine Rate zu halten.

k6. In den Arrival-Rate-Executors starten Iterationen unabhängig von der Antwort des Systems, solange ein virtueller Benutzer frei ist. Ist keiner frei, überspringt k6 die Iteration und zählt sie in dropped_iterations, was spät im Test heißen kann, dass das System nachlässt (geprüft am 9. Oktober 2026). Eine verworfene Iteration hat keine Antwortzeit, also lesen Sie diesen Zähler neben den Perzentilen. Auf LoadFocus laufen Arrival-Rate-Szenarien von k6-Skripten mit einer festen Zahl von Nutzern, also als geschlossenes Modell. Führen Sie k6 selbst aus, wenn es gerade um die Ankunftsrate geht.

Gatling. Schritte wie constantUsersPerSec innerhalb von injectOpen starten neue virtuelle Benutzer mit fester Rate, ganz gleich, ob frühere schon fertig sind (geprüft am 9. Oktober 2026).

Locust. constant_throughput passt die Wartezeit jedes Nutzers so an, dass er eine Task höchstens eine bestimmte Zahl von Malen pro Sekunde ausführt. Laut Dokumentation kann die Wartezeit die Rate nur begrenzen und keine neuen Nutzer starten, und die API-Referenz ergänzt, dass nach einer Task, die ihr Intervall überzieht, keine Wartezeit folgt. Eine langsame Antwort verzögert diesen Nutzer also trotzdem (geprüft am 9. Oktober 2026).

JMeter. Eine Thread Group ist ein Pool von Threads in Schleifen, also eine geschlossene Schleife. JMeter 5.5 brachte die experimentelle Open Model Thread Group, die einem Zeitplan wie rate(1/sec) random_arrivals(2 min) folgt und laut Versionshinweisen bei Bedarf Threads erzeugt (geprüft am 9. Oktober 2026).

Beseitigt ein offenes Lastmodell Coordinated Omission?

Es beseitigt die Hauptursache, einen Generator, der vor dem Senden wartet. Zwei Lücken bleiben: Ein Generator, dem Nutzer oder CPU fehlen, fällt trotzdem hinter seinen Zeitplan zurück, und jeder Nutzer in einer mehrstufigen Nutzerreise wartet weiter auf seine eigenen Antworten.

Die erste Lücke zeigt sich als verworfene Iterationen oder als ausgelastete Engine; beides ist ein Grund, mit mehr Reserve neu zu testen. Die zweite steckt in den meisten HTTP-Tests: Das README von wrk2 hält fest, dass Senden ohne Warten nur bei nicht blockierenden Protokollen oder einer Anfrage pro Verbindung funktioniert, und deshalb korrigiert wrk2 stattdessen die Zeitmessung.

FAQ

Von wem stammt der Begriff Coordinated Omission? Gil Tene, der ursprüngliche Autor von HdrHistogram, dessen wrk2-Fork von wrk darauf ausgelegt ist, den Fehler zu vermeiden. Sein Beitrag von 2013 auf der Mailingliste mechanical-sympathy beschreibt ihn als ein Problem, das er so nennt.

Ist Coordinated Omission dasselbe wie ein geschlossenes Lastmodell? Die beiden hängen zusammen. Ein geschlossenes Modell ist eine häufige Ursache, weil jeder virtuelle Benutzer auf seine Antwort wartet, bevor er erneut sendet, und das README von wrk2 findet den Effekt auch in Monitoring-Code.

Sollte man jedes Latenz-Histogramm dafür korrigieren? Nur wenn Sie das Intervall kennen, in dem Anfragen geplant waren, denn HdrHistogram braucht es, um die fehlenden Messwerte aufzufüllen. Wenden Sie auf einen Datensatz eine der beiden Korrekturmethoden an, nie beide.

Weiterlesen


Die technischen Aussagen in diesem Artikel wurden nicht unabhängig geprüft.

LoadFocus team
Geschrieben vom LoadFocus-Team, den Leuten hinter einem Cloud-Lasttest-Dienst.