Async API-Patterns: Wo Milan recht hat – und wo du als KMU früher aufhören kannst

Milan Jovanović erklärt präzise, wie man langlaufende API-Requests entkoppelt. Was er nicht zeigt: Wo du als Mittelständler mit zwei Entwicklern und ohne DevOps-Team aufhören solltest.

⚙ KI-Entwurf Dieser Beitrag wurde automatisiert generiert und nicht redaktionell freigegeben. Behandelt ihn entsprechend.

Letzten Dezember, Maschinenbauer aus Württemberg. 120 Mitarbeitende, ein interner Entwickler plus externer Dienstleister. Ihr Kundenportal hat eine Funktion: PDF-Export aller Bestellungen des letzten Jahres. Laufzeit je nach Kunde zwei bis acht Minuten. Kein Problem, solange ein Vertriebsmitarbeiter pro Tag auf den Button klickt.

Das Problem: Jahresabschluss. Alle 40 Außendienstler wollen gleichzeitig ihre Jahresübersicht. Das Portal bricht zusammen, der Hoster dreht der App den Hahn zu, der Chef ruft mich an. Klassisch. Was danach folgte, hat mich zu Milans Artikel geführt – der das technische Grundmuster für genau dieses Problem so sauber beschreibt, wie ich es selten gelesen habe.


Was Milan sagt

Milan Jovanović beschreibt eine Progression in vier Schritten. Schritt 0 ist das naive Blocking: Request rein, Arbeit passiert synchron, Antwort nach fünf Minuten. Schritt 1: Du nimmst die Arbeit an, legst sie in eine jobs-Tabelle, gibst sofort 202 Accepted mit einer Job-ID zurück, und ein Background-Prozess innerhalb derselben Applikation erledigt die Arbeit. Schritt 2: Du trennst den Worker vollständig vom API-Prozess, schaltest eine Queue dazwischen – RabbitMQ, Azure Service Bus – und bekommst damit Independent Scaling, Retry-Mechanismen und Dead-Letter-Queues quasi gratis. Am Ende benennt er Cloud-Alternativen (AWS SQS + Lambda, Azure Functions, Temporal) und ist fair genug zuzugeben, dass Schritt 2 echten Mehraufwand bedeutet und man nicht dorthin gehen soll, wenn der Schmerz es nicht rechtfertigt.

Der Artikel ist technisch präzise. Ich habe nichts daran auszusetzen. Was fehlt: die Entscheidungslogik, die mir in KMU-Mandaten täglich begegnet.


Wie das im Mittelstand wirklich landet

Von den KMU, mit denen ich in den letzten drei Jahren gearbeitet habe – Fertigungsbetriebe, Handelsunternehmen, Dienstleister – hatten etwa zwei Drittel genau das Problem, das Milan beschreibt. Langlaufende Reports, Bulk-Importe aus ERP-Systemen, Schnittstellenaufrufe zu Logistikpartnern, die gerne 90 Sekunden brauchen.

Bei fast allen war die richtige Antwort: Schritt 1. Sonst nichts.

Ein KMU mit 30 bis 300 Mitarbeitenden hat typischerweise ein IT-Team von einem bis vier Entwicklern. Keinen dedizierten DevOps-Engineer. Keinen Platform-Ingenieur. Oft niemanden, der Montag früh die Queue-Infrastruktur debuggt, wenn sie Samstagnacht Probleme gemacht hat. RabbitMQ selbst betreiben bedeutet: Installation, Updates, Monitoring, Alerting, Cluster-Konfiguration für Hochverfügbarkeit, Backup-Strategie. Ausgezeichnetes Tool. Aber es bedeutet einen neuen operativen Verantwortungsbereich für ein Team, das mit seiner eigentlichen Applikation bereits ausgelastet ist.

Das Gegenargument: "Dann nimmst du halt Azure Service Bus, managed, kein Betriebsaufwand." Stimmt teilweise. Wenn du ohnehin auf Azure bist und dein Team dort heimisch ist, ist das meine erste Empfehlung vor einem selbstgehosteten RabbitMQ. Aber auch dort: Azure Service Bus plus Azure Functions ist ein neuer Deployment-Stack, neue Observability-Anforderungen, neue Fehlerquellen. Ich habe erlebt, wie ein Entwickler drei Tage damit verbracht hat, die Verbindung zwischen einer Azure Function und dem Service Bus korrekt zu konfigurieren, weil sich der Managed-Identity-Setup in Staging anders verhielt als in Prod.

Die Jobs-Tabelle hingegen funktioniert mit dem, was das Team bereits kennt. Sie können hineinschauen mit einem SQL-Query. Sie können fehlerhafte Jobs manuell zurücksetzen. Sie sehen sofort, was hängt. Der operative Overhead ist nahe null.

Drei Dinge, die in Milans Artikel aus KMU-Sicht fehlen:

Erstens: der Unterschied zwischen Traffic-Spike und Spitzenlast. Der Maschinenbauer aus Württemberg hatte kein Problem mit fremden Concurrent Users – er hatte ein vorhersehbares Spitzenlast-Problem durch seine eigenen Leute zu einem bestimmten Zeitpunkt. Die Lösung war ein Rate-Limit auf dem Export-Button kombiniert mit Schritt 1. Drei Stunden Arbeit, kein neues Infrastruktur-Stück.

Zweitens: Hangfire. In .NET-Projekten ist Hangfire das, womit ich Schritt 1 in 90% der Fälle umsetze. Jobs-Tabelle ist drin, Dashboard ist drin, Retry-Mechanismus ist drin, der Job-Status per UI sichtbar. Setup: ein NuGet-Package und zehn Zeilen Code. Milan erwähnt es nicht, weil sein Artikel absichtlich generisch bleibt – ich sage es trotzdem, weil es für .NET-KMU der direkteste Weg ist.

Drittens: Idempotenz. Milan benennt sie korrekt als Anforderung für Queue-Systeme, erklärt sie aber nicht. In Teams, die noch nie mit Queues gearbeitet haben, ist "at-least-once delivery" ein echtes konzeptionelles Problem. Ich habe erlebt, wie ein Bulk-Import zweimal verarbeitet wurde, weil der Worker nach dem Schreiben und vor dem Bestätigen abgestürzt ist. Folge: 4.000 doppelte Buchungen, drei Tage Bereinigung. Das erklärt sich nicht von selbst.


Mein Entscheidungsbaum für KMU-Projekte

Ein oder wenige Endpoints mit langem Laufzeit-Problem, .NET-Stack? → Hangfire, Schritt 1, fertig. Kein Queue-System.

Auf Azure, Team kennt sich dort aus, mehr als drei bis vier async Stellen im System? → Azure Service Bus plus Azure Functions, aber plane einen halben Sprint für den richtigen Setup ein. Nicht unterschätzen.

Selbstgehostetes Setup, kein Cloud-Vendor-Lock gewünscht? → RabbitMQ – aber nur, wenn du jemanden hast, der es betreibt. Kein Tool ohne Verantwortung.

Workflow, der Tage dauert, externe Genehmigungen braucht oder wiederaufnehmbar sein muss? → Temporal ist eine ernsthafte Überlegung, auch für KMU. Es löst Probleme, die mit einer Jobs-Tabelle schnell chaotisch werden.

Die meisten KMU-Projekte landen in Kategorie eins. Schritt 2 kommt dann, wenn Schritt 1 messbar an seine Grenzen stößt – und das passiert seltener, als man denkt. Wer vor dem Schmerz skaliert, skaliert seinen operativen Aufwand mit, nicht nur seinen Durchsatz.


Der vollständige Original-Beitrag von Milan Jovanović: How to Scale Long-Running API Requests

Wenn du gerade vor genau dieser Entscheidung stehst – Jobs-Tabelle oder Queue, Hangfire oder Azure Functions – und in dreißig Minuten Klartext willst, welche Stufe für euer konkretes Setup die richtige ist:

30 Min Klartext-Sparring

— Bernhard