MCP Engineering

Performance und Observability: SLOs über die ganze Kette

Ein Tool hat 200 Millisekunden p95 und die Nutzer warten trotzdem zwölf Sekunden: Vier serielle Calls, Modellrunden und Queueing fehlen in der Servermetrik. Optimiert wird die Kette, nicht ihr bequemster Einzelwert.

Lehrtext · 10 Abschnitte · zuletzt geprüft: 2026-09-05

Nutzer erleben Ketten, keine Einzelkomponenten

Eine MCP-Interaktion umfasst Hostplanung, Modellaufrufe, Discovery, Toolauswahl, Transport, Serverqueue, Backendzugriff, Ergebnisaufbereitung und möglicherweise eine weitere Modellrunde. Eine schnelle Serverfunktion garantiert daher keine schnelle Nutzerantwort. Performancearbeit beginnt mit einem End-to-End-Ziel und zerlegt erst danach das Budget auf einzelne Stationen. Sonst optimiert jedes Team seine lokale Metrik, während die Gesamtlatenz weiter wächst.

Nutzer-SLO
Zeit bis zu einer verwertbaren Antwort oder sichtbaren Zwischenentscheidung
Host
Planung, Kontextaufbau, Toolauswahl und Modellrunden
MCP-Grenze
Netzwerk, Serialisierung, Queue und Handler
Backend
Datenbank, fremde API, Rate Limit und Fachwirkung

Definiere für typische Journeys p50, p95 und Fehlerrate, nicht nur einen Durchschnitt. Ein kleiner Anteil sehr langsamer Calls prägt interaktive Systeme stark, weil mehrere Stationen hintereinander liegen. Ergänze Ergebnisqualität: Ein schneller leerer Response oder abgeschnittener Kontext erfüllt das Nutzerziel nicht. SLOs verbinden deshalb Dauer, Erfolg und fachlich verwertbares Ergebnis.

Erstelle ein Journey-Diagramm aus echten Traces und markiere jede Netzwerk- und Modellgrenze. Addiere nicht einfach p95-Werte einzelner Komponenten; ihre Verteilungen sind korreliert und die langsamste Station kann je Request wechseln. Messe deshalb End-to-End direkt und nutze Teilspans zur Erklärung. Segmentiere nach erfolgreichem Pfad, fachlichem Fehlschlag, MRTR-Runde und Retry. Ein Pfad mit zusätzlicher Nutzereingabe hat ein anderes Ziel als ein automatischer Read. Behalte außerdem Cold Starts und erste Discovery getrennt vom warmen Regelbetrieb. Sonst erscheinen seltene, aber für neue Nutzer zentrale Startprobleme nur als Ausreißer. Eine gemeinsame Definition von Start- und Endereignis verhindert, dass Host und Server unterschiedliche „Latenz“ berichten. Erst wenn dieselbe Nutzerreise in Dashboard, Lasttest und Releasevergleich gemeint ist, werden Budgets belastbar.

LeitfrageWelche Station verbraucht das verbleibende Nutzerbudget, und ist ihre Arbeit für das Endergebnis notwendig?

Latenzbudgets werden rückwärts verteilt

Beginne bei der maximal akzeptablen Nutzerzeit und reserviere Budget für Antwortdarstellung, letzte Modellrunde und Fehlerbehandlung. Der Rest verteilt sich auf Toolkette und Backends. Jede nachgelagerte Operation erhält die verbleibende Deadline statt einer neuen vollen Frist. Andernfalls kann ein Host mit 20-Sekunden-Ziel über drei interne Retries minutenlange Arbeit erzeugen, nachdem der Nutzer längst abgebrochen hat.

``text user_budget = 12s model_rounds = 2 x 3s tool_chain = 4s render_and_margin = 2s remaining_deadline = request_deadline - now ``

