Ein Monolith ist eine einzige deploybare Anwendung; Microservices zerlegen sie in kleine, unabhängig deployte Dienste, die über APIs kommunizieren. Die Debatte klingt nach Architektur, ist aber vor allem eine Organisationsfrage: Entscheidend ist, ob Teamstruktur, Domänenwissen und operative Reife die Aufteilung tragen können – denn die Aufteilung stellt immer eine Rechnung.
Das Wichtigste in Kürze
| Frage | Antwort |
|---|---|
| Monolith | Eine Codebasis, ein Deployment, Aufrufe im Prozess, eine Datenbank |
| Microservices | Viele Dienste, unabhängige Deployments, Netzwerkaufrufe, eine Datenbank pro Dienst |
| Die verborgene dritte Option | Der modulare Monolith – eine Deployment-Einheit, durchgesetzte interne Grenzen |
| Konsens-Standard | Monolithisch beginnen; aufteilen, wenn die Deployment-Koordination schmerzt, nicht vorher |
| Die Falle | Der verteilte Monolith – Microservice-Kosten bei Monolith-Kopplung |
Der Unterschied in einem Codebeispiel
Innerhalb eines Monolithen ist der Aufruf eines anderen Moduls ein Funktionsaufruf – schnell, atomar und ohne die Möglichkeit, halb zu scheitern:
// Monolith: Aufruf im Prozess – eine Transaktion, eine Fehlerdomäne
const receipt = await billing.chargeOrder(order.id);
// Microservices: Derselbe Aufruf geht übers Netzwerk – und nun gehören
// Timeouts, Retries, Teilausfälle und Eventual Consistency Ihnen
const res = await fetch('https://billing.internal/charge', {
method: 'POST',
body: JSON.stringify({ orderId: order.id }),
signal: AbortSignal.timeout(3000), // und wenn billing langsam ist?
});
if (!res.ok) await compensateOrder(order.id); // und wenn es halb geklappt hat?
Jeder Schmerzpunkt von Microservices steckt in diesen letzten drei Zeilen. Der verwaltete Mittelweg hält eigene Logik unabhängig deploybar, ohne Ihnen die Fehlerbehandlung aufzubürden – eine Funktion wird wie ein Dienst aufgerufen, läuft aber auf einer von der Plattform verwalteten Infrastruktur:
// JavaScript / Node.js — Back4app JS SDK
// One deployable unit of business logic, no service mesh required
const receipt = await Parse.Cloud.run('chargeOrder', { orderId: 'ord_481' });
console.log(`Charged: ${receipt.status}`); // Flutter / Dart — Back4app Flutter SDK
final function = ParseCloudFunction('chargeOrder');
final response =
await function.execute(parameters: {'orderId': 'ord_481'});
if (response.success) {
print('Charged: ${response.result['status']}');
} // iOS / Swift — Back4app Swift SDK
ParseCloud.callFunction("chargeOrder",
parameters: ["orderId": "ord_481"]) { result in
if case .success(let receipt) = result {
print("Charged: \(receipt)")
}
} // Android / Kotlin — Back4app Android SDK
val params = hashMapOf("orderId" to "ord_481")
ParseCloud.callFunctionInBackground<Map<String, Any>>("chargeOrder", params) { receipt, e ->
if (e == null) Log.d("Billing", "Charged: ${receipt["status"]}")
} Drei Formen, nicht zwei
Der maßgebliche Microservices-Artikel beschreibt das Ziel, MonolithFirst den Weg dorthin: Fast jedes erfolgreiche Microservices-System begann als Monolith, der zu groß wurde, und der modulare Monolith hält Ihnen die Option offen – erst die Grenzen, später das Netzwerk, und nur dort, wo es sich lohnt.
Microservices vs. Monolith: die praktischen Unterschiede
| Dimension | Monolith | Microservices |
|---|---|---|
| Deployment | Eine Einheit, ein Release-Zug | Unabhängig, pro Dienst |
| Skalierung | Die ganze Anwendung skaliert gemeinsam | Pro Dienst, dort, wo die Last tatsächlich anfällt |
| Aufrufe zwischen Teilen | Im Prozess, Nanosekunden | Netzwerk, Millisekunden plus Fehlerfälle |
| Datenkonsistenz | ACID-Transaktionen | Sagas und Eventual Consistency |
| Fehlerisolation | Ein Bug kann alles lahmlegen | Fehler bleiben eingegrenzt – wenn so entworfen |
| Wo die Komplexität liegt | Im Code | Im Betrieb |
| Passendes Team | Ein Team, bis ca. 10 Entwickler | Mehrere autonome Teams |
| Debugging | Ein Stacktrace | Distributed Tracing über Dienste hinweg |
| Kostenprofil | Eine Runtime, günstig | Infrastruktur pro Dienst + Observability + Plattform-Team |
Die schärfste Zeile dieser Tabelle ist die Frage, wo die Komplexität liegt: Ein aufgeteiltes System hat nicht weniger Komplexität – es verlagert sie aus der Codebasis ins Netzwerk, in die Deployment-Pipeline und auf das Dashboard um drei Uhr nachts.
Die Migration in beide Richtungen
Die bekannte Richtung: Eine große Video-Streaming-Plattform hat jahrelang ihren Monolithen in über tausend Dienste zerlegt und damit ein Skalierungsproblem gelöst, das sie tatsächlich hatte. Die Gegenrichtung ist neuer und ebenso lehrreich: Dieselbe Branche brachte einen Monitoring-Dienst hervor, der seine Serverless-Microservices wieder in einen einzigen Prozess zusammenführte und die Infrastrukturkosten um rund 90 % senkte – der Datentransfer zwischen den Teilen war der größte Kostenfaktor –, sowie Engineering-Teams, die mehr als hundert Dienste wieder zu einem konsolidierten, weil Testsuiten und Abhängigkeitsverwaltung nicht mehr beherrschbar waren. Beide Richtungen waren rational: Konstant ist, dass die Architektur dem gemessenen Problem folgte, nicht dem Trend.
Typische Anwendungsfälle
- Monolith: neue Produkte, kleine Teams, unklare Domänen – überall dort, wo Lerngeschwindigkeit wichtiger ist als Skalierungstheorie.
- Modularer Monolith: wachsende Produkte, die sich Optionen für später offenhalten wollen, ohne heute den Mehraufwand zu tragen; der Standard, den man verteidigen sollte.
- Microservices: viele Teams, die unabhängig ausliefern, Komponenten mit unterschiedlichem Skalierungsbedarf (Feed vs. Checkout), Organisationen, die schnelles Provisioning, Monitoring und Rufbereitschaft bereits beherrschen.
- Hybrid mit verwaltetem Backend: Standard-Features (Authentifizierung, Daten, Speicher) werden als Dienst bezogen, eigene Logik läuft als unabhängig deployte Funktionen – Autonomie wie bei Microservices zu Betriebskosten wie beim Monolithen.
Sollten Sie aufteilen? Eine Entscheidungsmatrix
| Bleiben Sie monolithisch, wenn … | Teilen Sie auf, wenn … |
|---|---|
| Das Team in einen Raum passt (< ca. 10 Entwickler) | 15–20+ Entwickler in mehreren Teams auf ein Release warten |
| Sich die Domänengrenzen noch monatlich verschieben | Die Grenzen seit Quartalen stabil sind |
| Transaktionen Ihre zentralen Workflows umspannen | Komponenten tatsächlich unabhängige Daten haben |
| Operative Reife = “wir deployen ab und zu” | Provisioning, Tracing und Rufbereitschaft bereits solide sind |
| Das Problem die Codequalität ist | Das Problem die Deployment-Koordination ist |
Wenn die linke Spalte auf Sie zutrifft, die rechte Sie aber reizt, ist der modulare Monolith der ehrliche Kompromiss – und wenn Sie aufgeteilt haben und jede Änderung drei Dienste berührt, haben Sie den verteilten Monolithen gebaut und sollten ohne falsche Scham wieder zusammenführen.
Grenzen und Trade-offs
- Monolith: Der Release-Zug wird langsamer, je mehr Teams es gibt; ein einziges Speicherleck ist ein Ausfall für alle; über Jahre gewachsene Verflechtungen lassen sich kaum herauslösen, wenn die Moduldisziplin nachlässt.
- Microservices: die “MicroservicePremium” – verteilte Transaktionen, Behandlung von Netzwerkfehlern, versionierte APIs zwischen Ihren eigenen Teams und ein Observability-Stack, der zu einem eigenen Budgetposten wird.
- Beide: Keines der beiden Modelle rettet eine schlecht modellierte Domäne. Service-Grenzen auf einem schlechten Modell erzeugen eine verteilte Version desselben Durcheinanders – mit Latenz.
- Die organisatorische Grenze ist real: Nach dem Gesetz von Conway liefern Sie Ihre Kommunikationsstruktur aus. Wer die Architektur umbaut, ohne die Teams umzubauen, landet zuverlässig beim Anti-Pattern.
Microservices und Monolith mit Back4app
Back4app ist eine Open-Source-Plattform für Backend as a Service (BaaS), die eine verwaltete Datenbank, automatisch generierte REST- und GraphQL-APIs, Authentifizierung, Dateispeicher und Serverless-Funktionen mit Cloud Code kombiniert. Sie verschiebt die Bedingungen der Debatte: Die üblichen 80 % des Backends müssen Sie gar nicht selbst entwerfen, und die individuellen 20 % laufen als Cloud-Code-Funktionen – jede unabhängig deploybar wie ein Microservice, keine mit Service Mesh, Datenbank pro Dienst oder Ops-Rotation. Teams, denen selbst das zu eng wird, behalten den Ausweg: Der Stack ist Open Source, sodass das spätere Herauslösen eines echten Dienstes bei funktionierenden Grenzen beginnt, nicht bei einer Neuentwicklung.
Häufige Fragen
Was ist besser, Microservices oder ein Monolith?
Keines von beiden, pauschal gesehen – sie optimieren unterschiedliche Dinge. Ein Monolith optimiert Einfachheit: eine Codebasis, ein Deployment, Aufrufe im selben Prozess, echte Datenbanktransaktionen. Microservices optimieren die Autonomie der Teams und unabhängige Skalierung – um den Preis der Komplexität verteilter Systeme. Entscheidend sind Teamgröße, Stabilität der Domäne und operative Reife, nicht Architekturmoden.
Sollte ein Startup Microservices verwenden?
Der breite Konsens in der Branche lautet: nein – beginnen Sie mit einem Monolithen. Das maßgebliche Argument aus Martin Fowlers Essay MonolithFirst: Fast jede erfolgreiche Microservices-Geschichte begann als Monolith, der zu groß wurde, während Systeme, die von Anfang an als Microservices gebaut wurden, sich schwertun. Sie ziehen die Service-Grenzen, bevor Sie die Domäne verstehen – also genau dann, wenn Sie sie falsch ziehen werden.
Was ist ein modularer Monolith?
Die bewusst unspektakuläre dritte Option: eine einzige deploybare Anwendung mit streng durchgesetzten internen Modulgrenzen. Sie behält die operative Einfachheit des Monolithen und schafft zugleich die Nahtstellen, die eine spätere Aufteilung möglich machen. Für die meisten Teams ist sie der empfohlene Standard, denn sauber geschnittene Module lassen sich später als Dienste herauslösen, ein verknoteter Monolith nicht.
Was ist ein verteilter Monolith?
Das Anti-Pattern, das das Schlechteste beider Welten vereint: physisch getrennte Dienste, die trotzdem gemeinsam geändert und deployt werden müssen – meist, weil die Grenzen falsch gezogen wurden oder die Dienste sich eine Datenbank teilen. Sie zahlen die Betriebskosten von Microservices (Netzwerkaufrufe, Orchestrierung, Observability) und behalten die Kopplung des Monolithen. Es ist die häufigste Folge einer verfrühten Aufteilung.
Wann sollte man einen Monolithen in Microservices aufteilen?
Wenn die Koordination der Deployments – nicht die Größe des Codes – zum Engpass wird: mehrere Teams, die auf denselben Release-Zug warten, Komponenten mit tatsächlich unterschiedlichem Skalierungsbedarf und Domänengrenzen, die sich nicht mehr verschieben. Praxiswerte aus der Branche: Unter etwa zehn Entwicklern ist ein Monolith fast immer richtig; ab fünfzehn und mehr Entwicklern in mehreren Teams beginnt sich die Aufteilung zu lohnen.
Wie gehen Microservices mit Datenkonsistenz um?
Mühsam – das ist die am wenigsten beworbene Kostenstelle. Jeder Dienst besitzt seine eigene Datenbank, sodass aus der ACID-Transaktion, die im Monolithen eine Zeile war, eine Saga wird: eine Folge lokaler Transaktionen mit kompensierenden Rollbacks, die in Eventual Consistency (letztendliche Konsistenz) mündet. Workflows, die wirklich atomare Änderungen über mehrere Dienste brauchen, sind ein Zeichen dafür, dass diese Dienste nie hätten getrennt werden sollen.
Was hat das Gesetz von Conway mit dieser Wahl zu tun?
Alles – Systeme spiegeln am Ende die Kommunikationsstruktur der Organisationen wider, die sie bauen. Microservices funktionieren, wenn kleine autonome Teams jeweils einen Dienst von Anfang bis Ende verantworten; die Architektur ist ebenso Organigramm wie Diagramm. Ein einzelnes kleines Team, das Microservices einführt, übernimmt den Koordinationsaufwand vieler Teams, ohne diese Teams zu haben.
Sind Unternehmen von Microservices zum Monolithen zurückgekehrt?
Ja, und die Fallstudien sind lehrreich. Das Monitoring-Team einer großen Videoplattform hat bekanntlich seine Serverless-Microservices wieder in einen einzigen Prozess zusammengeführt und die Infrastrukturkosten um etwa 90 % gesenkt – der Datentransfer zwischen den Teilen war der größte Kostenfaktor. Andere Engineering-Teams haben Hunderte Microservices wieder zu einem Dienst konsolidiert und nannten dafür ausufernde Tests und Abhängigkeiten. Die Lehre lautet nicht "Microservices sind falsch", sondern: Die Aufteilung muss ihren eigenen Mehraufwand wieder einspielen.