Monolith vs. Microservices: Wann der Monolith in regulierten, On-Prem-Umgebungen gewinnt

Das reale Problem, nicht die Technologie
Wenn ein CTO in einer regulierten Branche ein neues System plant – etwa für eine Flottenintelligenz im Bahnumfeld, eine Plattform zur Vermessung oder ein Qualifikationssystem in der Luftfahrt –, steht nicht die Frage “Wie modern klingt der Stack?” im Vordergrund. Die eigentliche Herausforderung ist operativ: Wie halte ich das System über fünf bis zehn Jahre betriebssicher? Wie kontrolliere ich Datenflüsse unter DSGVO und Exportrestriktionen? Wie manage ich Updates in Fenstern von wenigen Stunden pro Quartal? Wie stelle ich deterministische Latenzen sicher, wenn Teile air-gapped laufen?

Microservices klingen dabei attraktiv, weil sie Skalierbarkeit und Teamautonomie versprechen. In vielen unserer Industrieprojekte schlagen die Rahmenbedingungen aber in die andere Richtung aus: Netzwerk und Betrieb sind die eigentlichen Engpässe, nicht horizontaler Durchsatz. Hier gewinnt ein modularer Monolith, weil er Komplexität dort reduziert, wo sie in der Praxis die größten Kosten verursacht – im Betrieb, im Debugging und in der Änderungskontrolle.

Ausgangsbedingungen in regulierten Industrien
Bevor wir über Architekturen sprechen, lohnt sich die nüchterne Beschreibung des Umfelds:

  • On-Premise, oft teilweise air-gapped: Kein durchgängiger Internetzugang, restriktive Firewalls, Proxy-Zwänge, keine US-Cloud-Abhängigkeit gewünscht oder erlaubt.
  • Langlebigkeit: Lebenszyklen von 7–15 Jahren sind keine Seltenheit. OS- und Datenbank-Upgrades sind planpflichtig und müssen rückrollbar sein.
  • Wartungsfenster und Change Management: Updates nur in definierten Fensterzeiten; konservative Freigabeprozesse, abgestufte Umgebungen (Labor, Pre-Prod, Prod).
  • Operative Ressourcen: Kleine Plattform-Teams mit breiter Verantwortung; kein 24/7 SRE-Team pro Subsystem.
  • Datenhoheit: Strikte Anforderungen an Auditierbarkeit, Reproduzierbarkeit, Backups und Restore-Testbarkeit.
  • Latenz- und Zuverlässigkeitsanforderungen: Teilweise harte Reaktionszeiten in der Peripherie (Edge), deterministische Pfade bevorzugt.

In diesem Kontext sind die wichtigsten Systemqualitäten nicht “elastische Skalierung bei Lastspitzen” oder “unabhängige Feature-Auslieferung im Tagesrhythmus”, sondern Beherrschbarkeit, Wartbarkeit und Risikoarmut über Jahre.

Die verkannte Kostenstruktur von Microservices in On-Prem-Setups
Microservices externalisieren Kopplung auf Netzwerkebene. Das erhöht Freiheitsgrade, bringt aber Kosten, die in On-Prem-Umgebungen selten sauber budgetiert werden:

  • Operative Oberfläche multipliziert sich:
  • Service Discovery, Ingress, Zertifikatsrotation, gehebelte Secrets-Verwaltung.
  • Versionierung und Kompatibilität zwischen Services, Schema-Evolution über Servicegrenzen.
  • Observability-Stack (Tracing, Metrics, Logs) wird Pflicht, nicht Kür. Ohne verteiltes Tracing sind Fehlerursachen in verteilten Flows kaum auffindbar.
  • Netzwerkrisiko wird dominierend:
  • Latenz-Varianz und Retries führen zu Tail-Latency, die im Labor nicht sichtbar ist.
  • Fehlerbilder sind probabilistisch: Timeouts, Partial Failures, Split-Brain-Verhalten bei Broker-Outages.
  • Datenkonsistenz wird fachlich:
  • Sagas, Outbox, Idempotenz, At-least-once-Zustellung – alles lösbar, aber mit erheblichem Design- und Testaufwand.
  • Audits werden schwieriger, wenn relevante Zustandsübergänge über mehrere Services verteilt sind.
  • Change Management fragmentiert:
  • Rollouts über N Services mit transaktiven Schemaänderungen setzen sorgfältige Kompatibilitätsstrategien voraus (expand/contract, read-compat-first).
  • Rollback wird heikel, wenn schon Nachbarsysteme neue Events gelesen haben.

