Eine Instanz pro Kunde – .NET, MSSQL und S3 weltweit skalieren
Eine Windows-VM mit IIS, ein MSSQL-Server, dazu S3 für die Dokumente – und das je Kunde einmal. Dieses Modell trägt erstaunlich weit. Es bricht auch nicht an der Last, sondern an drei berechenbaren Stellen: an den Lizenzkosten, an den Wartungsfenstern und an der Entfernung. Dieser Beitrag zeigt den Weg in vier Ausbaustufen – bis hin zu regionalen Zellen, also vollständigen, voneinander unabhängigen Kopien der ganzen Lösung, je eine pro Weltregion. Und er sagt dazu, welche Stufe die meisten Anbieter wirklich brauchen.
Das Wichtigste vorab
- Der Engpass ist selten die Last. Es sind Lizenzkosten je Kunde, Wartungsfenster mal N und die Laufzeit über Kontinente.
- Die Leitregel: Anwendung, Datenbank und Dokumente eines Mandanten gehören in dasselbe Rechenzentrum. Alles andere folgt daraus.
- Die Zahl, die das erklärt: 100 aufeinanderfolgende Abfragen kosten im eigenen Rechenzentrum rund 0,1 Sekunden – zwischen Frankfurt und Sydney rund 26.
- Was eine „Zelle“ ist: eine vollständige, in sich geschlossene Kopie der Lösung – eigene Web-Knoten, eigene Datenbank, eigener Dokumentspeicher, eigene Backups. Sie trägt eine fest gedeckelte Zahl an Mandanten und greift nie auf eine andere Zelle zu. Ist sie voll, baut man die nächste, statt sie größer zu machen. AWS nennt das eine Cell, Microsoft nennt dasselbe Muster Deployment Stamps.
- Vier Ausbaustufen – Stufe 0 ist der heutige Stand, danach folgen Trennen und Bündeln, die erste vollständige Zelle und mehrere Regionen mit Steuerebene. Die meisten brauchen Stufe 2, nicht Stufe 3.
- Zwei Fristen drängen: .NET 8 und .NET 9 verlieren am 10.11.2026 den Support, die Container-Basisimages auf Windows Server 2022 (ltsc2022) verlassen am 13.10.2026 den Mainstream-Support.
- Die teuerste Überraschung steckt in der SQL-Server-Lizenz, nicht in der Architektur.
Der Ausgangspunkt
Die Ausgangslage ist verbreiteter, als ihr Ruf vermuten lässt: Ein Softwarehaus betreibt eine webbasierte Fachanwendung auf .NET. Je Kunde gibt es eine eigene Instanz – eine Windows-VM mit IIS, dazu ein Microsoft-SQL-Server und ein S3-kompatibler Objektspeicher für die Dokumente. Jeder Kunde bekommt seinen eigenen Stack, seine eigene Datenbank, seine eigene Adresse.
Dieses Modell ist nicht rückständig, es ist eine bewusste Entscheidung mit echten Vorteilen. In der Sprache der SaaS-Architektur heißt es Silo: vollständige Trennung je Mandant. Daten können sich nicht vermischen, ein Kunde kann keinen anderen ausbremsen, Wiederherstellung und Löschung betreffen immer nur einen. Und wo ein Kunde eine Sonderlocke braucht, bekommt er sie. Genau deshalb verkaufen sich Silo-Installationen in regulierten Branchen so gut.
Der Preis dafür ist ebenso eindeutig – und er wird erst sichtbar, wenn aus zehn Kunden hundert werden und aus einem Land ein Dutzend.
Wo es zuerst bricht
Die Reihenfolge, in der dieses Modell in der Praxis reißt, ist bemerkenswert stabil. Sie hat wenig mit Rechenlast zu tun:
- Die Lizenzrechnung. Windows Server und SQL Server werden je Instanz fällig und die Mindestabnahme je Instanz kennt keinen kleinen Kunden. Ein Mandant mit fünf Nutzern kostet an Lizenz dasselbe wie einer mit fünfhundert.
- Das Wartungsfenster. Ein Sicherheitspatch ist nicht ein Vorgang, sondern N Vorgänge. Bei 40 Kunden in sechs Zeitzonen gibt es kein gemeinsames Fenster mehr – und jede Nacht gehört jemandem.
- Die Verfügbarkeit. Eine VM je Kunde heißt: ein Reboot ist ein Ausfall. Es gibt keinen zweiten Knoten, der übernimmt, und beim Datenbankserver auch keinen.
- Die Entfernung. Sobald Kunden auf anderen Kontinenten sitzen, wird die Anwendung zäh. Nicht wegen der Bandbreite, sondern wegen der Laufzeit – dazu gleich mehr.
- Das Recht. Irgendwann lässt sich ein Kunde vertraglich zusichern, wo seine Daten liegen. Ab da entscheidet nicht mehr die Technik, wo eine Instanz steht.
- Die Übersicht. Bei 20 Instanzen kennt man jede. Bei 200 weiß niemand mehr, welche Version wo läuft und welche Datenbank welchen Schemastand hat.
An der Reihenfolge hängt mehr, als es zunächst wirkt: Die ersten drei Punkte schlagen zu, bevor Geografie überhaupt eine Rolle spielt. Viele Anbieter halten ihr Problem deshalb für „wir müssen global werden“, während es tatsächlich lautet: „wir bekommen die Kunden, die wir schon haben, nicht mehr sauber beliefert.“ Das ist eine gute Nachricht, denn die Lösung dafür ist erheblich billiger als eine zweite Region.
Wichtig zur Einordnung: Keiner dieser Punkte verlangt, das Silo-Modell aufzugeben. Sie verlangen, es zu industrialisieren. Der Unterschied zwischen einem Anbieter mit 20 Instanzen und einem mit 2.000 ist selten die Architektur der Anwendung – es ist die Frage, ob die Instanz ein Produkt aus der Fertigung ist oder ein Einzelstück aus der Werkstatt.
Die Leitregel: Zusammengehöriges gehört zusammen
Vor allen Detailfragen steht eine einzige Regel, aus der sich fast alles Weitere ableitet:
Anwendung, Datenbank und Dokumentspeicher eines Mandanten liegen immer im selben Rechenzentrum.
Der Grund ist Arithmetik. Licht läuft im Glas mit rund 204.000 km/s – gut 68 Prozent der Vakuumlichtgeschwindigkeit. Das sind knapp 9,8 Millisekunden Umlaufzeit je 1.000 Kilometer Faserweg. Und Fasern folgen keiner Luftlinie: Gemessene Laufzeiten liegen typischerweise beim 1,5- bis 2-Fachen der Luftlinie. Von Frankfurt aus gemessen sind das rund 94 Millisekunden an die US-Ostküste, 166 nach Singapur, 197 nach São Paulo und 266 nach Sydney – und das über einen gut ausgebauten Anbieter-Backbone, also im günstigen Fall. Innerhalb Europas liegen die Werte bei 9 bis 16 Millisekunden. Diese Zahlen sind nicht verhandelbar – kein Anbieter, kein Protokoll und kein Budget schlägt die Physik.
Entscheidend ist, was eine Anwendung daraus macht. Fachanwendungen sind selten sparsam mit Roundtrips und die Verlangsamung ist exakt linear zur Umlaufzeit. Hundert aufeinanderfolgende Abfragen kosten im eigenen Rechenzentrum etwa eine Zehntelsekunde – dieselben hundert Abfragen zwischen Frankfurt und Sydney kosten rund 26 Sekunden. Und 100 ist keine böswillige Annahme: 400 Abfragen für eine einzige Listenansicht sind ein real dokumentierter Wert und der landet auf derselben Strecke bei knapp zwei Minuten. Der Grund für die Wucht dieses Effekts: Auf dem Entwicklerrechner liegt die Umlaufzeit bei etwa 0,05 Millisekunden, über den Kontinent bei 100 bis 266. Das ist ein Faktor von 2.000 bis 5.000 auf eine Konstante, die im Code nirgends auftaucht. Genau das ist der Punkt, an dem Kunden „die Software ist langsam“ melden und Entwickler im Profiler nichts finden.
Dazu kommt, was vor der ersten Nutzdatenübertragung passiert: Ein Verbindungsaufbau kostet drei bis fünf Umläufe. Eine kalte TLS-Verbindung über Sydney-Distanz verbrennt damit rund eine Sekunde, bevor das erste Byte fließt. Und selbst danach bremst TCP: Ein Megabyte braucht aus dem Startfenster heraus etwa sieben Umläufe – bei Sydney-Distanz knapp zwei Sekunden, an der US-Ostküste 0,7. Bandbreite hilft dagegen nicht. Nur die Umlaufzeit zählt.
Aus der Leitregel folgt die zweite Regel: Über weite Strecken wird nur einmal gesprochen. Der Browser redet über die Distanz mit dem nächstgelegenen Zugangspunkt, alles Weitere passiert lokal. Was über den Ozean geht, ist die fertige Antwort – nicht hundert einzelne SQL-Abfragen.
Was der Rand wirklich bringt – und was nicht
Ein Zugangspunkt nah beim Nutzer ist der wirksamste Einzelhebel gegen Entfernung, aber nicht aus dem Grund, den die meisten vermuten. Der Nutzen liegt nicht im Zwischenspeichern, sondern im Aufteilen der Verbindung: Der Edge nimmt die TLS-Verbindung entgegen, wickelt die drei bis fünf teuren Umläufe des Verbindungsaufbaus über die kurze Strecke ab und schickt die Anfrage dann über eine bereits offene, warme Verbindung zum Ursprung weiter. Aus fünf langen Umläufen werden fünf kurze plus einer.
Drei verbreitete Erwartungen an den Rand halten der Praxis dagegen nicht stand:
- „Das CDN cacht unsere Anwendung.“ Content-Delivery-Netze speichern HTML und JSON standardmäßig nicht zwischen. Und jede Antwort mit
Set-Cookieumgeht den Cache ohnehin. Eine angemeldete Fachanwendung hat ohne ausdrückliche Umkonfiguration nahezu keine Trefferquote. Was der Rand zuverlässig abnimmt, sind die statischen Bestandteile – und das ist bereits viel wert. - „
Varylöst das.“Vary: CookieundVary: Authorizationerzeugen je Header-Wert einen eigenen Cache-Eintrag. Sie verhindern das Zwischenspeichern, sie ermöglichen es nicht. - „Wir schwenken per DNS um.“ Die TTL ist beim Client nur ein Hinweis: Auflöser setzen eigene Unter- und Obergrenzen. Chromium etwa vergibt eine feste Lebensdauer von rund 60 Sekunden für alles, was vom Auflöser des Betriebssystems kommt – schlicht weil dieser gar keine TTL mitliefert. Eine sehr niedrige TTL garantiert deshalb kein schnelles Umschalten; eine DNS-gestützte Umschaltung zwischen Regionen kostet realistisch ein bis zwei Minuten sichtbaren Ausfall. Für schnelles Ausweichen ist Anycast das bessere Werkzeug.
Und ein Detail, das bei der Auswahl regelmäßig falsch angenommen wird: Nicht jeder als „global“ beworbene Dienst arbeitet mit Anycast. Es lohnt sich, das für den konkret eingesetzten Tarif zu prüfen, statt es der Produktseite zu glauben.
Vier Ausbaustufen
Der Weg von der Einzel-VM zur weltweiten Flotte lässt sich in vier Stufen zerlegen. Jede Stufe kauft ein konkretes Problem weg und kostet dafür konkrete Komplexität. Sie sind aufeinander aufgebaut, aber man muss nicht bis zum Ende gehen:
1.Trennen und bündeln
Der erste Schritt kostet am wenigsten und bringt am meisten: Die drei Schichten hören auf, gemeinsam auf einer Maschine zu wohnen. Aus „eine VM je Kunde“ werden ein Web-Pool, eine oder wenige SQL-Instanzen und ein Objektspeicher – und viele Mandanten teilen sich diese Bausteine.
Die Datenbanktrennung bleibt dabei erhalten: je Mandant eine Datenbank, aber viele Datenbanken auf einer Instanz. Das ist in der Praxis der beste Kompromiss aus Isolation und Stückkosten. Eine SQL-Server-Instanz trägt bis zu 32.767 Datenbanken – die Zahl der Mandanten ist also nie die Grenze. Die Grenze sind Arbeitsspeicher, Verbindungen und Wartbarkeit; sie liegt praktisch je nach Datenmenge irgendwo zwischen einigen Dutzend und einigen Hundert Mandanten je Instanz.
Was diese Stufe wegkauft:
- Stückkosten. Statt N Windows- und N SQL-Lizenzen zahlen Sie die Lizenz für den Pool. Bei kleinen Mandanten ist das der größte einzelne Hebel im ganzen Vorhaben.
- Wartungsfenster. Ein Patchlauf trifft eine Instanz, nicht vierzig.
- Sichtbarkeit. Es gibt einen Ort, an dem man nachsieht, wie es der Datenbankschicht geht.
Was es kostet: Ab jetzt gibt es Nachbarn. Ein Mandant mit einer entgleisten Abfrage kann andere spürbar bremsen. Die Gegenmittel sind vorhanden – Resource Governor, getrennte Ressourcenpools, harte Abfragezeitlimits – aber sie müssen von Anfang an gesetzt werden. Ab SQL Server 2025 steht der Resource Governor auch in der Standard-Edition zur Verfügung; zuvor war er Enterprise vorbehalten.
2.Die erste vollständige Zelle
Jetzt wird aus dem Pool eine belastbare Einheit – die erste vollständige Zelle: Web-Knoten, Datenbank, Objektspeicher, Backups und Überwachung als ein Paket, das für sich allein lauffähig ist. Die Abgeschlossenheit ist dabei kein Selbstzweck. Weil eine Zelle weder Datenbank noch Speicher mit einer anderen teilt und sie auch nicht aufruft, kann eine Störung in ihr die übrigen gar nicht erreichen – genau das unterscheidet sie von einem einfach nur größeren Server. Und weil alle Zellen gleich gebaut sind, ist die zweite kein neues Projekt mehr, sondern eine Wiederholung.
Konkret für diesen Stack bedeutet das:
- Zwei oder mehr IIS-Knoten hinter einem Lastverteiler. In reinen Microsoft-Umgebungen ist Application Request Routing (ARR) 3.0 weiterhin der aktuelle Stand und setzt das URL-Rewrite-Modul voraus. Wer ohnehin modernisiert, nimmt stattdessen YARP als Vordertür – ein Mandanten-Router ist damit wenige Zeilen Konfiguration.
- MSSQL mit einem Replikat in derselben Region, als Always-On-Verfügbarkeitsgruppe mit automatischer Übernahme.
- Backups mit Object Lock im Objektspeicher – unveränderlich, damit ein kompromittiertes Konto sie nicht mitlöschen kann.
- Eine Kapazitätsgrenze, die nicht geraten, sondern gemessen und dann verteidigt wird. AWS formuliert das streng: Die Kapazität einer Zelle muss als ausdrückliche, getestete und fachlich verständliche Zahl vorliegen – etwa „400 Mandanten“ oder „1.200 Anfragen je Sekunde“ – und durch Drosselung durchgesetzt werden.
Diese Stufe kauft das Wartungsfenster endgültig weg: Ein Knoten wird aus dem Verkehr genommen, aktualisiert und wieder aufgenommen, während die anderen weiterarbeiten. Sie kauft außerdem die Nacht zurück, in der bisher jemand einen Reboot begleitet hat.
Die Größe einer Zelle ist dabei eine Abwägung mit einer sehr einfachen Arithmetik: Der Schadensradius eines Ausfalls ist der Kehrwert der Zellenzahl. Zehn Zellen bedeuten, dass ein Totalausfall zehn Prozent der Kunden trifft, hundert Zellen ein Prozent. Kleinere Zellen begrenzen den Schaden und erhöhen den Verwaltungsaufwand – größere umgekehrt. Diese Zahl sollte man bewusst wählen, statt sie sich aus der Hardwaregröße ergeben zu lassen.
Microsofts eigene Vorgabe: Wer nach dem Zellenmuster baut, betreibt mindestens zwei Zellen. Eine einzelne Zelle ist keine Zelle, sondern eine normale Installation mit aufwendigerer Verwaltung – der ganze Nutzen des Musters entsteht erst dadurch, dass es eine zweite gibt: eine, auf die man ausweichen, in die man umziehen und auf der man zuerst ausrollen kann.
3.Mehrere Regionen und eine Steuerebene
Erst jetzt wird die Zelle vervielfältigt: eine in Europa, eine in Nordamerika, eine im asiatisch-pazifischen Raum. Jede ist eine eigenständige Kopie mit eigener Datenbank und eigenem Objektspeicher. Zwischen ihnen fließen keine Anwendungsdaten.
Global bleibt nur, was global bleiben muss – und das ist bewusst wenig:
| Baustein | Wo er lebt | Warum |
|---|---|---|
| Mandantenkatalog | global, in jede Region repliziert | Beantwortet nur: Welcher Mandant gehört zu welcher Zelle? Enthält keine Fachdaten. |
| Edge / WAF / TLS | global, Anycast | Nimmt die Anfrage nah beim Nutzer an und reicht sie über den Backbone weiter. |
| Bereitstellung & Überwachung | global | Ein Artefakt, viele Ziele; eine Flottensicht plus Sicht je Zelle. |
| Anwendung (IIS/.NET) | je Zelle | Muss neben der Datenbank stehen. |
| Datenbank (MSSQL) | je Zelle | Trägt die Fachdaten und die Residenzzusage. |
| Dokumente (S3) | je Zelle | Dieselbe Residenzzusage wie die Datenbank. |
| Backups | je Zelle, im selben Rechtsraum | Ein Backup, das die Region verlässt, hebt die Residenzzusage auf. |
Der Weg einer Anfrage ist damit festgelegt: Der Anycast-Zugangspunkt nimmt sie an, der Katalog beantwortet „Kunde → Region → Zelle“ und die Anfrage landet in der richtigen Zelle. AWS macht dazu eine harte Auflage, die man ernst nehmen sollte: Der Router ist die einzige Komponente mit gemeinsamem Zustand, er darf keine Fachlogik enthalten und die Datenebene muss weiterlaufen, wenn die Steuerebene ausfällt. Wenn der Mandantenkatalog nicht erreichbar ist, dürfen bestehende Sitzungen nicht stehen bleiben – deshalb gehört das Ergebnis der Zuordnung in ein Sitzungscookie und nicht in jede einzelne Anfrage.
Für die Zuordnung selbst gibt es zwei gängige Wege. Ein CNAME je Mandant
(kunde.app.example.com) erlaubt den Umzug zwischen Zellen ohne Adressänderung, erzeugt aber
DNS-Pflege je Kunde. Eine Wildcard je Region (*.eu.app.example.com) ist
betrieblich schlank, schreibt die Region aber in die Adresse – und macht damit genau den Umzug teuer, den
man später braucht. Wer sich für die Wildcard entscheidet, sollte den Umzugsweg von Anfang an mitplanen.
Die Grenze, an die fast jeder unvorbereitet läuft: Let's Encrypt stellt je registrierter Domain 50 neue Zertifikate in sieben Tagen aus – und zwar global über alle Konten hinweg. Wer je Mandant einen eigenen Hostnamen unter einer Domain vergibt, kann damit nicht mehr als rund 50 neue Mandanten pro Woche aufnehmen. Erneuerungen zählen nicht mit: Eine Bestellung mit genau derselben Namensmenge wie ein bereits ausgestelltes Zertifikat gilt als Erneuerung und ist vom Limit ausgenommen; über ARI koordinierte Erneuerungen sind sogar von allen Limits befreit. Den Bestand neu auszustellen geht also – gedeckelt ist die Aufnahme neuer Mandanten. Das ist kein Detail mehr, seit es Zertifikate mit sechs Tagen Laufzeit gibt. Wer schnell wachsen will, verteilt Mandanten über mehrere registrierte Domains oder setzt auf ein Wildcard-Zertifikat je Region.
Wann Sie diese Stufe nicht brauchen: Microsoft nennt eine praktische Untergrenze für eine echte Steuerebene bei etwa zehn Mandanten. Darunter ist die Mandantenliste schlicht Konfiguration und jede Automatisierung kostet mehr, als sie einspart. Und eine zweite Region rechnet sich erst, wenn Recht oder Entfernung sie erzwingen – sie verdoppelt Grundkosten, Rollout-Aufwand und Fehlerquellen.
Was die Anwendung lernen muss
Der schmerzhafteste Teil ist selten die Infrastruktur, sondern die Anwendung. Eine ASP.NET-Anwendung, die jahrelang allein auf einer Maschine lief, hat sich Gewohnheiten angeeignet, die mit einem zweiten Knoten sofort brechen. Die gute Nachricht: Es ist eine überschaubare, endliche Liste.
Zustand raus aus dem Prozess
Alles, was im Arbeitsspeicher eines Knotens liegt, ist ab dem zweiten Knoten falsch. Die Liste ist erfreulich endlich – und jede Zeile hat ein bekanntes Gegenmittel:
| Was bricht | Warum | Gegenmittel |
|---|---|---|
Sitzung im Prozess (InProc) | Die Voreinstellung; die Sitzung lebt im Arbeitsprozess und ist für jeden anderen Knoten unsichtbar. | Auslagern (SQL Server oder Redis) – besser: Sitzung ganz vermeiden. |
Statische Felder, IMemoryCache | Microsoft begrenzt IMemoryCache ausdrücklich auf einen Server oder auf Server mit Sitzungsbindung. | Verteilter Cache; bei HybridCache die Grenze kennen (siehe unten). |
Hochgeladene Dateien, erzeugte PDFs, App_Data | Liegen lokal und existieren auf dem Nachbarknoten nicht. | In den Objektspeicher. |
Geplante Aufgaben, BackgroundService-Schleifen | Laufen still auf jedem Knoten – der Nachtlauf passiert N-mal. | Eine koordinierende Jobverwaltung oder eine verteilte Sperre. |
Bei Hintergrundjobs lohnt der genaue Blick, weil sich die verbreiteten Bibliotheken unterschiedlich verhalten: Hangfire ist im Mehrknotenbetrieb ohne Zusatzarbeit sicher – die Knoten koordinieren sich über eine verteilte Sperre. Quartz.NET dagegen bildet nur mit dem datenbankgestützten Speicher einen Verbund, braucht dafür eindeutige Instanz-IDs und verlangt, dass die Uhren der Knoten auf eine Sekunde genau gehen. Und die schlichte Windows-Aufgabenplanung auf der VM ist im Verbund schlicht falsch: Sie führt jeden Lauf so oft aus, wie es Knoten gibt.
Die Schlüssel müssen überall gleich sein
Das ist der Klassiker, der Anwender mit „ich werde ständig ausgeloggt“ melden lässt. Unter .NET Framework
erzeugt die Voreinstellung AutoGenerate,IsolateApps auf jedem Server einen eigenen
Schlüssel – Cookies vom Knoten A sind auf Knoten B unbrauchbar. Der machineKey muss deshalb
explizit und identisch gesetzt werden:
<!-- The same key material must exist on every node of the farm -->
<machineKey validationKey="<64 hex bytes>"
decryptionKey="<32 hex bytes>"
validation="HMACSHA256" decryption="AES" />
<!-- Session state out of process; better still: no session state at all -->
<sessionState mode="SQLServer" allowCustomSqlDatabase="true"
sqlConnectionString="Data Source=sql-eu;Initial Catalog=AspState;…" />
Unter ASP.NET Core heißt dasselbe Thema Data Protection. Hier lauern zwei Fallen, die beide
lautlos zuschlagen. Erstens muss SetApplicationName() auf allen Knoten identisch sein.
Zweitens – und das ist die unangenehmere – schaltet das Festlegen eines Schlüsselspeichers die
Verschlüsselung der Schlüssel im Ruhezustand stillschweigend ab. Wer den Schlüsselbund
auslagert, muss den Schutz ausdrücklich wieder einschalten:
// Naming a key store silently disables encryption at rest — turn it back on.
builder.Services.AddDataProtection()
.SetApplicationName("acme-suite") // identical on every node
.PersistKeysToDbContext<KeyRingContext>()
.ProtectKeysWithCertificate(keyProtectionCert);
Stolperfalle: Wer den Schlüsselbund in Redis ablegt, ohne dort Persistenz zu konfigurieren, verliert bei jedem Redis-Neustart sämtliche Schlüssel – und damit jedes ausgestellte Cookie. Alle Nutzer sind gleichzeitig abgemeldet, ohne dass irgendetwas im Log nach einem Fehler aussieht. Ebenso wichtig: Das Sitzungscookie unter ASP.NET Core ist selbst mit dem Data-Protection-Schlüssel verschlüsselt. Ein gemeinsamer Sitzungsspeicher nützt deshalb nichts, solange der Schlüsselbund nicht ebenfalls geteilt wird – ein Fehler, der gerne als „Redis funktioniert nicht“ fehldiagnostiziert wird. Unter .NET Framework gilt zusätzlich: Auch die IIS-Anwendungspfade müssen auf allen Knoten gleich heißen.
Drei Dinge, die sich nicht wegkonfigurieren lassen
Nicht alles lässt sich wegkonfigurieren und es ist besser, das vorher zu wissen:
- SignalR und Blazor Server. Ein Redis-Backplane verteilt Nachrichten, aber es ersetzt die Sitzungsbindung nicht. Wer diese Techniken einsetzt, plant Sitzungsbindung ein oder baut den betroffenen Teil um.
HybridCacheab .NET 9. Der zweistufige Cache ist ein Gewinn, aber seine Invalidierung erreicht die erste Stufe – den Arbeitsspeicher – der anderen Knoten nicht. Für Daten, bei denen ein veralteter Wert schadet, ist er die falsche Wahl.- Lange laufende Verbindungen. Anycast ist beim Ausweichen stark, hat aber eine Schwäche bei zustandsbehafteten Verbindungen: Ändert sich die Route, landen die Pakete an einem Standort, der den Verbindungszustand nicht kennt – und die Sitzung stirbt. Das gilt für TCP und QUIC gleichermaßen; QUIC beendet sie über den Stateless Reset nur sauberer, statt sie hängen zu lassen. Lange stehende Verbindungen gehören deshalb so gebaut, dass ein Neuaufbau nicht weh tut.
Weniger reden, dafür sicherer
Über Distanz zählt jeder Roundtrip. Die wirksamsten Maßnahmen sind unspektakulär: N+1-Abfragen
im ORM beseitigen, Abfragen bündeln, Ergebnisse projizieren statt ganzer Entitäten und im
Zweifel eine gespeicherte Prozedur statt zehn Einzelabfragen. Dazu gehört unbedingt eine
Wiederholungsstrategie für flüchtige Fehler – mit dem wichtigen Vorbehalt, dass ein
automatischer Wiederholungsversuch bei nicht idempotenten Befehlen einen Vorgang doppelt ausführen kann.
Schreibende Aufrufe brauchen deshalb einen Idempotenzschlüssel, bevor man die Wiederholung einschaltet.
Zeit, Sprache und Zahlen
Sobald Kunden weltweit sitzen, wird jede lokale Zeitangabe zur Fehlerquelle. Zeitstempel gehören in UTC in die Datenbank, die Umrechnung in die Zeitzone des Mandanten passiert in der Darstellung. Dasselbe gilt für Zahlen- und Datumsformate: Der Server hat keine Kultur, die Anfrage hat eine.
Die Portierung ist keine Vorbedingung
Ein verbreiteter Denkfehler lautet: „Erst modernisieren, dann skalieren.“ Das Gegenteil stimmt. Eine Anwendung auf .NET Framework 4.8 kann alles oben Genannte – Web-Pool, Zelle, mehrere Regionen –, sobald Zustand und Schlüssel geordnet sind. .NET Framework 4.8 und 4.8.1 haben kein Enddatum: Sie sind Bestandteil von Windows und werden so lange gepflegt wie das Betriebssystem darunter.
Die Portierung lohnt sich trotzdem, nur aus anderen Gründen – Linux-Container statt Windows-Images, geringere Betriebskosten, ein aktueller Laufzeitunterbau. Sie läuft schrittweise nach dem Muster der Würgefeige: ein YARP-Reverse-Proxy davor, die System.Web-Adapter dazwischen und Modul für Modul wandert auf modernes .NET, während der Rest weiterläuft. Zwei Punkte gehören dabei ehrlich benannt: ASP.NET Web Forms hat keinen Migrationspfad und wird auch keinen bekommen; serverseitiges WCF existiert in modernem .NET nur über das Nachfolgeprojekt CoreWCF. Der frühere .NET Upgrade Assistant ist inzwischen abgekündigt; Microsoft verweist auf den Modernisierungs-Agenten in Visual Studio.
Zwei Fristen, die jetzt drängen: .NET 8 und .NET 9 verlieren beide am 10. November 2026 den Support – .NET 10 ist die LTS-Version mit Laufzeit bis zum 14. November 2028. Und die Container-Basisimages auf Windows Server 2022 (ltsc2022) verlassen am 13. Oktober 2026 den Mainstream-Support; wer Windows-Container fährt, plant den Wechsel auf ltsc2025 ein. Wer über Jahre je Kunde eine VM ausgerollt hat, prüft außerdem die Altbestände: Windows Server 2016 endet am 12. Januar 2027 und für SQL Server 2016 ist der erweiterte Support bereits im Juli 2026 ausgelaufen. Wer heute auf .NET Framework 4.8 steht, ist von den .NET-Fristen nicht betroffen – ein weiteres Argument dafür, die Portierung nicht zur Vorbedingung der Skalierung zu machen.
Die Datenbankschicht
Hier entscheidet sich, ob das Vorhaben wirtschaftlich aufgeht. Die technischen Möglichkeiten sind reichhaltig, aber sie hängen an der Edition – und die Edition an der Rechnung.
Innerhalb einer Region: Verfügbarkeitsgruppen
Der Standardaufbau je Zelle ist eine Always-On-Verfügbarkeitsgruppe mit einem synchronen Replikat in derselben Region. Eine Verfügbarkeitsgruppe fasst bis zu neun Replikate, von denen mehrere synchron bestätigen dürfen – wie viele genau, hängt an Version und Edition; das gehört gegen den eingesetzten Build geprüft. Synchron heißt: Jede Bestätigung an die Anwendung wartet auf das Replikat. Das funktioniert nur bei kurzen Wegen. Microsoft nennt als Obergrenze für synchrone Replikation eine Umlaufzeit von unter etwa zwei Millisekunden – die Größenordnung zwischen Verfügbarkeitszonen einer Region, gemessen typischerweise 0,5 bis 1,5 Millisekunden. Über Kontinente ist synchrone Replikation ausgeschlossen; dort bleibt nur asynchron und asynchron heißt Datenverlust im Fehlerfall.
-- Reporting reads go to the secondary, writes stay on the primary.
ALTER AVAILABILITY GROUP [ag-eu-01]
MODIFY REPLICA ON N'SQL-EU-02' WITH (
SECONDARY_ROLE (
ALLOW_CONNECTIONS = READ_ONLY,
READ_ONLY_ROUTING_URL = N'TCP://sql-eu-02.internal:1433'
)
);
Zwischen Regionen: nur asynchron, nur manuell
Wer Zellen über Regionen hinweg koppeln will, landet bei verteilten Verfügbarkeitsgruppen. Man sollte wissen, was man damit bekommt – und was nicht: Sie unterstützen ausschließlich manuelle Übernahme, sie haben keinen eigenen Listener und das Read-Only-Routing greift nur auf der primären Seite. Microsoft empfiehlt für standortübergreifende verteilte Gruppen ausdrücklich asynchrone Bestätigung. Für Katastrophenvorsorge ist das ein gutes Werkzeug. Als Grundlage für „der Kunde arbeitet in beiden Regionen gleichzeitig“ taugt es nicht – und das ist der Grund, warum die Leitregel lautet, jeden Mandanten in genau einer Zelle zu führen.
Die Edition ist die eigentliche Architekturentscheidung
An dieser Stelle entstehen die teuersten Überraschungen. Die Standard-Edition kennt nur Basic Availability Groups und deren Grenzen passen denkbar schlecht zu einer Datenbank je Mandant:
| Merkmal | Standard (Basic AG) | Enterprise |
|---|---|---|
| Replikate je Gruppe | 2 | bis 9 (mehrere davon synchron) |
| Datenbanken je Gruppe | genau 1 | viele |
| Lesbares Sekundärreplikat | nein | ja |
| Backup auf dem Sekundärreplikat | nein | ja |
| Online- und fortsetzbare Indexoperationen | nein | ja |
„Genau eine Datenbank je Gruppe“ bedeutet bei 300 Mandanten 300 Verfügbarkeitsgruppen. Das ist technisch möglich und betrieblich eine Zumutung. Genauso schwer wiegt die letzte Zeile: Online- und fortsetzbare Indexoperationen sind genau die Werkzeuge, mit denen man Schemaänderungen über viele Mandantendatenbanken ohne Ausfall ausrollt – und sie sind Enterprise-Funktionen. Wer Hochverfügbarkeit über eine gebündelte Instanz braucht, rechnet also Enterprise ein oder wechselt auf einen verwalteten Datenbankdienst und kauft die Fähigkeit dort ein.
Zwei weitere Punkte gehören in dieselbe Rechnung. Passive Replikate sind nur mit Software Assurance frei – Lizenzen ohne SA tragen überhaupt keine Rechte für Hochverfügbarkeit oder Katastrophenvorsorge. Und die Kernlizenzierung hat eine Mindestabnahme von vier Kernlizenzen je physischem Prozessor beziehungsweise je virtueller Umgebung, verkauft in Zweierpaketen. Eine winzige VM je Kunde ist damit lizenzseitig nie winzig.
Nützlich für die Bündelung: Contained Availability Groups ab SQL Server 2022
replizieren Anmeldungen, Benutzer, Berechtigungen und Agent-Aufträge auf Ebene der Verfügbarkeitsgruppe
mit – über eigene, in der Gruppe enthaltene master- und msdb-Datenbanken. Damit
entfällt das leidige Nachziehen von Logins nach jedem Failover. SQL Server 2025 ergänzt sie um
Unterstützung in verteilten Verfügbarkeitsgruppen.
Schemaänderungen über viele Datenbanken
Bei einer Datenbank je Mandant wird jede Migration zu einer Flottenoperation. Zwei Regeln haben sich bewährt. Erstens: versionierte Migrationen statt eines Abgleichs zur Laufzeit – ob mit EF Core Migrations, DbUp oder Flyway, ist zweitrangig, wichtig ist, dass jede Datenbank ihren Stand kennt. Zweitens: erweitern, dann verengen. Eine Änderung wird in zwei Releases zerlegt – erst wird das Neue additiv hinzugefügt, sodass alte und neue Anwendungsversion gleichzeitig lauffähig sind, und erst im nächsten Release verschwindet das Alte. Nur so lässt sich eine Flotte ringweise ausrollen, ohne dass Anwendung und Schema auseinanderfallen.
Dokumente über S3
Der Objektspeicher ist in diesem Stack der pflegeleichteste Teil – wenn man drei Dinge richtig macht.
Dokumente laufen nicht über den Anwendungsserver
Der wichtigste Hebel: Der Web-Knoten stellt nur die Berechtigung aus, nicht das Dokument. Er erzeugt eine kurzlebige signierte URL, der Browser lädt damit direkt beim Objektspeicher hoch oder herunter. Der Anwendungsserver sieht die Datei nie, wird von großen Anhängen nicht ausgebremst und braucht keinen Speicherplatz dafür.
// The key prefix carries the tenant; it is never taken from user input.
var url = s3.GetPreSignedURL(new GetPreSignedUrlRequest
{
BucketName = cell.DocumentBucket,
Key = $"t/{tenantId}/{documentId}",
Verb = HttpVerb.GET,
Expires = DateTime.UtcNow.AddMinutes(5)
});
Zwei Details, die regelmäßig Zeit kosten: Signierte URLs erlauben zwar bis zu sieben Tage Gültigkeit, aber nur mit langlebigen Zugangsdaten – eine URL, die mit einer übernommenen Rolle (AssumeRole) signiert wurde, verfällt mit der Sitzung dieser Rolle, typischerweise nach einer Stunde und spätestens nach zwölf. Und das Signieren ersetzt nicht die CORS-Konfiguration: Die Signatur regelt die Berechtigung, die Same-Origin-Regel des Browsers bleibt davon unberührt.
Ein Bucket je Mandant oder ein gemeinsamer Bucket?
Beides ist vertretbar, die Grenze liegt weiter oben, als viele annehmen: Die Voreinstellung bei AWS liegt heute bei 10.000 Buckets je Konto und lässt sich auf bis zu eine Million anheben – ein Bucket je Mandant ist also lange tragfähig und hat den unschlagbaren Vorteil, dass Zugriffsrechte, Verschlüsselung und Aufbewahrung je Kunde nachweisbar getrennt sind. Ab einer wirklich großen Zahl von Mandanten empfiehlt AWS stattdessen Access Points oder einen gemeinsamen Bucket mit einem Präfix je Mandant, abgesichert über kurzlebige Zugangsdaten, die auf genau dieses Präfix beschränkt sind.
Der entscheidende Haken beim gemeinsamen Bucket: Object Lock und Lebenszyklusregeln wirken auf Bucket-Ebene. Object Lock im Compliance-Modus ist nicht zurücknehmbar und erzwingt Versionierung; Lebenszyklusregeln sind auf 1.000 je Bucket begrenzt. Wer je Kunde unterschiedliche Aufbewahrungs- oder Löschfristen zusagt, braucht getrennte Buckets – das ist kein Geschmacksurteil, sondern eine Produkteigenschaft.
Datenbank und Objektspeicher fallen auseinander
Ein Punkt, der fast immer unterschätzt wird: Der Objektspeicher nimmt an keiner Datenbanktransaktion teil. Ein Rollback in SQL macht ein bereits hochgeladenes Objekt nicht rückgängig und ein abgebrochener Upload hinterlässt eine Zeile ohne Datei. Der Ausweg ist ein zweistufiger Schreibvorgang – erst das Objekt unter einem vorläufigen Schlüssel, dann die Transaktion, dann die Bestätigung – ergänzt um einen regelmäßigen Aufräumlauf, der verwaiste Objekte und verwaiste Zeilen findet. Ein Outbox-Muster allein löst das nicht.
Dasselbe gilt eine Ebene höher für die Replikation zwischen Regionen. S3 ist seit Ende 2020 innerhalb einer Region unmittelbar konsistent – die Replikation in eine andere Region ist es nicht. Das sind zwei verschiedene Zusagen und sie werden gerne verwechselt. Wer eine Frist braucht, kauft sie über Replication Time Control; deren vertragliche Zusage lautet allerdings 99,9 Prozent der Objekte innerhalb von 15 Minuten, nicht 99,99. Wichtiger noch: Die Replikation überspringt stillschweigend eine ganze Reihe von Fällen – Objekte, die vor Anlegen der Regel existierten, gehören dazu. Genau daraus entsteht der Klassiker „das Dokument steht in der Datenbank, aber im Ausweichstandort fehlt es“.
Europäische und selbstbetriebene Alternativen
Wer den Objektspeicher nicht bei einem US-Hyperscaler halten will, hat inzwischen eine ernstzunehmende Auswahl: Scaleway und OVHcloud aus Frankreich, IONOS, Hetzner und STACKIT aus Deutschland, Exoscale aus der Schweiz. Wer selbst betreibt, kommt an Ceph mit dem RADOS Gateway kaum vorbei – dessen Multi-Site-Replikation ist die stärkste Antwort für regionsübergreifende Spiegelung im Eigenbetrieb und sie erlaubt seit einigen Versionen Synchronisationsregeln je Bucket. Damit lässt sich sauber abbilden, dass die Dokumente des einen Kunden Frankfurt nie verlassen, während die eines anderen zusätzlich nach Paris gespiegelt werden.
Bitte prüfen, wer noch MinIO einplant: Die quelloffene Community-Ausgabe von MinIO wird nicht mehr gepflegt – das öffentliche Repository ist archiviert und nur noch lesbar. Der Nachfolger AIStor ist ein kommerzielles Produkt, dessen kostenfreie Stufe auf einen einzelnen Knoten begrenzt ist und damit für einen verteilten, mandantenfähigen Betrieb ausscheidet. Wer MinIO im Bauplan hat, sollte diese Annahme jetzt überprüfen statt bei der nächsten Sicherheitslücke.
Datenresidenz: Wo Recht die Region erzwingt
Hier verlässt die Architektur die Technik. Drei Begriffe werden regelmäßig vermischt und meinen Verschiedenes:
- Datenresidenz – wo die Daten physisch gespeichert sind. Eine Zusage über Standorte.
- Datenlokalisierung – eine gesetzliche Pflicht, dass Daten das Land nicht verlassen. Eine Zusage reicht hier nicht, es braucht die Region.
- Datensouveränität – wessen Recht auf die Daten zugreifen kann. Das hängt am Betreiber, nicht am Standort: Ein US-Anbieter bleibt US-Recht unterworfen, auch wenn der Server in Frankfurt steht.
Für die Architektur ist die Unterscheidung praktisch, weil nur der mittlere Fall zwingend eine eigene Region verlangt. Die DSGVO selbst enthält keine Lokalisierungspflicht – sie beschränkt die Übermittlung in Drittländer (Kapitel V). „Wir speichern ausschließlich in der EU“ ist deshalb in aller Regel eine kaufmännische Zusage, keine gesetzliche Vorgabe. Was eine eigene Region wirklich erzwingt, verteilt sich auf vier Kategorien:
- Vertragliche Zusagen – der mit Abstand häufigste Grund. Verschärft wird das durch Aufsichtsrecht: DORA gilt seit dem 17. Januar 2025 und verlangt in jedem IKT-Vertrag mit einem europäischen Finanzunternehmen die namentliche Angabe der Datenstandorte samt Ausstiegsplan. Das ist faktisch ein Residenzgebot über den Vertrag.
- Sektorauflagen. In den USA ist nicht HIPAA der Auslöser – HIPAA kennt keine Residenzpflicht –, sondern FedRAMP: Dessen High-Baseline verlangt über Control SA-9(5), dass Verarbeitung und Speicherung in den USA, in US-Territorien oder unter US-Jurisdiktion bleiben; die Low- und Moderate-Baselines kennen keine solche Ortsvorgabe. Eine Pflicht zu US-Personal enthält FedRAMP dagegen ausdrücklich nicht – die stellt gegebenenfalls die einzelne Behörde in ihrer Ausschreibung.
- Echte Lokalisierungspflichten. Russland (152-FZ) verlangt, dass die primäre Datenbank mit personenbezogenen Daten russischer Bürger physisch in Russland steht. China schreibt Betreibern kritischer Infrastruktur und Verarbeitern oberhalb bestimmter Mengenschwellen die Speicherung im Inland vor. Indien hat mit der Zahlungsdatenvorgabe der Notenbank eine seit Jahren durchgesetzte Regel, während das allgemeine DPDP-Regime erst 2027 voll greift.
- Marktzugang. Für Festlandchina ist die entscheidende Hürde nicht der Datenschutz, sondern die ICP-Registrierung: Wer von Servern in China ausliefert, braucht eine chinesische Rechtsperson und eine Registrierung – ohne sie sperrt der Hoster die Seite. Dazu kommt die Einstufung nach MLPS. China ist damit keine weitere Zelle, sondern ein eigenes Markteintrittsprojekt.
Zwei verbreitete Annahmen sind überholt – wer sie im Bauplan hat, plant eine Region zu viel: Saudi-Arabien hat die strikte Lokalisierungsvorgabe aus dem Datenschutzgesetz durch ein Risikobewertungsverfahren ersetzt. Und die kanadische Provinz British Columbia hat ihre Speicherpflicht im Inland bereits 2021 aufgehoben; in Kanada steht nur noch die Regelung in Nova Scotia und auch die läuft aus.
Für den europäischen Teil hat sich die Lage zuletzt eher entspannt. Microsofts EU Data Boundary ist seit Anfang 2025 vollständig und AWS hat im Januar 2026 mit der European Sovereign Cloud eine rechtlich und betrieblich getrennte Partition mit erster Region in Brandenburg in Betrieb genommen. Das Vereinigte Königreich hat Ende 2025 eine erneuerte Angemessenheit bis Ende 2031 erhalten; für Norwegen und die übrigen EWR-Staaten gilt die DSGVO ohnehin, eine EU-Zelle genügt dort also. Und mit Brasilien besteht seit Anfang 2026 wechselseitige Angemessenheit. Umgekehrt ist die europäische Cloud-Zertifizierung EUCS weiterhin nicht verabschiedet – wer heute „souverän“ ausschreibt, arbeitet mit Vertragswerk und Nachweisen, nicht mit einem fertigen Siegel.
Ein Punkt betrifft die Kalkulation statt die Architektur: Der EU Data Act ist seit dem 12. September 2025 anwendbar und verbietet Cloud-Anbietern ab dem 12. Januar 2027 jedes Wechselentgelt – einschließlich der Ausgangsentgelte für die Datenmitnahme beim Wechsel. Die laufenden Nutzungsentgelte, also auch der normale Traffic-Preis im Betrieb, bleiben davon unberührt. Wer einen Anbieterwechsel oder den Umzug einer Zelle plant, sollte diesen Stichtag kennen.
Der am häufigsten übersehene Punkt: Die Residenzzusage gilt für alle Kopien. Ein Backup in einer anderen Region, ein zentral aggregiertes Protokoll mit personenbezogenen Feldern, ein Fehlerbericht mit Nutzdaten in einem Dienst außerhalb des Rechtsraums – jedes davon hebt die Zusage auf. Genau deshalb gehört in die globale Ebene ausschließlich Steuerung und niemals Kundendaten.
Betrieb der Flotte
Der Unterschied zwischen 20 und 200 Instanzen ist Betrieb, nicht Architektur. Vier Bereiche entscheiden.
Aufnahme neuer Mandanten
Ein neuer Kunde darf kein Projekt sein. Die Aufnahme ist ein Ablauf, der Datenbank, Speicherbereich, DNS-Eintrag, Zertifikat, Konfiguration und Katalogeintrag in einem Zug anlegt – wiederholbar, abbrechbar und mit einer ausdrücklichen Fehlerbehandlung je Schritt. Microsoft beschreibt die entscheidende Weichenstellung treffend als Wahl zwischen „Mandantenliste als Konfiguration“ und „Mandantenliste als Daten“. Erst die zweite Variante ergibt eine Steuerebene; die erste ist eine Textdatei, die irgendwann nicht mehr stimmt.
Die Gegenrichtung gehört zwingend dazu: Ein Kunde, der geht, muss nachweisbar verschwinden – Datenbank, Objekte, Backups, Protokolle, Katalogeintrag. Wer die Löschung nicht automatisiert hat, kann Art. 17 DSGVO nicht belastbar zusagen.
-- No business data lives here. Only: which tenant belongs to which cell.
CREATE TABLE dbo.TenantCatalog (
TenantId uniqueidentifier NOT NULL PRIMARY KEY,
HostName nvarchar(253) NOT NULL UNIQUE, -- kunde.app.example.com
CellId varchar(32) NOT NULL, -- eu-central-01
Residency varchar(8) NOT NULL, -- EU | US | APAC
Ring tinyint NOT NULL, -- 0 canary … 2 broad
Status varchar(16) NOT NULL -- active | migrating | suspended
);
Ausrollen in Ringen
Eine Flotte bekommt nie gleichzeitig dasselbe Release. Der Rollout läuft ringweise: zuerst eine Kanarien-Zelle mit internen oder besonders kooperativen Mandanten, dann eine schmale Welle, dann die Breite. Zwischen den Ringen steht eine Wartezeit, die lang genug ist, dass Fehler auffallen – meist mindestens ein voller Arbeitstag in der jeweiligen Zeitzone. Das setzt voraus, dass mehrere Anwendungsversionen mit demselben Schema arbeiten können, siehe „erweitern, dann verengen“ oben.
Für Windows-Flotten der wohl größte einzelne Betriebsgewinn dieses Jahres: Hotpatching über Azure Arc ist seit Mai 2026 kostenfrei und funktioniert unabhängig davon, wo die Server laufen, also auch auf eigener Hardware und bei fremden Hostern. Auf Windows Server 2025 werden damit acht von zwölf Monaten im Jahr neustartfrei. Wer heute je Kunde eine VM patcht, halbiert damit die Zahl der Wartungsfenster, ohne eine Zeile Architektur zu ändern.
Sehen, was los ist
Überwachung muss die Zelle kennen. Jede Metrik, jedes Protokoll und jeder Trace trägt Zelle und Mandant als Merkmal, es gibt ein Dashboard je Zelle und eine aggregierte Flottensicht darüber. Der Grund ist unangenehm einfach: Eine einzelne schlechte Zelle verschwindet im Durchschnitt der Flotte. Wer nur den Mittelwert sieht, erfährt vom Ausfall durch den Kunden.
Sicherung und Wiederherstellung je Mandant
Die entscheidende Fähigkeit ist nicht das Backup, sondern die Wiederherstellung eines einzelnen Mandanten, ohne die anderen anzufassen. Bei einer Datenbank je Mandant ist das elegant – ein Point-in-Time-Restore betrifft genau eine Datenbank. Beim Objektspeicher braucht es Versionierung und Object Lock, damit ein kompromittiertes Konto die Sicherungen nicht mitnimmt. Und es braucht die Übung: Ein Wiederherstellungsverfahren, das nie geprobt wurde, ist eine Annahme, kein Verfahren.
Die Lizenzrechnung
Am Ende entscheidet die Stückkostenrechnung, welche Stufe wirtschaftlich ist. Die Struktur ist bei diesem Stack immer dieselbe:
| Kostenblock | Silo (VM je Kunde) | Gebündelte Zelle |
|---|---|---|
| Windows-Server-Lizenz | je Kunde | je Knoten, geteilt |
| SQL-Server-Lizenz | je Kunde, mit Mindestabnahme je Umgebung | je Instanz, geteilt |
| Rechenleistung | bezahlt auch im Leerlauf | nach Spitzenlast der Summe, nicht der Summe der Spitzen |
| Betriebsaufwand | linear mit der Kundenzahl | weitgehend konstant je Zelle |
| Hochverfügbarkeit | je Kunde zu bezahlen | einmal je Zelle |
Die beiden Zeilen in der Mitte sind der eigentliche Hebel. Der Leerlauf ist im Silo-Modell die größte stille Ausgabe: Eine Instanz für einen Kunden mit acht Nutzern ist nachts, am Wochenende und in der Mittagspause vollständig unbeschäftigt und kostet trotzdem. Und „Spitzenlast der Summe“ schlägt „Summe der Spitzen“ schon bei einer Handvoll Mandanten deutlich, weil sich Lastspitzen über Kunden und Zeitzonen hinweg ausgleichen.
Zur Größenordnung auf der Lizenzseite, gerechnet mit den offenen Listenpreisen von SQL Server 2025: Ein Zweikernpaket kostet bei Standard rund 3.900 US-Dollar, bei Enterprise rund 15.100. Wegen der Mindestabnahme von vier Kernlizenzen je virtueller Umgebung schlägt selbst eine Zwei-Kern-VM je Kunde mit zwei Paketen zu Buche – also grob 7.900 US-Dollar je Kunde bei Standard und 30.000 bei Enterprise, noch ohne Windows Server, Rechenleistung, Speicher, Backup und Arbeitszeit. Multipliziert mit der Kundenzahl ist das fast immer der größte einzelne Posten des Vorhabens und der stärkste Grund, Stufe 1 überhaupt anzugehen.
Diese Zahlen sind Listenpreise und taugen zum Vergleich der Größenordnungen, nicht als Angebot. Wer Software als Dienst für Dritte betreibt, kauft in aller Regel nicht über die Preisliste, sondern über ein Mietmodell für Dienstanbieter oder stundenweise in der Cloud – dort sieht die Rechnung anders aus. Der entscheidende Punkt bleibt aber in jedem Modell derselbe: Die Mindestabnahme je Umgebung macht kleine Kunden überproportional teuer.
Rechnen Sie in Stückkosten je Mandant und Monat, nicht in Gesamtkosten. Erst diese Zahl macht sichtbar, welche Kundengröße sich im Silo überhaupt trägt – und ab welcher Größe eine eigene Zelle für einen einzelnen Großkunden wieder die richtige Antwort ist. Beides gleichzeitig anzubieten, ist kein Widerspruch: AWS nennt diese Mischung aus Silo und Pool das Bridge-Modell und behandelt sie als Normalfall, nicht als Kompromiss.
Entscheidungsrahmen
Sieben Fragen, die die Richtung meist schnell klären:
- Wie hoch sind unsere Stückkosten je Mandant und Monat – und wie stark hängen sie an Lizenzen statt an Rechenleistung?
- Wie viele Wartungsfenster haben wir im letzten Quartal koordiniert und wie viele Personenstunden hat das gekostet?
- Wie viele Roundtrips macht unsere häufigste Maske – und was ergibt diese Zahl mal 266 Millisekunden, also der Strecke Frankfurt–Sydney?
- Gibt es einen Kunden, dem wir eine Residenz vertraglich zugesagt haben, die wir technisch nicht erzwingen können?
- Können wir die Aufnahme und die vollständige Löschung eines Mandanten heute automatisiert durchführen?
- Wissen wir zu jedem Zeitpunkt, welche Anwendungs- und Schemaversion bei welchem Kunden läuft?
- Haben wir die Wiederherstellung eines einzelnen Mandanten jemals geprobt – oder nur das Backup geprüft?
Wer bei den ersten beiden Fragen zusammenzuckt, gehört auf Stufe 1. Wer bei Frage drei zusammenzuckt, braucht kürzere Wege, nicht zwingend eine zweite Region. Erst wenn Frage vier mit Ja beantwortet wird, steht Stufe 3 wirklich an.
Häufige Fragen
Muss die Anwendung erst auf modernes .NET portiert werden, bevor sie skalieren kann?
Nein. Der teuerste Fehler ist, die Portierung zur Vorbedingung zu machen. Eine ASP.NET-Anwendung auf .NET Framework 4.8 läuft in einem Web-Pool mit mehreren Knoten, sobald drei Dinge stimmen: identische machineKey-Werte auf allen Knoten, Session-State außerhalb des Prozesses und keine lokal abgelegten Dateien. Das sind Konfigurationsarbeiten von Tagen, keine Portierung von Monaten. Die Portierung auf modernes .NET lohnt sich getrennt davon – wegen Linux-Containern, Betriebskosten und Sicherheitsupdates – und lässt sich schrittweise über System.Web-Adapter und einen YARP-Reverse-Proxy machen, während die alte Anwendung weiterläuft.
Reicht SQL Server Standard, wenn jeder Mandant eine eigene Datenbank hat?
Für den reinen Betrieb ja, für Hochverfügbarkeit meist nicht. Eine Instanz trägt bis zu 32.767 Datenbanken, die Anzahl der Mandanten ist also nie das Problem. Die Standard-Edition kennt aber nur Basic Availability Groups: zwei Replikate, genau eine Datenbank je Verfügbarkeitsgruppe, kein lesbares Sekundärreplikat. Bei einer Datenbank je Mandant heißt das eine Verfügbarkeitsgruppe je Mandant – betrieblich schnell untragbar. Auch die Werkzeuge für unterbrechungsfreie Schemaänderungen über viele Datenbanken, etwa Online- und fortsetzbare Indexoperationen, sind der Enterprise-Edition vorbehalten. Wer Hochverfügbarkeit über eine gemeinsame Instanz mit vielen Mandantendatenbanken braucht, rechnet Enterprise ein oder wechselt auf einen verwalteten Dienst.
Wann lohnt sich eine zweite Region wirklich?
Wenn Recht oder Entfernung es erzwingen, nicht wenn es nach guter Architektur aussieht. Recht erzwingt es, sobald ein Kunde vertraglich oder gesetzlich verlangt, dass seine Daten das Land oder den Wirtschaftsraum nicht verlassen. Entfernung erzwingt es, sobald die Anwendung über einen Kontinent hinweg spürbar zäh wird – was fast immer an der Zahl der Roundtrips je Seite liegt, nicht an der Bandbreite. Eine zweite Region verdoppelt Grundkosten, Rollout-Aufwand und Fehlerquellen; alles darunter löst man billiger über kürzere Wege im Frontend und weniger Roundtrips.
Ein Bucket je Mandant oder ein gemeinsamer Bucket mit Präfixen?
Ein Bucket je Mandant ist lange tragfähig und gut prüfbar: Die Voreinstellung bei AWS liegt heute bei 10.000 Buckets je Konto und lässt sich auf bis zu eine Million anheben. Erst ab einer wirklich großen Zahl von Mandanten wird der gemeinsame Bucket mit einem Präfix je Mandant und kurzlebigen, auf dieses Präfix beschränkten Zugangsdaten praktikabler. Wichtig ist die Kehrseite: Object Lock und Lebenszyklusregeln wirken auf Bucket-Ebene und Lebenszyklusregeln sind auf 1.000 je Bucket begrenzt. Wer je Mandant unterschiedliche Aufbewahrungsfristen zusagt, braucht getrennte Buckets.
Wie zieht ein Mandant von einer Region in eine andere um?
In vier Schritten, die AWS als Clone, Flip, Redirect und Forget beschreibt. Erst wird der Zustand in die Zielregion kopiert und laufend nachgeführt, dann wird der Mandant für einen kurzen Moment schreibgeschützt und der Katalogeintrag auf die neue Zelle umgestellt, danach zeigen Anfragen an die alte Adresse per Weiterleitung auf die neue und erst am Ende werden die Daten in der Quellregion nachweisbar gelöscht. Der Umzug ist deshalb schon beim Entwurf einzuplanen: Wer die Region in Kunden-URLs oder in Fremdschlüsseln festschreibt, kann später nicht mehr umziehen.
Quellen
Externe Quellen, Stand August 2026 (öffnen in einem neuen Tab):
- Microsoft Azure Architecture Center – Deployment Stamps pattern (das kanonische Muster für Zellen)
- AWS Well-Architected – Reducing the Scope of Impact with Cell-Based Architecture
- Microsoft – Tenancy models for a multitenant solution (Silo, Pool und die Zwischenformen)
- Microsoft – .NET Support Policy (Supportenden von .NET 8, 9 und 10)
- Microsoft – Basic Availability Groups (die Grenzen der Standard-Edition)
- Microsoft – Distributed Availability Groups (nur manuelle Übernahme, kein eigener Listener)
- Microsoft – SQL Server Licensing Guide (Kernmindestabnahme, Rechte für passive Replikate)
- AWS – Bucket restrictions and limitations (Bucket-Kontingente je Konto)
- AWS – Sharing objects with presigned URLs (Gültigkeitsdauer und Zugangsdaten)
- Ceph – RADOS Gateway Multi-Site (regionsübergreifende Replikation im Eigenbetrieb)
- Microsoft – Configure ASP.NET Core Data Protection (gemeinsamer Schlüsselbund über mehrere Knoten)
- Microsoft – Incremental ASP.NET to ASP.NET Core migration (System.Web-Adapter und YARP)
Vom Einzelstück zur Fertigung – ohne Bruch im Betrieb
Wir begleiten Softwarehäuser auf genau diesem Weg: die bestehende Lösung analysieren, die Ausbaustufe bestimmen, die sich rechnet, und den Umbau so schneiden, dass der laufende Betrieb ihn aushält. Herstellerunabhängig, mit Rechenzentren in Deutschland und Finnland – und mit europäischer Datenhoheit als Voreinstellung statt als Aufpreis.
Dieser Beitrag beschreibt den Stand August 2026 und dient der allgemeinen Information. Produktversionen, Lizenzbedingungen und Rechtslage entwickeln sich weiter – prüfen Sie die genannten Punkte vor einer Entscheidung gegen die aktuellen Angaben der Hersteller.