Serielle Calls addieren ihre Latenz. Parallelisierung hilft nur bei unabhängigen Aufgaben und erhöht gleichzeitig Concurrency. Prüfe, ob ein besser geschnittenes Tool mehrere kleine Round-Trips ersetzt oder ob ein Resource-Read wiederverwendbaren Kontext liefert. Kürzere Timeouts sind kein Performancegewinn, wenn sie gesunde Arbeit abbrechen und Retries auslösen. Messe Queuezeit, Ausführungszeit und Transportzeit getrennt.

Budgetiere auch Fehlerpfade. Ein schneller Primärversuch mit drei langen Retries kann das Nutzerziel stärker verletzen als ein einzelner langsamer Call. Jede Wiederholung verbraucht verbleibende Deadline, Concurrency und Downstreamquote. Der Host klassifiziert Fehler vor dem Retry: Schema- und Autorisierungsfehler sind stabil, fachliche Konflikte brauchen andere Parameter, kurzzeitige Transportfehler können mit Backoff erneut versucht werden, und ein verlorener Response eines wirkenden Calls verlangt Statusklärung. Messe Retry-Verstärkung als zusätzliche Requests pro ursprünglicher Absicht. Steigt sie unter Last, ist sie häufig Ursache statt Lösung der Sättigung. Setze ein gemeinsames Budget über Modellrunden, MRTR, Toolcalls und Statusprüfungen, damit keine Ebene lokal korrekt und insgesamt unbegrenzt wiederholt. Die Nutzeroberfläche zeigt dabei, ob weiter versucht, degradiert oder auf Entscheidung gewartet wird.

Trade-offGroße zusammengesetzte Tools sparen Round-Trips, koppeln aber Fehler, Rechte und Cachebarkeit; die fachliche Atomizität entscheidet.

Kontext ist Latenz-, Kosten- und Qualitätsbudget

Toolbeschreibungen, Resource-Inhalte und Ergebnisse konkurrieren mit Nutzerfrage und Arbeitsgedächtnis um Modellkontext. Mehr Daten erhöhen Übertragung, Tokenkosten und Inferenzzeit und können relevante Signale verdrängen. Ein Server liefert deshalb keine vorsorglichen Volltabellen, wenn eine Projektion, Zusammenfassung oder einzelne Resource genügt. Der Host begrenzt zusätzlich die Summe über alle Server und priorisiert nach Aufgabe und Herkunft.

  • Discovery: nur aktive, policy-erlaubte Capabilities in den Modellkontext.
  • Input: Referenzen und fachliche Parameter statt wiederholter Vollinhalte.
  • Output: Pagination, Projektion und strukturierte Kerndaten plus knapper Text.
  • History: veraltete Toolresultate verdichten oder entfernen, Herkunft erhalten.
  • Messung: Bytes und Tokens pro Server, Tool, Turn und erfolgreicher Aufgabe.

Ein Kontextbudget wird nicht pauschal pro Response, sondern pro Journey festgelegt. Ein Tool kann sein lokales Limit einhalten und zusammen mit sieben anderen die Modellgrenze überschreiten. Registriere erwartete und maximale Outputgröße im Produktkatalog, stoppe unbeschränkte Exporte und beobachte Truncation. Wird gekürzt, muss der Nutzer erkennen, dass das Ergebnis unvollständig ist; stilles Abschneiden erzeugt schnelle, aber falsche Antworten.

MerksatzDer beste Kontext ist die kleinste belegbare Datenmenge, die die nächste Entscheidung zuverlässig ermöglicht.

Concurrency-Limits schützen die gemeinsame Ressource

Agentische Hosts können in wenigen Sekunden viele parallele Toolaufrufe erzeugen. Ohne Grenze füllen sie Connection Pools, Workerqueues und Backendlimits; die Latenz steigt, Timeouts lösen Retries aus und verstärken die Überlast. Ein Server begrenzt gleichzeitig laufende Arbeit global und fair pro Principal, Tenant oder teurer Capability. Überzählige Arbeit wartet nur in einer begrenzten Queue oder wird mit handlungsleitendem Signal abgewiesen.