Diese Punkte sind im Cloud-SaaS-Umfeld oft durch Werkzeuge, Plattformteams und geübte Praktiken abgefedert. On-Prem, besonders in regulierten Industrien, tragen Produktteams diese Last meist selbst. Das begrenzt die Netto-Kapazität für das eigentliche Fachproblem.

Wann der Monolith gewinnt – und warum
Die nüchterne Antwort in vielen Industrieprojekten: Der Monolith gewinnt, wenn er modular konstruiert ist und die reale Engpassstelle adressiert – den Betrieb.

Technische Gründe, die wir wiederholt gesehen haben:

  • Transaktionale Integrität über fachliche Grenzen:
  • Eine konsistente Datenbanktransaktion schlägt jede Saga, wenn der Fachprozess stark gekoppelt ist (z. B. Zustand einer Flotte, Sicherheits- oder Qualitätsfreigaben).
  • Latenz und Debuggability:
  • Funktionale Pfade bleiben in Prozessgrenzen. Debuggen, Profiler, deterministische Reproduzierbarkeit sind einfacher als in einem verteilten System.
  • Atomare Deployments und einfachere Rollbacks:
  • Ein Paket, eine Migrationskette, ein Health-Gate. Rollback ist einheitlich möglich, Backups/Restores testbar.
  • Ressourcenökonomie:
  • Ein Prozess mit internem Scheduling/Threadpools spart Overhead von N Runtimes, N HTTP-Stacks, N Containern und potenziellen Sidecars.
  • Geringerer Angriffs- und Fehlervektor:
  • Weniger Zertifikate, weniger Netzwerkflächen, weniger Cross-Service-ACLs; Security-Prüfungen konzentrieren sich.

Wichtig: “Monolith” heißt nicht “Big Ball of Mud”. In unseren Projekten reden wir von modularen Monolithen mit harten Modulgrenzen und expliziten Integrationspunkten. Es ist eine Architekturdisziplin, kein Schnellschuss.

Der modulare Monolith: Muster, die in der Praxis tragen
Ein modularer Monolith kann die gleichen organisatorischen Vorteile wie Microservices bieten, ohne das Netzwerk in die Mitte der Architektur zu stellen. Zentrale Bausteine:

  • Bounded Contexts als Module:
  • Fachliche Domänen (z. B. Flotte, Wartung, Diagnostik, Auth/Access) werden als klar abgegrenzte Module umgesetzt, jeweils mit eigener Datenzugriffsschicht (logisch getrennt, physisch in einer DB).
  • Modulgrenzen werden durch den Build- und Lint-Prozess erzwungen (keine Querverweise außerhalb definierter Schnittstellen).
  • Explizite Modul-APIs:
  • Interne, aber harte APIs (z. B. via Interface-Pakete), keine “Friendly Imports”.
  • Kommunikation synchron (Funktionsaufruf) und asynchron (interner Event-Bus) – jedoch in-proc.
  • Interner Event-Driven-Ansatz:
  • Domain Events innerhalb des Prozesses erlauben lose Kopplung und asynchrone Reaktionen, ohne Broker-Setup. Persistenz optional über Outbox, wenn Drittsysteme angebunden werden.
  • Migrationssicherheit:
  • Expand/Contract auch im Monolithen: Neue Felder/Tabellen zunächst schreibbar machen, Lesepfade beidseitig tolerieren, erst dann alte Pfade entfernen.
  • Test- und Release-Disziplin:
  • Modultests plus Integrationssuites, deterministische Testdaten, möglichst idempotente Migrationsskripte mit Dry-Run.
  • Packaging und Betrieb:
  • Ein ausführbares Paket mit modularem Plugin-System. Betrieb per systemd/Windows-Dienst, Container optional, aber nicht als Pflicht.

Architektur-Skizze für ein On-Prem/Edge-Szenario
Ein konkretes Muster, das sich bewährt hat: