Ein wachsender B2B-Händler pflegt seinen Katalog nicht mehr von Hand: Artikel, Preise und Bestände liegen im ERP und wandern jede Nacht per Massenimport in den Shop und zurück. Genau dieser nächtliche Lauf scheitert erfahrungsgemäß am gleichen Punkt, sobald das Datenvolumen wächst, nämlich an den Rate-Limits des Cloud-ERP. Microsoft Dataverse etwa erlaubt 6.000 Requests (Microsoft Learn) je gleitendem Fünf-Minuten-Fenster; wer sie überschreitet, erhält HTTP 429 (RFC 6585) und einen abgebrochenen Teilimport. Das Ergebnis am Morgen sind widersprüchliche Preise, falsche Verfügbarkeiten und ein Datenstand, der von Hand nachgezogen werden muss. Dieser Beitrag zeigt, warum die Drosselung greift und wie Batching, eine bewusste Parallelitätssteuerung und sauberes Retry-After-Handling die Anbindung von Dynamics 365 und SAP an den Shop belastbar machen.
Das Wichtigste in Kürze
- Microsoft Dataverse begrenzt jeden Nutzer auf 6.000 Requests, 1.200 Sekunden kombinierte Ausführungszeit und 52 gleichzeitige Requests je 300-Sekunden-Fenster (Microsoft Learn). Wird eine Grenze erreicht, antwortet der Dienst mit HTTP 429 (RFC 6585).
- Der 429-Response trägt einen Retry-After-Header mit der Wartezeit in Sekunden (Microsoft Learn). Wer ihn ignoriert und sofort erneut sendet, verlängert die Drosselung, statt sie zu beenden.
- Batching bündelt viele Datensätze in wenige Requests: Ein OData-$batch fasst bis zu 1.000 Operationen zusammen (Microsoft Learn) und senkt so das Request-Volumen deutlich.
- Dynamics 365 Finance und Operations drosselt prioritätsbasiert; niedrig eingestufte Integrationen werden zuerst gebremst (Microsoft Learn). SAP veröffentlicht keinen einheitlichen Grenzwert, sondern drosselt je API und Mandant (SAP Knowledge Base).
- Gegen abgebrochene Läufe helfen exponentielles Backoff mit Jitter (AWS), idempotente Schreibvorgänge und Wiederaufsetzpunkte, damit ein unterbrochener Import ohne Dubletten fortsetzt.
Warum nächtliche Massenimporte an Rate-Limits scheitern
Der klassische Fehler ist ein Import, der so schnell sendet, wie er kann. Ein Skript liest 40.000 Artikel aus dem ERP und feuert für jeden einzeln einen Schreib-Request an die Cloud-Schnittstelle. In der Testumgebung mit wenigen hundert Datensätzen läuft das durch; im Produktivbetrieb mit dem vollen Katalog trifft es nach kurzer Zeit die Grenze. Cloud-ERP-Systeme schützen sich mit sogenannten Service-Protection-Limits davor, dass ein einzelner Mandant die geteilte Infrastruktur überlastet. Microsoft Dataverse begrenzt jeden Nutzer auf 6.000 Requests je Fünf-Minuten-Fenster von 300 Sekunden (Microsoft Learn). Ist die Zahl erreicht, kommt keine langsamere Antwort, sondern ein hartes HTTP 429 (RFC 6585): Der Request wird abgewiesen.
Das eigentliche Problem ist nicht das Limit selbst, sondern der Umgang damit. Ein Import ohne Fehlerbehandlung interpretiert die 429 als Absturz und bricht ab. Zurück bleibt ein halb übertragener Datenstand: Die ersten Tausend Preise sind aktualisiert, der Rest steht auf gestern. Bei einer Dynamics-365-Anbindung über OData und das Data Management Framework fällt das besonders auf, weil Preis- und Bestandsdaten eng zusammenhängen. Wer stattdessen das Limit einplant, verwandelt es von einer Fehlerquelle in einen kalkulierbaren Takt: Der Import dauert etwas länger, läuft aber vollständig und wiederholbar durch.
Was ein Service-Protection-Limit konkret bedeutet
Ein Service-Protection-Limit ist kein einzelner Schwellenwert, sondern ein Bündel aus mehreren Grenzen, die parallel gelten. Bei Microsoft Dataverse sind es drei: die Zahl der Requests, die kombinierte Ausführungszeit und die Zahl gleichzeitiger Verbindungen. Alle drei werden über ein gleitendes Fenster von 300 Sekunden gemessen (Microsoft Learn). Es genügt, eine der drei Grenzen zu erreichen, um gedrosselt zu werden. Gerade die Ausführungszeit wird oft übersehen: Selbst wenige, aber sehr rechenintensive Requests können die 1.200 Sekunden kombinierte Ausführungszeit je Fenster (Microsoft Learn) ausschöpfen, lange bevor die reine Request-Zahl kritisch wird.
Request-Zahl
6.000 Requests je 300-Sekunden-Fenster in Dataverse (Microsoft Learn). Jeder Lese- und Schreibvorgang zählt einzeln mit.
Ausführungszeit
1.200 Sekunden kombinierte Ausführungszeit je Fenster (Microsoft Learn). Schwere Abfragen zehren daran besonders.
Parallelität
52 gleichzeitige Requests als Obergrenze (Microsoft Learn). Mehr parallele Verbindungen lösen sofort 429-Antworten aus.
HTTP 429
Bei Überschreitung antwortet der Dienst mit 429 Too Many Requests (RFC 6585) und einem Retry-After-Header.
Prioritätsstufen
Dynamics 365 Finance und Operations drosselt nach Priorität; niedrig eingestufte Integrationen werden zuerst gebremst (Microsoft Learn).
Sinn des Limits
Die Grenzen schützen die geteilte Cloud-Infrastruktur vor Überlast durch einen einzelnen Mandanten und halten sie für alle stabil.
HTTP 429 und den Retry-After-Header richtig lesen
Der entscheidende Baustein steckt in der Antwort selbst. Zusammen mit dem Status 429 liefert der Dienst einen Retry-After-Header, der in Sekunden angibt, wie lange der Aufrufer warten soll, bevor er den Request erneut sendet (Microsoft Learn). Dieser Wert ist kein Richtwert, sondern eine Ansage des Servers. Ein robuster Import liest ihn aus, pausiert genau so lange und wiederholt erst dann. Wichtig: Wiederholte Requests werden nach Ablauf der Frist wie neue Anfragen behandelt und erhalten keine höhere Priorität (Microsoft Learn). Ein sofortiger, ungebremster Retry verschärft die Lage also nur.
Retry-After schlägt jede eigene Schätzung
sende Batch an Cloud-ERP
wenn Antwort == 429:
warte Retry-After Sekunden (aus Header)
wiederhole denselben Batch (idempotent)
sonst wenn Antwort == 5xx:
backoff = min(cap, basis * 2^versuch) + zufall(jitter)
warte backoff, wiederhole (max. 3 bis 5 Versuche)
sonst:
markiere Batch als übernommen
speichere WiederaufsetzpunktBatching: viele Datensätze, wenige Requests
Der wirksamste Hebel gegen die Request-Grenze ist, gar nicht erst so viele Requests zu erzeugen. Statt für jeden Artikel einen eigenen Aufruf zu senden, bündelt Batching viele Operationen in einen einzigen Request. Ein OData-$batch in Dataverse fasst bis zu 1.000 Einzeloperationen zusammen (Microsoft Learn). Aus 40.000 Einzel-Requests werden so 40 Batch-Requests, weit unter der Grenze von 6.000 je Fenster (Microsoft Learn). Das reduziert nicht nur die Zahl der Aufrufe, sondern auch den Protokoll-Overhead pro Datensatz. Wichtig ist, die Batchgröße zu testen: Zu große Batches erhöhen die Ausführungszeit je Request und können an die 1.200-Sekunden-Grenze (Microsoft Learn) stoßen.
- Batchgröße staffeln: Mit einer moderaten Größe starten und anhand von Ausführungszeit und Fehlerrate nach oben tasten, statt sofort das Maximum zu nutzen.
- Lese- und Schreibpfade trennen: Deltas zuerst lesen, dann gebündelt schreiben, damit nicht jeder Abgleich einen Vollimport auslöst.
- Nur Änderungen übertragen: Ein Delta-Sync überträgt geänderte Datensätze statt des gesamten Katalogs und hält das Volumen dauerhaft klein, die Grundlage jeder stabilen Warenwirtschaftsanbindung.
- Fehler je Operation auswerten: In einem Batch kann ein einzelner Datensatz scheitern; die Antwort muss pro Operation geprüft und nur der fehlerhafte Teil wiederholt werden.
Parallelität bewusst steuern
Mehr Parallelität klingt nach mehr Tempo, führt bei Cloud-ERPs aber schnell ins Gegenteil. Dataverse begrenzt die Zahl gleichzeitiger Requests auf 52 (Microsoft Learn); wer mit hundert parallelen Verbindungen anfährt, produziert sofort eine Welle von 429-Antworten. Sinnvoll ist eine feste, konservative Zahl paralleler Arbeiter, etwa vier bis acht, kombiniert mit einer Warteschlange, die neue Batches erst nachschiebt, wenn ein Arbeiter frei wird. So bleibt der Durchsatz hoch, ohne die Grenze zu reißen. Diese Steuerung gehört in eine Middleware zwischen ERP und Shop, nicht in jedes Skript einzeln.
Wird dennoch gedrosselt, sollte die Parallelität dynamisch nachgeben: Häufen sich 429-Antworten, reduziert der Import die Zahl aktiver Arbeiter, bis die Fehler abklingen, und erhöht sie danach vorsichtig wieder. Dieses adaptive Verhalten hält den Import im grünen Bereich, ohne dass jemand nachts eingreifen muss. Für Anbindungen mit mehreren Verkaufskanälen gilt dasselbe Prinzip kanalübergreifend, damit nicht Shop und Marktplatz gleichzeitig gegen dasselbe Limit laufen.
| Kriterium | Naiver Massenimport | Gedrosselter Import |
|---|---|---|
| Requests | Ein Request je Datensatz | Gebündelt per Batch, bis zu 1.000 je Aufruf |
| Parallelität | Unbegrenzt, oft über 52 gleichzeitig | Feste Arbeiterzahl mit Warteschlange |
| Reaktion auf 429 | Abbruch oder sofortiger Retry | Retry-After abwarten, dann wiederholen |
| Fehlerfall | Halber Datenstand, manuelle Nacharbeit | Wiederaufsetzen ab dem letzten Punkt |
| Ergebnis | Inkonsistente Preise und Bestände | Vollständige, konsistente Übernahme |
| Betrieb | Nächtliche Eingriffe nötig | Läuft unbeaufsichtigt durch |
Retry-After-Handling und Backoff mit Jitter
Nicht jeder Fehler ist eine 429. Für vorübergehende Server- und Netzwerkfehler, etwa den Status 5xx, fehlt ein Retry-After-Header, und der Import muss die Wartezeit selbst bestimmen. Bewährt hat sich exponentielles Backoff: Die Pause wächst mit jedem Versuch, typischerweise nach dem Muster Basis mal Zwei hoch Versuch, begrenzt durch eine Obergrenze (AWS). Ohne Zufallsanteil laufen allerdings alle wartenden Arbeiter synchron wieder los und erzeugen einen gemeinsamen Ansturm. Deshalb ergänzt man einen Jitter, also einen zufälligen Anteil, der die Wiederholungen zeitlich streut (AWS). Google Cloud aktiviert diesen Jitter in seinen Client-Bibliotheken standardmäßig (Google Cloud).
In der Praxis genügt eine überschaubare Zahl von Wiederholungen: Drei bis fünf Versuche je Batch fangen die meisten vorübergehenden Störungen ab (Google Cloud), während eine Obergrenze von etwa 10 bis 30 Sekunden je Pause verhindert, dass ein einzelner Batch den ganzen Lauf blockiert (Google Cloud). Für die 429 selbst gilt weiter der Vorrang des Retry-After-Headers; Backoff mit Jitter ist die Antwort auf alles, was der Server nicht mit einer konkreten Wartezeit quittiert. Beide Mechanismen gehören in dieselbe Wiederholungslogik und lassen sich in einer maßgeschneiderten Schnittstelle zentral konfigurieren.
Konsistenz sichern: Idempotenz und Wiederaufsetzpunkte
Wiederholungen sind nur dann harmlos, wenn ein zweimal gesendeter Datensatz nicht doppelt ankommt. Deshalb müssen Schreibvorgänge idempotent sein: Ein Upsert über einen fachlichen Schlüssel, etwa die Artikelnummer, legt den Datensatz an oder aktualisiert ihn, unabhängig davon, wie oft er gesendet wird. So kann ein nach einer 429 wiederholter Batch gefahrlos noch einmal laufen. Ergänzend speichert der Import nach jedem übernommenen Batch einen Wiederaufsetzpunkt. Bricht der Lauf ab, setzt er beim nächsten Start dort fort, statt von vorn zu beginnen.
Wie eng dieses Zusammenspiel aus Batch, Wiederholung und Wiederaufsetzpunkt sein muss, zeigt sich bei der Anbindung über die SAP Business One Service Layer, die Sitzungen und Transaktionen eigenständig verwaltet. Auch dort gilt: Ein Import, der seinen Fortschritt kennt und Schreibvorgänge idempotent hält, übersteht Drosselung und Verbindungsabbrüche ohne inkonsistenten Zwischenstand.
Ein Limit ist ein Takt, kein Hindernis
SAP und Dynamics im Vergleich
Die Grenzen unterscheiden sich je System, das Grundprinzip bleibt gleich. Microsoft Dataverse nennt seine Werte offen: 6.000 Requests, 1.200 Sekunden Ausführungszeit und 52 gleichzeitige Requests je Fenster (Microsoft Learn). Dynamics 365 Finance und Operations ergänzt eine prioritätsbasierte Drosselung, bei der niedrig eingestufte Integrationen zuerst gebremst werden und hoch eingestufte am längsten durchlaufen (Microsoft Learn). SAP dagegen veröffentlicht keinen einheitlichen globalen Grenzwert; die Drosselung greift je API und Mandant, und im Zweifel klärt ein Support-Vorgang den konkreten Wert (SAP Knowledge Base). Trotz Status 429 (RFC 6585) als gemeinsamem Signal lohnt es sich, die Anbindung an SAP und Dynamics jeweils auf das dokumentierte Verhalten des Zielsystems auszulegen.
Implementierung Schritt für Schritt
- Limits des Zielsystems erheben: Dokumentierte Grenzwerte von Dynamics 365 oder SAP sammeln und den nächtlichen Bedarf dagegen rechnen.
- Volumen messen: Zahl der Artikel, Preise und Bestandsbewegungen je Lauf ermitteln und den nötigen Durchsatz je Fenster ableiten.
- Batching einführen: Schreibvorgänge zu Batches bündeln und die Batchgröße anhand von Ausführungszeit und Fehlerrate einstellen.
- Retry-After- und Backoff-Logik ergänzen: 429 mit Retry-After respektieren, 5xx mit exponentiellem Backoff und Jitter wiederholen.
- Idempotenz und Wiederaufsetzpunkte sichern: Upserts über fachliche Schlüssel und gespeicherten Fortschritt, damit Wiederholungen keine Dubletten erzeugen.
- Überwachen: Drosselungsereignisse, Laufzeit und übertragene Datensätze protokollieren, um Batchgröße und Parallelität laufend nachzujustieren.
Ein Massenimport wird nicht dadurch schneller, dass er das Limit ignoriert, sondern dadurch, dass er es kennt und seinen Takt danach richtet.