Request klassifizierenPrincipal- und Toolbudget prüfenBegrenzte Queue betretenDeadline vor Start erneut prüfenArbeit ausführenSlot garantiert freigeben

Fairness verhindert, dass ein einzelner Tenant die gesamte Kapazität belegt. Getrennte Pools schützen kurze interaktive Reads vor minutenlangen Exporten. Das Limit orientiert sich am knappsten Downstream, nicht an der Zahl verfügbarer Serverthreads. Beobachte aktive Arbeit, Queuezeit, Ablehnungen, Abbrüche und Auslastung gemeinsam. Eine dauerhaft volle Queue ist kein Puffer, sondern gespeicherte Latenz.

Admission Control unterscheidet Kostenklassen. Ein Metadaten-Read benötigt vielleicht einen Datenbankslot für Millisekunden; ein Export bindet Speicher, Netzwerk und Backendminuten. Gewichte Aufträge oder trenne Pools, statt alle Requests als identische Einheit zu zählen. Setze harte Obergrenzen für Payload, Laufzeit und parallele Child-Jobs. Ein abgebrochener Client muss seine reservierten Ressourcen zuverlässig freigeben; für nicht abbrechbare Backends bleibt der Slot bis zur tatsächlichen Beendigung belegt. Autoscaling reagiert verzögert und kann ein gemeinsam begrenztes Backend nicht vermehren. Verwende Hysterese, damit Replikate und Circuit Breaker nicht schwingen. Lasttests steigern Ankunftsrate schrittweise, beobachten den Knick in Queue und Tail-Latenz und bestätigen, dass Ablehnung vor Kollaps einsetzt. Fairness wird separat geprüft: Ein aggressiver Tenant darf die p95-Zeit anderer Nutzer nicht unverhältnismäßig verschlechtern.

BetriebsregelBackpressure muss vor Überlast wirken und dem Host sagen, ob und wann eine Wiederholung sinnvoll ist.

Caching braucht dieselbe Autorisierungsgrenze wie die Quelle

Caching spart Latenz und Backendlast, kann aber Daten zwischen Nutzern oder Tenants vermischen. Der Cachekey enthält die autorisierte Sicht: Server, Methode oder URI, normalisierte Argumente, Principal- oder Tenantbereich, relevante Scopes und Policyversion. Ein Tokenwert selbst gehört weder in Schlüssel noch Log. Bei jedem Treffer prüft der Host oder Server, ob die aktuelle Identität den gecachten Inhalt weiterhin sehen darf.

ttlMs
Serverhinweis zur Frische dieser konkreten Response
cacheScope
Vorgesehener Geltungsbereich, keine automatische Berechtigung
Invalidierung
Änderungssignal macht abhängige Einträge stale; Quelle wird erneut gelesen
Rechtewechsel
Aktuelle Policy gewinnt auch vor Ablauf des Daten-TTL

Listen werden seitenweise gecacht und erhalten keine implizite Konsistenz über alle Seiten. Sensible Tool-Ergebnisse sind oft gar nicht oder nur sehr kurz cachebar. Ein globaler Cache für öffentliche Schemas kann sinnvoll sein, ein globaler Cache für personalisierte Resources nicht. Messe Trefferquote zusammen mit Stale-Fehlern, Invalidierungsdauer und Cachegröße; eine hohe Hit Rate ist wertlos, wenn sie falsche Sicht ausliefert.

Kurzcheck

Ein Resource-Response ist noch laut TTL frisch, doch der Nutzer verlor inzwischen seine Rolle. Darf der Cache liefern?

  • Nein; aktuelle Autorisierung erneut prüfen und den Treffer bei fehlender Sicht verwerfen.
  • Ja; das TTL garantiert bis zum Ablauf dieselben Zugriffsrechte.
  • Ja, wenn der Tokenwert Teil des öffentlichen Cachekeys ist.

Treffer. Richtig. Frische und Berechtigung sind unabhängige Bedingungen.

Vertragsmetriken verbinden Technik und Fachziel

CPU und HTTP-Status erklären nicht, ob ein MCP-Vertrag funktioniert. Ergänze technische Signale um Vertragsmetriken: Discovery-Erfolg, Schemaablehnung, Tool-Ausführungsfehler, MRTR-Runden, deduplizierte Wiederholung, Cursorablauf, Subscription-Abbruch, Cancellation vor Wirkung und Outputvalidierung. Jede Metrik hat eine klare Einheit, zulässige Labels und einen Owner. Unbegrenzte Request-IDs oder Freitexte werden nie zu Labels.

Latenz
End-to-End und pro Station; Queue und Ausführung getrennt
Verfügbarkeit
Erfolgreiche, fachlich verwertbare Ergebnisse pro Capability
Korrektheit
Schema-, Autorisierungs- und Idempotenzverletzungen
Kosten
Toolcalls, Modellrunden, Tokens und Backendverbrauch pro Aufgabe
Sättigung
Concurrency, Queue, Poolauslastung und Ablehnungen

Ein SLO benötigt Nenner und Ausschlüsse. Zähle einen vom Nutzer abgebrochenen Request anders als einen internen Timeout, aber verstecke ihn nicht. Segmentiere nach Toolklasse und Serverversion, ohne personenbezogene Hochkardinalität zu erzeugen. Release-Gates vergleichen nicht nur Mittelwerte, sondern Tail-Latenz, Fehlertypen und Kosten pro erfolgreicher Aufgabe. So wird eine „Optimierung“ sichtbar, die lediglich mehr Fehler schnell zurückgibt.

Kontrolliere Label-Kardinalität schon im Instrumentierungsreview. Toolname und stabile Serverklasse sind begrenzt; Resource-URI, Request-ID, Nutzer-ID, Fehlertext und freie Modellantwort sind es nicht. Hochkardinale Werte gehören als redigierte Attribute in gesampelte Traces oder strukturierte Logs, nicht als Metriklabel. Lege Buckets anhand des SLO fest, damit Histogramme die entscheidende Schwelle auflösen. Zähler sind monoton und besitzen eindeutige Units. Dashboards zeigen Rate, Errors, Duration und Saturation zusammen, weil niedriger Durchsatz bei niedriger Latenz auch einen vollständigen Ausfall bedeuten kann. Alerts basieren auf Nutzerwirkung und Error-Budget-Verbrauch statt jeder einzelnen Ausnahme. Jeder Alarm verlinkt Runbook, Owner und relevante Trace-Suche. Teste Telemetrie bei Ausfall des Exporters: Der Datenpfad darf nicht blockieren, und verlorene Metriken müssen als eigene Lücke sichtbar sein.

MerksatzMesse den publizierten Vertrag und das Nutzerziel, nicht nur die bequemsten Infrastrukturzähler.

Korrelation erklärt eine verteilte Interaktion

Ein Incident verteilt sich über Host, Modell, MCP-Client, Server, Queue und Backend. Eine durchgängige Trace- oder Korrelationskennung verbindet Ereignisse, ohne den gesamten Payload zu kopieren. Jeder Span nennt Serveridentität, Methode oder Capability, Status, Dauer und relevante Fehlerklasse. Anwendungshandles und Tenantwerte werden pseudonymisiert oder gehasht, wenn Korrelation nötig ist. Tokens, Prompts und vollständige Ergebnisse bleiben draußen.

Host-Interaktion startenModellrunde korrelierenMCP-Request mit Server-ID markierenQueue und Handler messenDownstream-Call verknüpfenFachwirkung und Nutzerergebnis abschließen

Trace-Kontext ist untrusted Eingabe und darf keine Autorisierung steuern. Begrenze akzeptierte Header und überschreibe interne Attribute kontrolliert. Sampling erhält Fehler, langsame Ausreißer und riskante Wirkungen häufiger als Routine, ohne sensible Payloads einzuschalten. Logs ergänzen diskrete Ereignisse; Metriken zeigen Trends; Traces erklären einen einzelnen Pfad. Keine Signalart ersetzt die anderen vollständig.

Definiere einen kanonischen Endstatus pro Request und einen separaten Fachstatus pro wirkendem Vorgang. Ein Trace kann mit Timeout enden, während der Export später erfolgreich abgeschlossen wird. Diese Aussagen widersprechen sich nicht, solange Korrelation und Begriffe stimmen. Nach Cancellation folgt keine weitere MCP-Nachricht für die Request-ID; interne Spans dürfen die Klärung des Außeneffekts dennoch fortführen. Verknüpfe sie über einen Vorgangshandle, nicht durch Wiederverwendung eines offenen Requeststatus. Clock Skew und asynchrone Exporte erschweren Reihenfolgen; Ereigniszeit, Empfangszeit und stabile IDs helfen. Für Incident-Suche existieren vorbereitete Queries: alle Calls einer Serverversion, alle deduplizierten Wiederholungen, alle unbekannten Ausgänge und alle Policyablehnungen. So beginnt Analyse mit einer belegbaren Kette statt dem manuellen Zusammenkopieren widersprüchlicher Logs.

DatenschutzBeobachtbarkeit braucht Identitätskorrelation, nicht Identitätsinhalte; verwende minimale, zugriffsbeschränkte Referenzen.

Nutzerstatus und Telemetrie haben andere Adressaten

Der Nutzer braucht verständliche Aussagen zu seinem konkreten Vorgang: angenommen, läuft, benötigt Eingabe, abgeschlossen, abgebrochen oder Ausgang unbekannt. Betriebsteams brauchen aggregierte Latenzen, Queuezustände und Fehlerklassen. Ein interner Logstream ist keine UX, und eine Fortschrittsanzeige ist kein belastbarer Observability-Stack. Beide Pfade können denselben Vorgang korrelieren, haben aber andere Inhalte, Zugriffe und Aufbewahrung.

Nutzer
Fachstatus, relevante Menge, nächste Aktion und ehrliche Unsicherheit
Host
Requestzustand, Consent, Abbruch und sichtbarer Server
Betrieb
Metriken, Logs, Traces, SLO und Kapazität
Security
Policyentscheidungen, ungewöhnlicher Egress und manipulationsarme Wirkungsspur

Die aktuelle MCP-Revision besitzt keine allgemeine Progress-Utility im Core. Langläufer werden über Fachstatus, Ergebnis-Resources oder passende Streamingmuster modelliert. Der Host darf daher alte Progressannahmen nicht als universellen Rückkanal voraussetzen. Nach einem verlorenen Response zeigt die UI „Ausgang unbekannt“ und bietet Statusprüfung, statt aus fehlender Telemetrie einen Fehlschlag abzuleiten.

DesignregelJedes Signal nennt seinen Adressaten und die Entscheidung, die es ermöglichen soll.

SLOs steuern Degradation und Kapazität

Wenn das Fehlerbudget schmilzt, reagiert das System abgestuft. Es reduziert teure parallele Arbeit, verkleinert optionale Kontextmengen, deaktiviert erwiesen tote Capabilities und schützt Kernfunktionen mit reservierter Kapazität. Degradation darf keine Sicherheitsgrenzen abschalten. Ein globaler Cache ohne Principalbindung oder ein Bypass der Autorisierung ist keine Performanceoption. Ebenso wenig darf die UI einen partiellen Output als vollständig darstellen.

  • Warnen: steigende Queuezeit oder Tail-Latenz vor Nutzerfehlern erkennen.
  • Begrenzen: Admission Control und faire Budgets aktivieren.
  • Degradieren: optionale, klar markierte Arbeit reduzieren; Kernvertrag erhalten.
  • Isolieren: ausgefallenen Server oder Downstream aus aktiver Auswahl nehmen.
  • Erholen: mit begrenzten Probes und Hysterese zurückkehren, keine Retry-Welle erzeugen.

Kapazitätsplanung nutzt Ankunftsrate, Servicezeit, Parallelität und Headroom. Lasttests bilden agentische Bursts, große Payloads, langsame Backends und Cancellation ab. Prüfe, dass Slots bei Fehlern freigegeben werden und Queueeinträge ihre Deadline nicht überleben. Autoscaling hilft bei CPU-gebundener Arbeit, aber nicht automatisch bei einem begrenzten Backendpool. Der Engpass bestimmt das sichere Limit.

Trade-offHeadroom kostet im Normalbetrieb; fehlender Headroom verwandelt kleine Bursts in lange Warteschlangen und kaskadierende Retries.

Die Produktionsprobe misst Ergebnis und Ursache

Journey und SLO definierenLatenz- und Kontextbudget verteilenConcurrency und Cachegrenzen setzenVertragsmetriken instrumentierenKorrelation ohne Payloadleak prüfenLast und Teilausfälle injizierenDegradation und Erholung auswerten

Teste zwei Tenants parallel, einen heißen Cache, einen Rechtewechsel und ein langsames Backend. Erzeuge einen Burst aus Toolcalls, kappe einzelne Responses und breche laufende Requests ab. Danach müssen Fachwirkung, Nutzerstatus, Metrik, Log und Trace dieselbe Geschichte erzählen: welche Arbeit angenommen wurde, wo sie wartete, ob sie wirkte und warum sie endete. Kein Cache darf Sicht vermischen, kein Retry doppelt wirken und kein Label unkontrolliert wachsen.

  • Performance: Zeit und Tokens pro erfolgreicher Nutzeraufgabe.
  • Resilienz: begrenzte Queue, faire Concurrency und sichere Wiederholung.
  • Observability: korrelierte Vertragsmetriken statt Payloadkopien.
  • Betrieb: SLO-basierte Degradation mit erhaltener Autorisierung und Ehrlichkeit.

Lege vor dem Test erwartete Invarianten fest: kein Cross-Tenant-Cachetreffer, höchstens eine Fachwirkung pro Idempotency-Key, begrenzte Queue, kein Response nach Cancellation und vollständige Korrelation ohne Secret. Erzeuge dann eine Baseline und steigere Last, Payloadgröße und Backendlatenz einzeln, bevor du Kombinationen testest. Vergleiche nicht nur Durchsatz, sondern Error Budget, Tail-Latenz, Kosten und fachliche Korrektheit. Speichere Lastprofil, Serverstand und Konfiguration, damit Regressionen reproduzierbar sind. Nach dem Test wird geprüft, ob alle temporären Daten und Debugstufen entfernt wurden. Ein bestandener Test ohne auswertbare Telemetrie ist kein belastbarer Nachweis; umgekehrt ist perfekte Telemetrie kein Erfolg, wenn das Nutzer-SLO verfehlt oder die Autorisierungsgrenze unter Last umgangen wurde.

AusblickDas nächste Modul macht diese Szenarien zu systematischen, reproduzierbaren Vertrags-, Integrations-, Last- und Releaseprüfungen mit eindeutigen Gates, Verantwortlichen und überprüfbaren Befunden im tatsächlichen Produktionsbetrieb dauerhaft zuverlässig.

Jetzt anwenden

Diesen Stoff gibt es als Modul mit bewerteten Entscheidungs-Checks — dieselbe Einführung, danach die Übungen.

Zum Modul →
Quellen & Aktualität7 Primärquellen · zuletzt geprüft:
  1. 01modelcontextprotocol.io/specification/2026-07-28/architecture
  2. 02modelcontextprotocol.io/specification/2026-07-28/server/tools
  3. 03modelcontextprotocol.io/specification/2026-07-…er/utilities/caching
  4. 04modelcontextprotocol.io/specification/2026-07-…lities/subscriptions
  5. 05opentelemetry.io/docs/specs/otel
  6. 06sre.google/sre-book/service-level-objectives
  7. 07modelcontextprotocol.io/specification/2026-07-28/basic/authorization