<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Aleksei Aleinikov</title>
    <description>The latest articles on DEV Community by Aleksei Aleinikov (@aleksei_aleinikov).</description>
    <link>https://dev.to/aleksei_aleinikov</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2950325%2F67548842-b25f-4c39-84ef-bc470e23aa8d.jpg</url>
      <title>DEV Community: Aleksei Aleinikov</title>
      <link>https://dev.to/aleksei_aleinikov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aleksei_aleinikov"/>
    <language>en</language>
    <item>
      <title>GKE Autopilot vs Standard 2026: Die echten Trade-offs</title>
      <dc:creator>Aleksei Aleinikov</dc:creator>
      <pubDate>Wed, 15 Jul 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/aleksei_aleinikov/gke-autopilot-vs-standard-2026-die-echten-trade-offs-3mic</link>
      <guid>https://dev.to/aleksei_aleinikov/gke-autopilot-vs-standard-2026-die-echten-trade-offs-3mic</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4t1y4r4w0xism0w67koj.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4t1y4r4w0xism0w67koj.webp" alt="GKE Autopilot vs Standard 2026: Die echten Trade-offs" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Die Wahl zwischen GKE Autopilot und Standard sieht wie eine Checkbox bei der Cluster-Erstellung aus. Es ist tatsächlich eine Entscheidung, die dein Abrechnungsmodell, deine Betriebsgrenzen und die ausführbaren Workloads für die gesamte Lebensdauer des Clusters festlegt. Der Modus lässt sich danach nicht mehr wechseln.&lt;/p&gt;

&lt;p&gt;Die meisten Vergleiche listen Features auf. Dieser beginnt dort, wo die Feature-Liste die eigentliche Antwort verbirgt: &lt;strong&gt;wer die Worker-Node-Schicht besitzt&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Das Eine, was beide Modi gemeinsam haben
&lt;/h2&gt;

&lt;p&gt;Beide Modi betreiben dieselbe von Google verwaltete Control Plane. etcd, API-Server, Scheduler, Controller Manager — Google verwaltet, aktualisiert und betreibt alles davon hochverfügbar. Du provisionierst keinen Control-Plane-Node, weil es keinen zu provisionieren gibt. Es ist ein vollständig verwalteter Dienst hinter dem &lt;code&gt;container.googleapis.com&lt;/code&gt;-Endpunkt.&lt;/p&gt;

&lt;p&gt;Das ist kein Differenzierungsmerkmal. Der eigentliche Unterschied liegt vollständig &lt;strong&gt;unterhalb&lt;/strong&gt; der Control Plane.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1qpkjiuadhrwivhfec95.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1qpkjiuadhrwivhfec95.webp" alt="GKE-Architektur: Beide Modi teilen eine von Google verwaltete Control Plane. In Autopilot besitzt Google auch Node-Provisioning, Betriebssystem und kubelet. In Standard besitzt und konfigurierst du das alles selbst." width="799" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Autopilot: Die Node-Schicht verschwindet
&lt;/h2&gt;

&lt;p&gt;Im Autopilot-Modus abstrahiert Google alles unterhalb der Pod-Ebene.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Node-Provisioning ist automatisch.&lt;/strong&gt; Du erstellst oder löschst keine Node Pools. Wenn du einen Pod mit einem gültigen Resource-Request deployest, provisioniert Google automatisch einen passenden Node. Wenn der Pod endet, skaliert der Node herunter. Der Node ist ein Implementierungsdetail, das du nicht verwaltest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Du forderst Kapazität an, keine Maschinen.&lt;/strong&gt; Standardmäßig (GKE 1.32.3-gke.1927002 und später) laufen Pods auf der &lt;strong&gt;Container-optimierten Compute-Plattform&lt;/strong&gt; — Nodes, die zur Laufzeit dynamisch skalieren und ab Bruchteilen einer vCPU wachsen, sodass neue Pods selten auf das Booten eines Nodes warten. Braucht ein Workload spezifische Hardware, forderst du eine &lt;strong&gt;ComputeClass&lt;/strong&gt; an, statt einen Node Pool zu verwalten:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Balanced / Scale-Out&lt;/strong&gt; — General-Purpose; Scale-Out wählt Arm (T2A) für zustandslose Dichte&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt; — Compute-optimierte Machine-Serie&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accelerator&lt;/strong&gt; — GPUs und TPUs, angefordert in der ComputeClass oder im Pod-Spec&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;autopilot-spot&lt;/strong&gt; — unterbrechungstolerante Spot-Pods&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GKE provisioniert und dimensioniert die passenden Nodes automatisch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security-Posture wird erzwungen.&lt;/strong&gt; Pods laufen standardmäßig als Nicht-Root, hostPath-Volumes und Host-Networking sind gesperrt, und Google pflegt das Node-OS. Diese Einschränkungen sind keine Konfigurationsoptionen — sie machen das verwaltete Modell möglich.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resource-Requests sind Pflicht.&lt;/strong&gt; Autopilot lehnt Pods ohne &lt;code&gt;resources.requests&lt;/code&gt; ab. Das bricht Workloads, die sie wegzulassen, aber es ist ohnehin die richtige Einschränkung.&lt;/p&gt;

&lt;h2&gt;
  
  
  Standard: Du besitzt die Node-Schicht
&lt;/h2&gt;

&lt;p&gt;Im Standard-Modus bist du der Node-Betreiber.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Node Pools gehören dir.&lt;/strong&gt; Du erstellst sie, wählst Machine-Familien (n2, n2d, c3, t2d, m3, a2/a3 GPU und mehr), konfigurierst Boot-Disk-Größe, setzt Node-Taints und -Labels und entscheidest über die Upgrade-Strategie.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vollständige Workload-Freiheit.&lt;/strong&gt; Privilegierte Container, eigene DaemonSets für deine Agents, hostPath-Volumes, Host-Networking, Windows-Workloads — alles unterstützt. Das ist der Modus, wenn dein Security-Tooling, dein Netzwerk-Plugin oder dein Compliance-Agent Low-Level-Node-Zugriff benötigt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dein Upgrade-Takt.&lt;/strong&gt; Du konfigurierst die Node-Pool-Upgrade-Strategie (Surge- oder Blue-Green-Upgrades), Wartungsfenster und Patch-Ausschlüsse.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Abrechnung ist vorhersehbar, aber unerbittlich.&lt;/strong&gt; Du zahlst für die GCE-VMs in deinen Node Pools, unabhängig davon, ob Pods darauf laufen oder nicht. Drei &lt;code&gt;n2-standard-8&lt;/code&gt;-Nodes in &lt;code&gt;europe-west3&lt;/code&gt; für 24 Stunden → du zahlst für 72 vCPU-Stunden und 288 GB-Stunden RAM, unabhängig von der tatsächlichen Pod-Last.&lt;/p&gt;

&lt;h2&gt;
  
  
  Das Abrechnungsmodell ist die eigentliche Entscheidung
&lt;/h2&gt;

&lt;p&gt;Hier machen Teams teure Fehler.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flb8agjjjdzqm7wz6096g.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flb8agjjjdzqm7wz6096g.webp" alt="Kostenvergleich: Autopilot berechnet pro Pod-Resource-Request — variabel mit der Last. Standard berechnet pro GCE-Node-VM — fix, unabhängig von der Auslastung. Bei geringer oder variabler Last gewinnt Autopilot; bei konstant hoher Auslastung gewinnt Standard." width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Autopilot-Kosten&lt;/strong&gt; = Summe der Pod-&lt;code&gt;resources.requests&lt;/code&gt; × Einheitstarife (vCPU-Stunde + GB-Stunde + Ephemeral-Storage-GB-Stunde). Die Tarife enthalten einen Managed-Cluster-Aufschlag gegenüber reinen VM-Äquivalenten — etwa 10–20 % pro Einheit. Keine Pods → keine Compute-Kosten.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ein Detail, das viele überrascht:&lt;/strong&gt; Die Pod-Abrechnung gilt nur für &lt;em&gt;General-Purpose&lt;/em&gt;-Pods. Sobald ein Pod spezifische Hardware wählt — eine GPU, eine TPU oder eine benannte Compute-Engine-Machine-Serie — wechselt Autopilot diesen Workload auf &lt;strong&gt;Node-basierte Abrechnung&lt;/strong&gt; (ganzer Node plus Management-Aufschlag), genau wie Standard. Autopilots „zahle nur, was Pods anfordern“ gilt für General-Purpose-Compute, nicht für Accelerator-Nodes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Standard-Kosten&lt;/strong&gt; = Summe der Node-VM-Preise × Laufstunden. Ein Node bei 20 % Auslastung kostet dasselbe wie ein Node bei 95 %.&lt;/p&gt;

&lt;p&gt;Der Kipppunkt: Bei &lt;strong&gt;etwa 70–80 % konstanter Node-Auslastung&lt;/strong&gt; unterschreiten die Standard-Gesamtkosten in der Regel die von Autopilot. Unterhalb dieser Schwelle ist Autopilot meistens günstiger.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In der Praxis:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dev- und Test-Cluster&lt;/strong&gt; : Autopilot gewinnt fast immer. Variable Last, Pods idle über Nacht, niemand skaliert manuell herunter.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch-Workloads mit Spitzen&lt;/strong&gt; : Autopilot gewinnt — du zahlst für die Spitze, nicht für die Wartezeit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Produktions-Cluster mit stabiler, hoher Last&lt;/strong&gt; : Kalkuliere es durch. Wenn deine p50-Node-Auslastung zuverlässig über 75 % liegt, ist Standard wahrscheinlich günstiger.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keine überspezifizierten Resource-Requests in Autopilot&lt;/strong&gt; — überhöhte Requests erhöhen direkt die Rechnung.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Was sich geändert hat — und was Autopilot 2026 noch nicht kann
&lt;/h2&gt;

&lt;p&gt;Die Lücke zwischen den Modi ist seit dem Autopilot-Launch 2021 deutlich geschrumpft. Was inzwischen auf Autopilot funktioniert:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GPUs und TPUs&lt;/strong&gt; — über eine ComputeClass oder das Pod-Spec angefordert; keine Accelerator-Node-Pools zu verwalten&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spot-Pods&lt;/strong&gt; — unterbrechungstolerante Kapazität pro Pod, kein Spot-Node-Pool&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Arm (T2A)&lt;/strong&gt; — über die Scale-Out-Klasse oder eine Arm-ComputeClass&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DaemonSets&lt;/strong&gt; — unterstützt, solange sie keinen erhöhten Zugriff auf den Node benötigen (die meisten Monitoring- und Logging-Agents erfüllen das)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confidential GKE Nodes&lt;/strong&gt; — AMD-SEV-Speicherverschlüsselung ist jetzt eine Autopilot-Option, kein Standard-Alleinstellungsmerkmal mehr&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GKE Sandbox (gVisor)&lt;/strong&gt; — auf Autopilot standardmäßig aktiv, für eine zusätzliche Syscall-Isolationsschicht&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GKE Dataplane V2, CMEK, Binary Authorization, Workload Identity Federation&lt;/strong&gt; — alle verfügbar, mehrere standardmäßig aktiv&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Die harten Grenzen, die bleiben — die echten Gründe für Standard:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Kein erhöhter Node-Zugriff&lt;/strong&gt; — privilegierte Container und alles, was Root auf dem Host braucht, wird abgelehnt; ein Agent, der den Node direkt anfassen muss, läuft nicht&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kein Node-SSH&lt;/strong&gt; — kein SSH oder Exec in Worker-Nodes; Debug auf Pod-Ebene&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kein eigenes Node-OS&lt;/strong&gt; — Autopilot nutzt ausschließlich Container-Optimized OS, kein Ubuntu-Image, keine eigenen Startup-Skripte&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keine Windows-Nodes&lt;/strong&gt; — nur Linux-Workloads&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kein Host-Networking, keine beliebigen hostPath-Volumes&lt;/strong&gt; — Node-erzwungene Security-Einschränkungen&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keine Cloud-Marketplace-Apps&lt;/strong&gt; und kein &lt;code&gt;externalIPs&lt;/code&gt;-Service-Feld&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Zwei Korrekturen, die erwähnenswert sind, weil ältere Vergleiche sie falsch darstellen: &lt;strong&gt;DaemonSets und Confidential GKE Nodes funktionieren 2026 beide auf Autopilot.&lt;/strong&gt; Der Blocker war nie „DaemonSet“ — es ist &lt;em&gt;erhöhter Node-Zugriff&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gegenüberstellung: Das vollständige Bild
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;GKE Autopilot&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;GKE Standard&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Node-Verwaltung&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;Du&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cluster-Standort&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Nur regional&lt;/td&gt;
&lt;td&gt;Regional oder zonal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Abrechnung General-Purpose&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pro Pod-Request&lt;/td&gt;
&lt;td&gt;Pro Node-VM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Abrechnung spezifische Hardware&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pro Node (+ Aufschlag)&lt;/td&gt;
&lt;td&gt;Pro Node-VM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Idle-Node-Kosten&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Keine&lt;/td&gt;
&lt;td&gt;Voller Node-Preis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Compute-Auswahl&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ComputeClasses&lt;/td&gt;
&lt;td&gt;Jede GCE-Machine-Serie&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Node-OS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Container-Optimized OS&lt;/td&gt;
&lt;td&gt;COS / Ubuntu / Windows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Node-SSH&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Nein&lt;/td&gt;
&lt;td&gt;Ja&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Privilegierter / erhöhter Node-Zugriff&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Nein&lt;/td&gt;
&lt;td&gt;Ja&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DaemonSets&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ja (kein erhöhter Zugriff)&lt;/td&gt;
&lt;td&gt;Ja (uneingeschränkt)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Windows-Nodes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Nein&lt;/td&gt;
&lt;td&gt;Ja&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Confidential GKE Nodes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ja&lt;/td&gt;
&lt;td&gt;Ja&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GKE Sandbox (gVisor)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Standardmäßig aktiv&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GPU / TPU&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ja (ComputeClass)&lt;/td&gt;
&lt;td&gt;Ja (Node Pools)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Spot&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pro Pod&lt;/td&gt;
&lt;td&gt;Node Pool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Arm (T2A)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ja&lt;/td&gt;
&lt;td&gt;Ja&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dataplane V2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Standard&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Workload Identity Federation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Vorkonfiguriert&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Node-Auto-Upgrade&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pflicht&lt;/td&gt;
&lt;td&gt;Konfigurierbar&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Autopilot-Modus-Workloads&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ganzer Cluster&lt;/td&gt;
&lt;td&gt;Pro Workload via ComputeClass&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Die Grenze verwischt 2026
&lt;/h2&gt;

&lt;p&gt;Zwei Änderungen machen die Wahl weniger binär als früher.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Autopilot-Workloads innerhalb von Standard-Clustern.&lt;/strong&gt; Du musst nicht mehr einen Modus für den ganzen Cluster wählen. In einem Standard-Cluster kannst du einzelne Workloads im Autopilot-Modus laufen lassen, indem du eine Autopilot-ComputeClass anforderst — GKE provisioniert und verwaltet diese Nodes für dich, während der Rest des Clusters mit deinen eigenen Node Pools unter deiner Kontrolle bleibt. Händefreie Nodes für die Workloads, die sie wollen, volle Kontrolle für die, die sie brauchen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Die Container-optimierte Compute-Plattform.&lt;/strong&gt; Auf aktuellen Versionen (GKE 1.32.3-gke.1927002+) laufen General-Purpose-Autopilot-Pods auf Nodes, die zur Laufzeit dynamisch skalieren und aus einem Pool vorbereitgestellter Kapazität schöpfen. Das beseitigt den größten Teil der Cold-Start-Verzögerung, die früher Autopilots Schwachstelle war — neue Pods werden meist eingeplant, ohne auf einen frischen Node zu warten.&lt;/p&gt;

&lt;p&gt;Fazit: „Autopilot vs Standard“ wird zunehmend zu „wie viel von &lt;em&gt;diesem Cluster&lt;/em&gt; soll verwaltet sein“ — statt zwei getrennten Welten.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wie man wählt: Drei Fragen
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkepmpjkh8qw5mc8evisl.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkepmpjkh8qw5mc8evisl.webp" alt="Entscheidungs-Flowchart: Braucht ein Workload erhöhten Node-Zugriff — privilegierte Pods, Node-SSH, ein eigenes/Ubuntu-Node-OS oder Windows-Nodes? → Standard. Konstant &gt;75% Node-Auslastung? → Standard. Sonst → Autopilot." width="799" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Benötigt ein Workload erhöhten Node-Zugriff — privilegierte Container, ein DaemonSet, das den Node anfasst, Node-SSH, ein eigenes oder Ubuntu-Node-OS oder Windows-Nodes?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Wenn ja → &lt;strong&gt;Standard&lt;/strong&gt; , ohne Diskussion. Das sind harte Einschränkungen in Autopilot, keine Einstellungen. (Was &lt;em&gt;nicht&lt;/em&gt; mehr auf dieser Liste steht: GPUs, TPUs, Spot, Arm und Confidential GKE Nodes laufen alle auf Autopilot.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Läuft dein Cluster bei konstant hoher Node-Auslastung (über ~75%)?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Wenn ja → &lt;strong&gt;Standard durchrechnen.&lt;/strong&gt; Bei konstant hoher Auslastung nutzt du die VMs, für die du zahlst, vollständig — und der Standard-VM-Preis unterbietet Autopilots Pod-Request-Preis. Nutze den &lt;a href="https://cloud.google.com/products/calculator" rel="noopener noreferrer"&gt;GCP Pricing Calculator&lt;/a&gt; mit deinen tatsächlichen Resource-Requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Soll das Team, das diesen Cluster betreibt, Infrastruktur verwalten?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Wenn nein → &lt;strong&gt;Autopilot.&lt;/strong&gt; Dev-Umgebungen, interne Developer-Plattformen, SaaS-Produktcluster, Batch-Verarbeitung — Autopilot beseitigt den Node-Pool-Verwaltungsaufwand, damit das Team sich auf die Applikationsschicht konzentriert.&lt;/p&gt;

&lt;p&gt;Im Zweifel: &lt;strong&gt;Autopilot als Standard für neue Cluster&lt;/strong&gt; , es sei denn, eine der harten Grenzen greift. Für die Workloads, die es benötigen, kann immer ein paralleler Standard-Cluster betrieben werden.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ein Muster, das in großem Maßstab funktioniert
&lt;/h2&gt;

&lt;p&gt;Beim Aufbau der ersten Produktions-GCP-Plattform bei der Deutschen Telekom hat sich mit der Zeit diese Aufteilung ergeben:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Standard für die Produktions-Datenebene&lt;/strong&gt; : konstant hohe Auslastung, Security-DaemonSets für Compliance-Agents, vollständige Dataplane-V2-Konfiguration, Spot-Node-Pools für Batch-Verarbeitung.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Autopilot für Dev- und Pre-Prod-Umgebungen&lt;/strong&gt; : automatisches Scale-to-Zero an Wochenenden und nachts, keine Idle-Node-Kosten, Entwickler erhalten einen Cluster, ohne ihn besitzen zu müssen.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Beide Cluster-Typen treten demselben GKE Enterprise Fleet bei, teilen Policy-Controller-Regeln und werden aus demselben Cloud-Monitoring-Workspace überwacht. Der Modus ist ein Implementierungsdetail; die Governance-Schicht liegt über beiden.&lt;/p&gt;

&lt;h2&gt;
  
  
  Die Security-Grundlage ändert sich nicht
&lt;/h2&gt;

&lt;p&gt;Unabhängig vom gewählten Modus sind diese Maßnahmen identisch und nicht verhandelbar:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Workload Identity Federation&lt;/strong&gt; — keine Service-Account-Schlüsseldateien auf Nodes oder in Pods. WIF stellt kurzlebige OIDC-Token aus. Den vollständigen Ansatz zur Eliminierung von SA-Schlüsseln findest du in &lt;a href="https://www.alekseialeinikov.com/de/blog/topics/security/service-account-schluessel-abschaffen-workload-identity-federation-2026" rel="noopener noreferrer"&gt;Service-Account-Schlüssel abschaffen: Workload Identity Federation auf GKE&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Binary Authorization&lt;/strong&gt; — erzwinge, dass nur signierte, geprüfte Images in deinem Cluster laufen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GKE Dataplane V2&lt;/strong&gt; — eBPF-basierte Network-Policy-Durchsetzung (Cilium). Standard bei Autopilot; opt-in bei Standard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Least-Privilege RBAC&lt;/strong&gt; — ClusterAdmin für Menschen ist fast nie korrekt. Binde Rollen an Service Accounts, nicht direkt an Google-Identitäten.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Node-Auto-Upgrade&lt;/strong&gt; — konfiguriere bei Standard einen Release-Channel (Regular oder Stable) und aktiviere Auto-Upgrade. Rückstand bei Node-Versionen ist die häufigste Ursache vermeidbarer Security-Exposition in produktiven GKE-Clustern. Bei Autopilot übernimmt Google das.&lt;/p&gt;

&lt;p&gt;Mehr zu Isolations-Trade-offs beim Betrieb nicht vertrauenswürdiger Workloads innerhalb von GKE findest du in &lt;a href="https://www.alekseialeinikov.com/de/blog/topics/devops/microvms-firecracker-vs-gvisor-sichere-workloads-2026" rel="noopener noreferrer"&gt;MicroVMs 2026: Firecracker vs gVisor für sichere Workloads&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ursprünglich veröffentlicht auf &lt;a href="https://www.alekseialeinikov.com/de/blog/topics/cloud/gke-autopilot-vs-standard-vergleich-2026" rel="noopener noreferrer"&gt;alekseialeinikov.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>gke</category>
      <category>kubernetes</category>
      <category>gkeautopilot</category>
      <category>gkestandard</category>
    </item>
    <item>
      <title>GKE Autopilot vs Standard in 2026: The Real Trade-offs</title>
      <dc:creator>Aleksei Aleinikov</dc:creator>
      <pubDate>Wed, 15 Jul 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/aleksei_aleinikov/gke-autopilot-vs-standard-in-2026-the-real-trade-offs-5el8</link>
      <guid>https://dev.to/aleksei_aleinikov/gke-autopilot-vs-standard-in-2026-the-real-trade-offs-5el8</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4t1y4r4w0xism0w67koj.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4t1y4r4w0xism0w67koj.webp" alt="GKE Autopilot vs Standard in 2026: The Real Trade-offs" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choosing between GKE Autopilot and Standard looks like a checkbox decision at cluster creation time. It is actually a commitment that determines your billing model, your operational ceiling, and what workloads you can run — for the lifetime of the cluster. You cannot switch modes after creation.&lt;/p&gt;

&lt;p&gt;Most comparisons list features. This one starts where the feature list hides the real answer: &lt;strong&gt;who owns the worker node layer&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The One Thing Both Modes Have in Common
&lt;/h2&gt;

&lt;p&gt;Both modes run the exact same Google-managed control plane. etcd, the API server, the scheduler, the controller manager — Google manages, upgrades, and HA-replicates all of it. You never provision a control plane node, because there are none to provision. It is a fully managed service behind the &lt;code&gt;container.googleapis.com&lt;/code&gt; endpoint.&lt;/p&gt;

&lt;p&gt;This is not a differentiator. Stop treating it as one. The actual split is entirely &lt;strong&gt;below&lt;/strong&gt; the control plane.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1qpkjiuadhrwivhfec95.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1qpkjiuadhrwivhfec95.webp" alt="GKE architecture: both modes share a Google-managed control plane. In Autopilot, Google also owns node provisioning, OS, and kubelet. In Standard, you own and configure all of that." width="799" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Autopilot: The Node Layer Disappears
&lt;/h2&gt;

&lt;p&gt;In Autopilot mode, Google abstracts away everything below the pod level.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Node provisioning is automatic.&lt;/strong&gt; You never create or delete a node pool. When you deploy a pod with a valid resource request, Google provisions a node that fits it. When the pod leaves, the node scales down. The node is an implementation detail you do not manage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You request capacity, not machines.&lt;/strong&gt; By default (GKE 1.32.3-gke.1927002 and later) pods run on the &lt;strong&gt;container-optimized compute platform&lt;/strong&gt; — nodes that dynamically resize while running and scale from a fraction of a vCPU, so new pods rarely wait for a node to boot. When a workload needs specific hardware, you request a &lt;strong&gt;ComputeClass&lt;/strong&gt; instead of managing a node pool:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Balanced / Scale-Out&lt;/strong&gt; — general-purpose; Scale-Out selects Arm (T2A) for stateless density&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt; — compute-optimised machine series&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accelerator&lt;/strong&gt; — GPUs and TPUs, requested in the ComputeClass or the pod spec&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;autopilot-spot&lt;/strong&gt; — interruption-tolerant Spot pods&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GKE provisions and sizes the matching nodes automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security posture is enforced.&lt;/strong&gt; Pods run as non-root by default, hostPath volumes and host networking are blocked, and Google maintains the node OS. These constraints are not configuration options — they are what makes the managed model work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resource requests are mandatory.&lt;/strong&gt; Autopilot rejects pods without &lt;code&gt;resources.requests&lt;/code&gt;. This will break workloads that lazily omit them, but it is the right constraint to enforce anyway.&lt;/p&gt;

&lt;h2&gt;
  
  
  Standard: You Own the Node Layer
&lt;/h2&gt;

&lt;p&gt;In Standard mode, you are the node operator.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Node pools are yours.&lt;/strong&gt; You create them, choose machine families (n2, n2d, c3, t2d, m3, a2/a3 GPU, and more), configure boot disk size, set node taints and labels, and decide upgrade strategy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full workload freedom.&lt;/strong&gt; Privileged containers, custom DaemonSets for your own agents, hostPath volumes, host networking, Windows workloads — all supported. This is the mode when your security tooling, network plugin, or compliance agent needs low-level node access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your upgrade cadence.&lt;/strong&gt; You configure node pool upgrade strategy (surge or blue-green), maintenance windows, and patch exclusions. You choose the release channel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Billing is predictable but blunt.&lt;/strong&gt; You pay for the GCE VMs in your node pools whether pods are running on them or not. Three &lt;code&gt;n2-standard-8&lt;/code&gt; nodes in &lt;code&gt;europe-west3&lt;/code&gt; running 24 h → you pay for 72 vCPU-hours and 288 GB-hours of RAM, regardless of actual pod load.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Billing Model Is the Real Decision
&lt;/h2&gt;

&lt;p&gt;This is where teams make expensive mistakes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flb8agjjjdzqm7wz6096g.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flb8agjjjdzqm7wz6096g.webp" alt="Cost comparison: Autopilot charges per pod resource request — variable with load. Standard charges per GCE node VM — fixed regardless of utilisation. At low or bursty load Autopilot wins; at consistently high utilisation Standard wins." width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Autopilot cost&lt;/strong&gt; = sum of pod &lt;code&gt;resources.requests&lt;/code&gt; × per-unit rates (vCPU-hour + GB-hour + ephemeral storage GB-hour). The rates include a managed-cluster premium over raw VM equivalent — roughly 10–20% per unit. No pods → no compute cost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One caveat that surprises people:&lt;/strong&gt; per-pod billing only applies to &lt;em&gt;general-purpose&lt;/em&gt; pods. The moment a pod selects specific hardware — a GPU, a TPU, or a named Compute Engine machine series — Autopilot switches that workload to &lt;strong&gt;per-node billing&lt;/strong&gt; (the whole node plus a management premium), exactly like Standard. Autopilot’s “pay only for what pods request” advantage is about general-purpose compute, not accelerator nodes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Standard cost&lt;/strong&gt; = sum of node VM prices × hours running. A node at 20% utilisation costs the same as a node at 95%.&lt;/p&gt;

&lt;p&gt;The crossover: at &lt;strong&gt;roughly 70–80% consistent node utilisation&lt;/strong&gt; , Standard’s total cost typically drops below Autopilot’s. Below that threshold, Autopilot is usually cheaper because you are not paying for idle capacity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In practice:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dev and test clusters&lt;/strong&gt; : Autopilot almost always wins. Variable load, pods idle overnight, no one scales down properly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch workloads with spikes&lt;/strong&gt; : Autopilot wins — you pay for the spike, not for waiting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production clusters with steady, high load&lt;/strong&gt; : model it. If your p50 node utilisation is reliably above 75%, Standard is likely cheaper.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid over-specifying resource requests in Autopilot&lt;/strong&gt; — over-requested pods inflate your bill directly. Get sizing right before migrating.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Changed — and What Autopilot Still Cannot Do in 2026
&lt;/h2&gt;

&lt;p&gt;The gap between the modes has narrowed sharply since Autopilot launched in 2021. What now works on Autopilot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GPUs and TPUs&lt;/strong&gt; — requested through a ComputeClass or the pod spec; no accelerator node pools to manage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spot pods&lt;/strong&gt; — per-pod interruption-tolerant capacity, no Spot node pool&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Arm (T2A)&lt;/strong&gt; — via the Scale-Out class or an Arm ComputeClass&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DaemonSets&lt;/strong&gt; — supported, as long as they do not need elevated access on the node (most monitoring and logging agents qualify)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confidential GKE Nodes&lt;/strong&gt; — AMD SEV memory encryption is now an Autopilot option, not a Standard-only feature&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GKE Sandbox (gVisor)&lt;/strong&gt; — enabled by default on Autopilot for an extra syscall-isolation layer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GKE Dataplane V2, CMEK, Binary Authorization, Workload Identity Federation&lt;/strong&gt; — all available, several on by default&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The hard limits that remain — the real reasons to reach for Standard:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No elevated node access&lt;/strong&gt; — privileged containers and anything that needs root on the host are rejected; an agent that must touch the node directly will not run&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No node SSH&lt;/strong&gt; — you cannot SSH or exec into worker nodes; you debug at the pod level&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No custom node OS&lt;/strong&gt; — Autopilot is Container-Optimized OS only, with no Ubuntu image and no custom startup scripts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Windows nodes&lt;/strong&gt; — Linux workloads only&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No host networking or arbitrary hostPath volumes&lt;/strong&gt; — node-enforced security restrictions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Cloud Marketplace apps&lt;/strong&gt; and no &lt;code&gt;externalIPs&lt;/code&gt; Service field&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two corrections worth flagging, because older comparisons still get them wrong: &lt;strong&gt;DaemonSets and Confidential GKE Nodes both work on Autopilot in 2026.&lt;/strong&gt; The blocker was never “DaemonSets” — it is &lt;em&gt;elevated node access&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side-by-Side: The Full Picture
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;GKE Autopilot&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;GKE Standard&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Node management&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;You&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cluster location&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Regional only&lt;/td&gt;
&lt;td&gt;Regional or zonal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;General-purpose billing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per pod request&lt;/td&gt;
&lt;td&gt;Per node VM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Specific-hardware billing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per node (+ premium)&lt;/td&gt;
&lt;td&gt;Per node VM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Idle node cost&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Full node price&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Compute selection&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ComputeClasses&lt;/td&gt;
&lt;td&gt;Any GCE machine series&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Node OS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Container-Optimized OS&lt;/td&gt;
&lt;td&gt;COS / Ubuntu / Windows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Node SSH&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Privileged / elevated node access&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DaemonSets&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes (no elevated access)&lt;/td&gt;
&lt;td&gt;Yes (unrestricted)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Windows nodes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Confidential GKE Nodes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GKE Sandbox (gVisor)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;On by default&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GPU / TPU&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes (ComputeClass)&lt;/td&gt;
&lt;td&gt;Yes (node pools)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Spot&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per pod&lt;/td&gt;
&lt;td&gt;Node pool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Arm (T2A)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dataplane V2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Default&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Workload Identity Federation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pre-configured&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Node auto-upgrade&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Mandatory&lt;/td&gt;
&lt;td&gt;Configurable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Autopilot-mode workloads&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Whole cluster&lt;/td&gt;
&lt;td&gt;Per-workload via ComputeClass&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The Line Is Blurring in 2026
&lt;/h2&gt;

&lt;p&gt;Two changes make this less of a binary choice than it used to be.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Autopilot workloads inside Standard clusters.&lt;/strong&gt; You no longer have to pick one mode for the whole cluster. In a Standard cluster you can mark specific workloads to run in Autopilot mode by requesting an Autopilot ComputeClass — GKE provisions and manages those nodes for you, while the rest of the cluster stays under your control with your own node pools. Hands-off nodes for the workloads that want them, full control for the ones that need it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The container-optimized compute platform.&lt;/strong&gt; On recent versions (GKE 1.32.3-gke.1927002+), general-purpose Autopilot pods run on nodes that resize dynamically while running and draw from a pool of pre-provisioned capacity. This removes most of the cold-start delay that used to be Autopilot’s weak point — new pods usually schedule without waiting for a fresh node to boot.&lt;/p&gt;

&lt;p&gt;The takeaway: “Autopilot vs Standard” is increasingly “how much of &lt;em&gt;this cluster&lt;/em&gt; do I want managed”, not two separate worlds.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Choose: Three Questions
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkepmpjkh8qw5mc8evisl.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkepmpjkh8qw5mc8evisl.webp" alt="Decision flowchart: does a workload need elevated node access — privileged pods, node SSH, a custom or Ubuntu node OS, or Windows nodes? → Standard. Consistently &gt;75% node utilisation? → Standard. Otherwise → Autopilot." width="799" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Does any workload need elevated node access — privileged containers, a custom DaemonSet that touches the node, node SSH, a custom or Ubuntu node OS, or Windows nodes?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If yes → &lt;strong&gt;Standard&lt;/strong&gt; , full stop. These are hard constraints in Autopilot, not settings you can unlock. (Note what is &lt;em&gt;not&lt;/em&gt; on this list anymore: GPUs, TPUs, Spot, Arm, and Confidential GKE Nodes all work on Autopilot.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Is your cluster running at consistently high node utilisation (above ~75%)?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If yes → &lt;strong&gt;run the numbers for Standard.&lt;/strong&gt; At high, consistent utilisation you are paying for capacity you are actually using, and Standard’s per-VM price undercuts Autopilot’s per-pod-request price. Use the &lt;a href="https://cloud.google.com/products/calculator" rel="noopener noreferrer"&gt;GCP Pricing Calculator&lt;/a&gt; with your actual resource requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Should the team running this cluster manage infrastructure?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If no → &lt;strong&gt;Autopilot.&lt;/strong&gt; Dev environments, internal developer platforms, SaaS product clusters, batch processing — Autopilot removes node-pool-management toil so the team focuses on the application layer.&lt;/p&gt;

&lt;p&gt;When still unsure: &lt;strong&gt;default to Autopilot for new clusters&lt;/strong&gt; unless you hit one of the hard limits above. You can always run a parallel Standard cluster for workloads that need it.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Pattern That Works at Scale
&lt;/h2&gt;

&lt;p&gt;Building the first production GCP platform at Deutsche Telekom, the split that emerged over time was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Standard for the production data plane&lt;/strong&gt; : consistent high utilisation, security DaemonSets for compliance agents, full Dataplane V2 configuration, spot-node pools for batch processing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Autopilot for dev and pre-prod environments&lt;/strong&gt; : automatic scale-to-zero on weekends and overnight, no idle node cost, developers get a cluster without owning it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both clusters join the same GKE Enterprise fleet, share Policy Controller rules, and report to the same Cloud Monitoring workspace. The mode is an implementation detail; the governance layer sits above both.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Security Baseline Does Not Change
&lt;/h2&gt;

&lt;p&gt;Regardless of mode, these practices are identical and non-negotiable:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Workload Identity Federation&lt;/strong&gt; — no service account key files on nodes or in pods. WIF issues short-lived OIDC tokens. Dropping SA keys entirely removes one of the most common GCP credential-exfiltration vectors — see the full walkthrough in &lt;a href="https://www.alekseialeinikov.com/en/blog/topics/security/kill-service-account-keys-workload-identity-federation-2026" rel="noopener noreferrer"&gt;Kill Service Account Keys: Workload Identity Federation on GKE&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Binary Authorization&lt;/strong&gt; — enforce that only signed, approved images run in your cluster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GKE Dataplane V2&lt;/strong&gt; — eBPF-based network policy enforcement (Cilium). Default on Autopilot; opt-in on Standard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Least-privilege RBAC&lt;/strong&gt; — ClusterAdmin for humans is almost never correct. Bind roles to service accounts, not to Google identities directly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Node auto-upgrade&lt;/strong&gt; — on Standard, configure a release channel (Regular or Stable) and enable auto-upgrade. Falling behind on node versions is the single most common cause of preventable security exposure in production GKE clusters. On Autopilot, Google handles this for you.&lt;/p&gt;

&lt;p&gt;The mode you pick does not change the security work. Do it regardless.&lt;/p&gt;

&lt;p&gt;For more on isolation trade-offs when running untrusted workloads inside GKE, see &lt;a href="https://www.alekseialeinikov.com/en/blog/topics/devops/microvms-firecracker-vs-gvisor-secure-workloads-2026" rel="noopener noreferrer"&gt;MicroVMs in 2026: Firecracker vs gVisor for Secure Workloads&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://www.alekseialeinikov.com/en/blog/topics/cloud/gke-autopilot-vs-standard-2026" rel="noopener noreferrer"&gt;alekseialeinikov.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>gke</category>
      <category>kubernetes</category>
      <category>gkeautopilot</category>
      <category>gkestandard</category>
    </item>
    <item>
      <title>AI Coding Agents in 2026: Claude Code vs Codex vs opencode</title>
      <dc:creator>Aleksei Aleinikov</dc:creator>
      <pubDate>Tue, 14 Jul 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/aleksei_aleinikov/ai-coding-agents-in-2026-claude-code-vs-codex-vs-opencode-1i69</link>
      <guid>https://dev.to/aleksei_aleinikov/ai-coding-agents-in-2026-claude-code-vs-codex-vs-opencode-1i69</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frxzygqhnxreu9a0zx3n5.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frxzygqhnxreu9a0zx3n5.webp" alt="AI Coding Agents in 2026: Claude Code vs Codex vs opencode" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two years ago, AI in the editor meant autocomplete: it guessed the next line and you pressed Tab. In 2026 it means something categorically different — an &lt;strong&gt;agent&lt;/strong&gt; that reads your repo, edits files across it, runs your tests, reads the errors, and tries again, all from a single instruction. The tool stopped suggesting and started &lt;em&gt;doing&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Three names dominate that shift: &lt;strong&gt;Claude Code&lt;/strong&gt; , &lt;strong&gt;Codex&lt;/strong&gt; , and &lt;strong&gt;opencode&lt;/strong&gt;. They look similar in a demo and are marketed as rivals, but they make genuinely different bets on lock-in, control, and openness. This is a vendor-neutral guide to what they actually are, how the thing under all of them works, and how to choose — and run — one without handing over the keys to your codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, What a Coding Agent Actually Is
&lt;/h2&gt;

&lt;p&gt;The word “agent” gets thrown around loosely, so pin it down. A coding agent is not one clever prompt — it’s a &lt;strong&gt;loop&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjzi2ymn40eue64ihi74m.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjzi2ymn40eue64ihi74m.webp" alt="The agent loop: your prompt goes to the model, which plans a step, calls tools to read/edit files and run commands, observes the result, and repeats until the task is done and it shows you a diff." width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You give a goal — &lt;em&gt;“add JWT auth to the API.”&lt;/em&gt; Then:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The model plans&lt;/strong&gt; the next concrete step.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It acts&lt;/strong&gt; — calls tools to read files, edit code, run a command, grep the repo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It observes&lt;/strong&gt; the result — test output, a stack trace, the new file contents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It loops&lt;/strong&gt; — feeds that back in and plans again, until the task is actually done.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It stops&lt;/strong&gt; and shows you a diff to review and approve.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That loop is the whole idea, and it’s why an agent is powerful and risky at the same time: &lt;strong&gt;between your prompt and the result, it takes actions on its own.&lt;/strong&gt; Autocomplete could only ever suggest; an agent edits your files and runs your shell. Every tool below is a different wrapper around this same loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three That Matter
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Claude Code&lt;/strong&gt; — Anthropic’s agent. It began as a terminal tool and now runs across the terminal, IDE, desktop app, and the browser — including managed cloud sessions that chew through long tasks in parallel while your machine is off. It’s tied to Claude models, closed-source, MCP-native, and asks permission before edits and commands. If you already trust Claude for code, it’s the most polished way to let it act.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Codex&lt;/strong&gt; — OpenAI’s coding agent, and the one that pushes the loop the furthest. It runs in two modes: a &lt;strong&gt;cloud agent&lt;/strong&gt; that grinds through long tasks in an isolated, managed sandbox — so you can fire off several jobs at once and walk away — and a &lt;strong&gt;local CLI&lt;/strong&gt; for hands-on work at the keyboard. It’s tied to OpenAI’s frontier models, which are still some of the strongest at real code, and its cloud agent is a mature, isolated place to hand off long work. The CLI is open; the models and the managed service are proprietary. The trade is clear: you accept the OpenAI ecosystem, and in return you get one of the strongest model-plus-cloud combinations on the market.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;opencode&lt;/strong&gt; — the open-source outlier. A terminal agent that is &lt;strong&gt;model-agnostic&lt;/strong&gt; : you point it at whichever provider you want — Anthropic, OpenAI, Google, or a local model — and the agent itself is open-source, so you can read it, extend it, and self-host it. Its bet is &lt;em&gt;no lock-in and full auditability&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Each One Sits
&lt;/h2&gt;

&lt;p&gt;Strip away the branding and the three separate on two axes: &lt;strong&gt;how open they are&lt;/strong&gt; (closed vs open-source) and &lt;strong&gt;how locked to one model vendor&lt;/strong&gt; they are. Notice what is &lt;em&gt;not&lt;/em&gt; an axis anymore: where it runs. Both Claude Code and Codex now run locally &lt;em&gt;and&lt;/em&gt; offer a managed cloud, so that stopped being the dividing line.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq1kw3zmweuyjs0mi29tb.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq1kw3zmweuyjs0mi29tb.webp" alt="Positioning matrix on two axes — closed vs open source, and locked to one vendor vs any model. Claude Code and Codex sit together in the closed, vendor-locked corner and both also run local and in a managed cloud; opencode sits alone in the open, any-model corner." width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the same decision as a table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Claude Code&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Codex&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;opencode&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Vendor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Anthropic&lt;/td&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;Open-source (community)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Models&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Claude only&lt;/td&gt;
&lt;td&gt;OpenAI only&lt;/td&gt;
&lt;td&gt;Any — bring your own&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Where it runs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Local + managed cloud&lt;/td&gt;
&lt;td&gt;Local CLI + managed cloud&lt;/td&gt;
&lt;td&gt;Local / self-hosted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Openness&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Closed&lt;/td&gt;
&lt;td&gt;CLI open, service/model closed&lt;/td&gt;
&lt;td&gt;Fully open-source&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MCP support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Native&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Auditability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Trust the vendor&lt;/td&gt;
&lt;td&gt;Trust the vendor&lt;/td&gt;
&lt;td&gt;Read the source&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Deep Claude users, polished all-surface&lt;/td&gt;
&lt;td&gt;Delegating &amp;amp; parallelizing long tasks, hands-off cloud runs&lt;/td&gt;
&lt;td&gt;Avoiding lock-in, local-only, self-hosting&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The pattern is clear: the two proprietary agents cluster together — polished, model-locked, vendor-trusted — and &lt;strong&gt;opencode is the deliberate counterweight&lt;/strong&gt; for teams that refuse model lock-in or need to audit what the agent does.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Actually Choose
&lt;/h2&gt;

&lt;p&gt;Ignore the demos; they all look magical for ten minutes. Choose on three real constraints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model lock-in.&lt;/strong&gt; Do you want to be tied to one model family? Claude Code binds you to Claude, Codex to OpenAI. opencode lets you swap models — including running a local one for sensitive code — without changing your workflow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Where it runs.&lt;/strong&gt; This used to split them, but no longer: both Claude Code and Codex run locally &lt;em&gt;and&lt;/em&gt; offer a managed cloud that chews through long, parallel tasks while you do something else. opencode is the local / self-hosted one — no vendor cloud at all, which is the whole point if you need everything on your own infrastructure. So don’t choose on “local vs cloud”; choose on whose cloud you’re willing to send code to, if any.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Openness and auditability.&lt;/strong&gt; In a regulated or security-sensitive shop, “we can read exactly what the agent does” is not a nice-to-have. That’s opencode’s home turf; the proprietary tools ask you to trust the vendor instead.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practice the switching cost is low — the loop is the same everywhere — so trying two is cheap and often clarifying. Pick the default that matches your constraints, not the one with the best launch video.&lt;/p&gt;

&lt;h2&gt;
  
  
  Letting It Act Without Letting It Loose
&lt;/h2&gt;

&lt;p&gt;Here’s the part the demos skip. A coding agent is, mechanically, &lt;strong&gt;a program that edits your source and runs shell commands on your behalf&lt;/strong&gt;. That is enormous leverage and a genuine attack surface. The failure mode isn’t the model being dumb — it’s the model being &lt;em&gt;capable&lt;/em&gt; and &lt;em&gt;unsupervised&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9ovvjvrui2x26at4waok.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9ovvjvrui2x26at4waok.webp" alt="Four guardrails: permission prompts before edits and commands, sandboxed execution in a container or VM, scoped tool/MCP access with deny-by-default, and a human reviewing the diff before it merges." width="799" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Treat every agent like a new junior developer who somehow has root. Four guardrails make that safe:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Permission prompts.&lt;/strong&gt; Approve edits and shell commands &lt;em&gt;before&lt;/em&gt; they run, not after. All three support this — leave it on, especially for anything that touches the network or the filesystem outside the repo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sandboxed execution.&lt;/strong&gt; Run the agent in a container or a microVM, never directly on your host or anything near production. If it runs &lt;code&gt;rm -rf&lt;/code&gt; or a poisoned dependency’s postinstall, the blast radius should be a throwaway sandbox. For the isolation trade-offs, see &lt;a href="https://www.alekseialeinikov.com/en/blog/topics/devops/microvms-firecracker-vs-gvisor-secure-workloads-2026" rel="noopener noreferrer"&gt;MicroVMs in 2026: Firecracker vs gVisor for Secure Workloads&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scoped tool access.&lt;/strong&gt; An agent’s power comes from the tools it can call. Allow-list them — and if it reaches external tools over MCP, control &lt;em&gt;which&lt;/em&gt; servers and &lt;em&gt;which&lt;/em&gt; tools it can touch, deny-by-default. This is exactly the per-tool permission problem covered in &lt;a href="https://www.alekseialeinikov.com/en/blog/topics/security/user-level-permission-controls-mcp-tool-access-gateway-2026" rel="noopener noreferrer"&gt;User-Level Permission Controls for MCP Tool Access&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human reviews the diff.&lt;/strong&gt; The agent proposes; you decide. Read the change before it commits. The moment you let an agent merge unattended, you’ve replaced code review with faith.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of this is exotic — it’s least-privilege, applied to a very capable new kind of process. The agent that can rewrite your codebase in a minute can also break it in a minute; the guardrails are what turn that speed into leverage instead of a liability.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Field Rule
&lt;/h2&gt;

&lt;p&gt;The three agents are more alike than their marketing suggests: the same plan-act-observe loop, wrapped differently — and the two proprietary ones, Claude Code and Codex, are near-twins that both now run locally and in a managed cloud. So choose on what actually differs — &lt;strong&gt;openness and model lock-in&lt;/strong&gt; — and run whichever you pick like a powerful junior: sandboxed, permission-gated, tool-scoped, and never merging without a human on the button. Claude Code if you live in Claude and want the most polished experience; &lt;strong&gt;Codex if you want OpenAI’s frontier models with a mature cloud agent to hand long, parallel work to&lt;/strong&gt; ; opencode if you refuse lock-in and want open source you control. If you just want a strong set-and-forget default and don’t mind the OpenAI ecosystem, Codex is the easiest one to bet on. Get the guardrails right first, and any of the three becomes leverage instead of a gamble.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://www.alekseialeinikov.com/en/blog/topics/ai/ai-coding-agents-2026-claude-code-vs-codex-vs-opencode" rel="noopener noreferrer"&gt;alekseialeinikov.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aicodingagents</category>
      <category>claudecode</category>
      <category>codex</category>
      <category>opencode</category>
    </item>
    <item>
      <title>KI-Coding-Agents 2026: Claude Code vs Codex vs opencode</title>
      <dc:creator>Aleksei Aleinikov</dc:creator>
      <pubDate>Tue, 14 Jul 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/aleksei_aleinikov/ki-coding-agents-2026-claude-code-vs-codex-vs-opencode-3d99</link>
      <guid>https://dev.to/aleksei_aleinikov/ki-coding-agents-2026-claude-code-vs-codex-vs-opencode-3d99</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frxzygqhnxreu9a0zx3n5.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frxzygqhnxreu9a0zx3n5.webp" alt="KI-Coding-Agents 2026: Claude Code vs Codex vs opencode" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vor zwei Jahren bedeutete KI im Editor Autocomplete: Sie erriet die nächste Zeile, und du drücktest Tab. 2026 bedeutet sie etwas kategorisch anderes — einen &lt;strong&gt;Agent&lt;/strong&gt; , der dein Repo liest, Dateien darüber hinweg ändert, deine Tests ausführt, die Fehler liest und es erneut versucht, alles aus einer einzigen Anweisung. Das Werkzeug hörte auf vorzuschlagen und fing an zu &lt;em&gt;handeln&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Drei Namen dominieren diesen Wandel: &lt;strong&gt;Claude Code&lt;/strong&gt; , &lt;strong&gt;Codex&lt;/strong&gt; und &lt;strong&gt;opencode&lt;/strong&gt;. In einer Demo sehen sie ähnlich aus und werden als Rivalen vermarktet, aber sie setzen auf wirklich unterschiedliche Wetten bei Lock-in, Kontrolle und Offenheit. Das hier ist ein anbieterneutraler Leitfaden dazu, was sie wirklich sind, wie das Ding unter allen funktioniert, und wie man eines wählt — und betreibt — ohne die Schlüssel zu deinem Codebestand abzugeben.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zuerst: Was ein Coding-Agent wirklich ist
&lt;/h2&gt;

&lt;p&gt;Das Wort „Agent“ wird locker verwendet, also fixieren wir es. Ein Coding-Agent ist nicht ein cleverer Prompt — er ist eine &lt;strong&gt;Schleife&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjzi2ymn40eue64ihi74m.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjzi2ymn40eue64ihi74m.webp" alt="Die Agent-Schleife: Dein Prompt geht ans Modell, das einen Schritt plant, Tools zum Lesen/Ändern von Dateien und Ausführen von Befehlen aufruft, das Ergebnis beobachtet und wiederholt, bis die Aufgabe erledigt ist und es dir einen Diff zeigt." width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Du gibst ein Ziel vor — &lt;em&gt;„füge JWT-Auth zur API hinzu.“&lt;/em&gt; Dann:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Das Modell plant&lt;/strong&gt; den nächsten konkreten Schritt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Es handelt&lt;/strong&gt; — ruft Tools auf, um Dateien zu lesen, Code zu ändern, einen Befehl auszuführen, das Repo zu durchsuchen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Es beobachtet&lt;/strong&gt; das Ergebnis — Testausgabe, einen Stacktrace, den neuen Dateiinhalt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Es wiederholt&lt;/strong&gt; — führt das zurück und plant erneut, bis die Aufgabe wirklich erledigt ist.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Es stoppt&lt;/strong&gt; und zeigt dir einen Diff zum Prüfen und Freigeben.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Diese Schleife ist die ganze Idee, und deshalb ist ein Agent zugleich mächtig und riskant: &lt;strong&gt;zwischen deinem Prompt und dem Ergebnis handelt er eigenständig.&lt;/strong&gt; Autocomplete konnte nur vorschlagen; ein Agent ändert deine Dateien und führt deine Shell aus. Jedes Werkzeug unten ist eine andere Hülle um genau diese Schleife.&lt;/p&gt;

&lt;h2&gt;
  
  
  Die drei, die zählen
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Claude Code&lt;/strong&gt; — Anthropics Agent. Er begann als Terminal-Tool und läuft heute über Terminal, IDE, Desktop-App und den Browser — inklusive verwalteter Cloud-Sitzungen, die lange Aufgaben parallel abarbeiten, auch wenn deine Maschine aus ist. Er ist an Claude-Modelle gebunden, Closed Source, MCP-nativ und fragt vor Änderungen und Befehlen um Erlaubnis. Wenn du Claude für Code bereits vertraust, ist er der ausgereifteste Weg, es handeln zu lassen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Codex&lt;/strong&gt; — OpenAIs Coding-Agent, und der, der die Schleife am weitesten treibt. Er läuft in zwei Modi: einem &lt;strong&gt;Cloud-Agent&lt;/strong&gt; , der lange Aufgaben in einer isolierten, verwalteten Sandbox durcharbeitet — du kannst also mehrere Jobs auf einmal anstößen und weggehen — und einer &lt;strong&gt;lokalen CLI&lt;/strong&gt; fürs Arbeiten direkt an der Tastatur. Er ist an OpenAIs Frontier-Modelle gebunden, die noch immer zu den stärksten bei echtem Code zählen, und sein Cloud-Agent ist ein ausgereifter, isolierter Ort, um lange Arbeit abzugeben. Die CLI ist offen; die Modelle und der verwaltete Dienst sind proprietär. Der Handel ist klar: du akzeptierst das OpenAI-Ökosystem und bekommst dafür eine der stärksten Modell-plus-Cloud-Kombinationen am Markt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;opencode&lt;/strong&gt; — der Open-Source-Ausreißer. Ein Terminal-Agent, der &lt;strong&gt;modellagnostisch&lt;/strong&gt; ist: Du richtest ihn auf den Anbieter, den du willst — Anthropic, OpenAI, Google oder ein lokales Modell — und der Agent selbst ist Open Source, sodass du ihn lesen, erweitern und selbst hosten kannst. Seine Wette lautet: &lt;em&gt;kein Lock-in und volle Auditierbarkeit&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wo jeder sitzt
&lt;/h2&gt;

&lt;p&gt;Streift man Branding ab, trennen sich die drei auf zwei Achsen: &lt;strong&gt;wie offen sie sind&lt;/strong&gt; (closed vs Open Source) und &lt;strong&gt;wie stark an einen Modell-Anbieter gebunden&lt;/strong&gt;. Beachte, was &lt;em&gt;keine&lt;/em&gt; Achse mehr ist: wo es läuft. Sowohl Claude Code als auch Codex laufen inzwischen lokal &lt;em&gt;und&lt;/em&gt; bieten eine verwaltete Cloud — das hörte auf, die Trennlinie zu sein.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq1kw3zmweuyjs0mi29tb.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq1kw3zmweuyjs0mi29tb.webp" alt="Positionierungsmatrix auf zwei Achsen — closed vs Open Source und an einen Anbieter gebunden vs beliebiges Modell. Claude Code und Codex sitzen zusammen in der closed, anbietergebundenen Ecke und laufen beide lokal und in einer verwalteten Cloud; opencode sitzt allein in der offenen Ecke mit beliebigem Modell." width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dieselbe Entscheidung als Tabelle:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Claude Code&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Codex&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;opencode&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Anbieter&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Anthropic&lt;/td&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;Open Source (Community)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Modelle&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Nur Claude&lt;/td&gt;
&lt;td&gt;Nur OpenAI&lt;/td&gt;
&lt;td&gt;Beliebig — bring dein eigenes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Wo es läuft&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Lokal + verwaltete Cloud&lt;/td&gt;
&lt;td&gt;Lokale CLI + verwaltete Cloud&lt;/td&gt;
&lt;td&gt;Lokal / selbst gehostet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Offenheit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Closed&lt;/td&gt;
&lt;td&gt;CLI offen, Dienst/Modell closed&lt;/td&gt;
&lt;td&gt;Vollständig Open Source&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MCP-Support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Nativ&lt;/td&gt;
&lt;td&gt;Ja&lt;/td&gt;
&lt;td&gt;Ja&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Auditierbarkeit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Anbieter vertrauen&lt;/td&gt;
&lt;td&gt;Anbieter vertrauen&lt;/td&gt;
&lt;td&gt;Quellcode lesen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Am besten für&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Tiefe Claude-Nutzer, ausgereift auf allen Oberflächen&lt;/td&gt;
&lt;td&gt;Lange Aufgaben delegieren &amp;amp; parallelisieren, händefreie Cloud-Läufe&lt;/td&gt;
&lt;td&gt;Lock-in vermeiden, lokal, selbst hosten&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Das Muster ist klar: Die beiden proprietären Agents clustern zusammen — ausgereift, modellgebunden, anbietervertrauensbasiert — und &lt;strong&gt;opencode ist das bewusste Gegengewicht&lt;/strong&gt; für Teams, die Modell-Lock-in ablehnen oder auditieren müssen, was der Agent tut.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wie man wirklich wählt
&lt;/h2&gt;

&lt;p&gt;Ignoriere die Demos; alle sehen zehn Minuten lang magisch aus. Wähle nach drei echten Einschränkungen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Modell-Lock-in.&lt;/strong&gt; Willst du an eine Modellfamilie gebunden sein? Claude Code bindet dich an Claude, Codex an OpenAI. opencode lässt dich Modelle tauschen — inklusive eines lokalen Modells für sensiblen Code — ohne deinen Workflow zu ändern.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wo es läuft.&lt;/strong&gt; Das trennte sie früher, aber nicht mehr: Sowohl Claude Code als auch Codex laufen lokal &lt;em&gt;und&lt;/em&gt; bieten eine verwaltete Cloud, die lange, parallele Aufgaben abarbeitet, während du etwas anderes tust. opencode ist das lokale / selbst gehostete — gar keine Anbieter-Cloud, was genau der Punkt ist, wenn du alles auf deiner eigenen Infrastruktur brauchst. Wähle also nicht nach „lokal vs Cloud“, sondern danach, wessen Cloud du überhaupt Code anvertrauen willst.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offenheit und Auditierbarkeit.&lt;/strong&gt; In einem regulierten oder sicherheitskritischen Umfeld ist „wir können genau lesen, was der Agent tut“ kein Nice-to-have. Das ist opencodes Heimspiel; die proprietären Tools verlangen stattdessen Vertrauen in den Anbieter.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In der Praxis sind die Wechselkosten niedrig — die Schleife ist überall dieselbe — also ist es günstig und oft erhellend, zwei auszuprobieren. Wähle die Voreinstellung, die zu deinen Einschränkungen passt, nicht die mit dem besten Launch-Video.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handeln lassen, ohne von der Leine zu lassen
&lt;/h2&gt;

&lt;p&gt;Hier der Teil, den die Demos überspringen. Ein Coding-Agent ist mechanisch &lt;strong&gt;ein Programm, das deinen Quellcode ändert und Shell-Befehle in deinem Namen ausführt&lt;/strong&gt;. Das ist enorme Hebelwirkung und eine echte Angriffsfläche. Der Fehlerfall ist nicht ein dummes Modell — es ist ein &lt;em&gt;fähiges&lt;/em&gt; und &lt;em&gt;unbeaufsichtigtes&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9ovvjvrui2x26at4waok.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9ovvjvrui2x26at4waok.webp" alt="Vier Leitplanken: Berechtigungsabfragen vor Änderungen und Befehlen, Sandbox-Ausführung in Container oder VM, eingegrenzter Tool-/MCP-Zugriff mit Deny-by-default, und ein Mensch, der den Diff vor dem Merge prüft." width="799" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Behandle jeden Agent wie einen neuen Junior-Entwickler, der irgendwie Root hat. Vier Leitplanken machen das sicher:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Berechtigungsabfragen.&lt;/strong&gt; Genehmige Änderungen und Shell-Befehle &lt;em&gt;bevor&lt;/em&gt; sie laufen, nicht danach. Alle drei unterstützen das — lass es an, besonders für alles, was das Netzwerk oder das Dateisystem außerhalb des Repos berührt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sandbox-Ausführung.&lt;/strong&gt; Betreibe den Agent in einem Container oder einer microVM, nie direkt auf deinem Host oder nahe der Produktion. Führt er &lt;code&gt;rm -rf&lt;/code&gt; oder das Postinstall einer vergifteten Abhängigkeit aus, sollte der Schadensradius eine Wegwerf-Sandbox sein. Zu den Isolations-Trade-offs siehe &lt;a href="https://www.alekseialeinikov.com/de/blog/topics/devops/microvms-firecracker-vs-gvisor-sichere-workloads-2026" rel="noopener noreferrer"&gt;MicroVMs 2026: Firecracker vs gVisor für sichere Workloads&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Eingegrenzter Tool-Zugriff.&lt;/strong&gt; Die Macht eines Agents kommt aus den Tools, die er aufrufen kann. Erlaube sie per Allow-List — und erreicht er externe Tools über MCP, kontrolliere &lt;em&gt;welche&lt;/em&gt; Server und &lt;em&gt;welche&lt;/em&gt; Tools er berühren darf, deny-by-default. Genau dieses Pro-Tool-Berechtigungsproblem behandelt &lt;a href="https://www.alekseialeinikov.com/de/blog/topics/security/benutzerbezogene-zugriffskontrolle-mcp-tools-gateway-2026" rel="noopener noreferrer"&gt;Benutzerbezogene Zugriffskontrolle für MCP-Tools&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ein Mensch prüft den Diff.&lt;/strong&gt; Der Agent schlägt vor; du entscheidest. Lies die Änderung, bevor sie committet. In dem Moment, in dem du einen Agent unbeaufsichtigt mergen lässt, hast du Code-Review durch Glauben ersetzt.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nichts davon ist exotisch — es ist Least-Privilege, angewandt auf eine sehr fähige neue Art von Prozess. Der Agent, der deinen Codebestand in einer Minute umschreiben kann, kann ihn auch in einer Minute kaputt machen; die Leitplanken verwandeln dieses Tempo in Hebelwirkung statt in ein Risiko.&lt;/p&gt;

&lt;h2&gt;
  
  
  Die Feldregel
&lt;/h2&gt;

&lt;p&gt;Die drei Agents sind sich ähnlicher, als ihr Marketing suggeriert: dieselbe Plan-Handeln-Beobachten-Schleife, anders verpackt — und die beiden proprietären, Claude Code und Codex, sind Beinahe-Zwillinge, die beide inzwischen lokal und in einer verwalteten Cloud laufen. Wähle also nach dem, was wirklich unterschiedlich ist — &lt;strong&gt;Offenheit und Modell-Lock-in&lt;/strong&gt; — und betreibe das Gewählte wie einen mächtigen Junior: sandboxed, berechtigungsgesteuert, tool-eingegrenzt, und niemals mergend ohne einen Menschen am Knopf. Claude Code, wenn du in Claude lebst und das ausgereifteste Erlebnis willst; &lt;strong&gt;Codex, wenn du OpenAIs Frontier-Modelle mit einem ausgereiften Cloud-Agent willst, an den du lange, parallele Arbeit übergibst&lt;/strong&gt; ; opencode, wenn du Lock-in ablehnst und Open Source willst, den du kontrollierst. Willst du einfach einen starken Set-and-forget-Standard und störst dich nicht am OpenAI-Ökosystem, ist Codex die einfachste Wette. Bring zuerst die Leitplanken in Ordnung, und jeder der drei wird zur Hebelwirkung statt zum Glücksspiel.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ursprünglich veröffentlicht auf &lt;a href="https://www.alekseialeinikov.com/de/blog/topics/ai/ki-coding-agents-2026-claude-code-vs-codex-vs-opencode" rel="noopener noreferrer"&gt;alekseialeinikov.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aicodingagents</category>
      <category>claudecode</category>
      <category>codex</category>
      <category>opencode</category>
    </item>
    <item>
      <title>Cloud Bigtable 2026: Wann Wide-Column BigQuery, Spanner und Cassandra schlägt</title>
      <dc:creator>Aleksei Aleinikov</dc:creator>
      <pubDate>Mon, 13 Jul 2026 15:00:00 +0000</pubDate>
      <link>https://dev.to/aleksei_aleinikov/cloud-bigtable-2026-wann-wide-column-bigquery-spanner-und-cassandra-schlagt-1711</link>
      <guid>https://dev.to/aleksei_aleinikov/cloud-bigtable-2026-wann-wide-column-bigquery-spanner-und-cassandra-schlagt-1711</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flrv2b0j0uk74co14egnw.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flrv2b0j0uk74co14egnw.webp" alt="Cloud Bigtable 2026: Wann Wide-Column BigQuery, Spanner und Cassandra schlägt" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bigtable ist die am meisten missverstandene Datenbank in Google Cloud. Teams greifen zu BigQuery, wenn sie Bigtable brauchen, schrauben ein Analytics-Warehouse an einen Workload, der nur schnelle Key-Lookups will, und wundern sich dann, warum Rechnung und Latenz beide in die falsche Richtung liefen. Andere hören „NoSQL in Google-Größe“ und werfen Bigtable auf ein Problem, das eigentlich relationale Transaktionen brauchte.&lt;/p&gt;

&lt;p&gt;Die Verwirrung ist verständlich — die Namen verschwimmen, und auf jedem steht „Petabytes“. Aber diese Engines lösen wirklich unterschiedliche Probleme, und die falsche zu wählen ist auf eine Weise teuer, die man jahrelang spürt. Das hier ist ein praktischer Leitfaden dazu, was Cloud Bigtable wirklich ist, wann es BigQuery, Spanner, Cassandra und DynamoDB schlägt, und die eine Design-Entscheidung, die bestimmt, ob es fliegt oder abstürzt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Was Bigtable wirklich ist
&lt;/h2&gt;

&lt;p&gt;Bigtable ist ein &lt;strong&gt;Wide-Column-NoSQL-Store&lt;/strong&gt; : eine einzige, riesige Tabelle, in der jede Zeile über einen &lt;strong&gt;Row Key&lt;/strong&gt; adressiert wird und Spalten spärlich sind und in &lt;strong&gt;Column Families&lt;/strong&gt; gruppiert werden. Es stammt direkt vom Bigtable-Paper von 2006 ab, das HBase, Cassandra und einen Großteil der NoSQL-Ära inspirierte — und dieselben Kernideen erklären sein Verhalten bis heute.&lt;/p&gt;

&lt;p&gt;Unter der Haube zählen drei Dinge:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4zhyi08pwu6pi22hqg97.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4zhyi08pwu6pi22hqg97.webp" alt="Wie Bigtable funktioniert: eine sortierte Wide-Column-Tabelle, aufgeteilt in Tablets, je von einem Node bedient, gestützt auf immutable SSTables auf Colossus-Speicher, der von Compute getrennt ist." width="799" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Zeilen werden nach Row Key sortiert gespeichert.&lt;/strong&gt; Die Tabelle ist ein langer, lexikografisch geordneter Keyspace — deshalb sind Range-Scans günstig und deshalb zählt das Key-Design so sehr (dazu unten mehr).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Die Tabelle wird in Tablets aufgeteilt.&lt;/strong&gt; Zusammenhängende Zeilenbereiche bilden &lt;em&gt;Tablets&lt;/em&gt;, und jedes Tablet wird von genau einem Node bedient. Füge Nodes hinzu, und Bigtable verteilt Tablets automatisch neu.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speicher ist von Compute getrennt.&lt;/strong&gt; Daten liegen als immutable &lt;strong&gt;SSTables&lt;/strong&gt; auf Colossus, Googles verteiltem Dateisystem. Nodes bedienen Requests; sie besitzen die Daten nicht. Diese Trennung ist der Grund, warum du Durchsatz durch Hinzufügen von Nodes skalierst, ohne je ein Byte zu verschieben — und warum Bigtable von Gigabytes bis Petabytes einstellige Millisekunden-Latenz hält.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Das ist das ganze mentale Modell: eine sortierte Wide-Column-Tabelle, in Tablets zerlegt, bedient von einer dünnen Compute-Schicht über dauerhaftem Speicher. Alles, worin Bigtable gut und schlecht ist, folgt daraus.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wo es passt: Bigtable vs BigQuery vs Spanner vs Cassandra
&lt;/h2&gt;

&lt;p&gt;Am schnellsten wählst du richtig, indem du jede Engine danach einordnest, &lt;em&gt;wie du auf die Daten zugreifst&lt;/em&gt;, nicht nach dem Marketing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4egfp3kq0dgn7dar3yjw.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4egfp3kq0dgn7dar3yjw.webp" alt="Positionierungsmatrix: Bigtable und Cassandra/DynamoDB liegen bei Key-/Punktzugriff + Wide-Column-NoSQL; Spanner ergänzt SQL und Transaktionen; BigQuery deckt Full-Table-Analytics ab." width="799" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Bigtable&lt;/strong&gt; — Punkt-/Key-Zugriff, Wide-Column-NoSQL. Durchsatzstarke Reads und Writes per Row Key, einstellige ms-Latenz, Single-Row-Atomarität.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Spanner&lt;/strong&gt; — Punkt-/Key-Zugriff, aber &lt;em&gt;relational&lt;/em&gt; mit SQL und starken Multi-Row-Transaktionen. Diese Korrektheit kostet pro Operation mehr.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BigQuery&lt;/strong&gt; — die entgegengesetzte Ecke: analytische Full-Table-Scans mit SQL. Hervorragend für Aggregationen über Milliarden Zeilen, falsch fürs schnelle Holen einer einzelnen Zeile.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cassandra / DynamoDB&lt;/strong&gt; — dieselbe Wide-Column-Familie wie Bigtable, die man auf AWS/Azure oder in einem bestimmten Hybrid-Setup wählt.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dieselbe Entscheidung als Tabelle:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Cloud Bigtable&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;BigQuery&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Cloud Spanner&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Cassandra / DynamoDB&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Datenmodell&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Wide-Column-NoSQL (spärlich)&lt;/td&gt;
&lt;td&gt;Spaltenbasiertes Warehouse&lt;/td&gt;
&lt;td&gt;Relational (SQL)&lt;/td&gt;
&lt;td&gt;Wide-Column-NoSQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Am besten für&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Durchsatzstarke Key-Reads/Writes&lt;/td&gt;
&lt;td&gt;Ad-hoc-Analytics über riesige Scans&lt;/td&gt;
&lt;td&gt;Globale, stark-konsistente Transaktionen&lt;/td&gt;
&lt;td&gt;Key-Reads/Writes außerhalb GCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Query&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Key- + Range-Scans, keine Joins&lt;/td&gt;
&lt;td&gt;Volles SQL, Joins, Aggregate&lt;/td&gt;
&lt;td&gt;Volles SQL + Transaktionen&lt;/td&gt;
&lt;td&gt;Key/CQL-API, keine Joins&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Transaktionen&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Nur Single-Row-atomar&lt;/td&gt;
&lt;td&gt;Keine (Analytics)&lt;/td&gt;
&lt;td&gt;Multi-Row, externe Konsistenz&lt;/td&gt;
&lt;td&gt;Single-Row / leichtgewichtig&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Latenz&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Einstellige ms in jedem Maßstab&lt;/td&gt;
&lt;td&gt;Sekunden (Scan-basiert)&lt;/td&gt;
&lt;td&gt;Niedrige ms (höher als Bigtable)&lt;/td&gt;
&lt;td&gt;Einstellige ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Skalierung&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Petabytes, linear mit Nodes&lt;/td&gt;
&lt;td&gt;Petabytes, serverless&lt;/td&gt;
&lt;td&gt;Petabytes, global&lt;/td&gt;
&lt;td&gt;Petabytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Wählen bei&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Zeitreihen, IoT, Adtech, ML-Features&lt;/td&gt;
&lt;td&gt;Du brauchst SQL-Analytics, keine Punkt-Reads&lt;/td&gt;
&lt;td&gt;Du brauchst relational + starke Txn&lt;/td&gt;
&lt;td&gt;Du bist auf AWS/Azure oder hybrid&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Das Muster ist klar: &lt;strong&gt;Bigtable gehört der Punktzugriff im großen Maßstab.&lt;/strong&gt; Sobald du SQL-Analytics brauchst, ist das BigQuery; sobald du relationale Transaktionen brauchst, ist das Spanner. Wenn du für die Analytics-Seite noch zwischen den beiden Warehouses wählst, sind die Trade-offs hier aufgeschlüsselt: &lt;a href="https://www.alekseialeinikov.com/de/blog/topics/data/bigquery-vs-snowflake-2026-ehrlicher-vergleich" rel="noopener noreferrer"&gt;BigQuery vs Snowflake 2026: Ein ehrlicher Vergleich&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wann Bigtable die richtige Wahl ist
&lt;/h2&gt;

&lt;p&gt;Bigtable glänzt, wenn ein Workload ein &lt;strong&gt;bekanntes Key-Zugriffsmuster und eine sehr hohe Lese-/Schreibrate&lt;/strong&gt; hat. Die klassischen Fälle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zeitreihen und Monitoring&lt;/strong&gt; — Metriken, Events und Sensordaten, kontinuierlich geschrieben und nach Entität + Zeitbereich zurückgelesen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IoT&lt;/strong&gt; — Millionen Geräte, die je Daten anhängen; Bigtable schluckt die Schreib-Feuerwehr ohne Latenzeinbruch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adtech und Personalisierung&lt;/strong&gt; — Nutzerprofile und Echtzeit-Bidding-State, in Millisekunden abgerufen, milliardenfach am Tag.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Finanz-/Betriebsdaten&lt;/strong&gt; — hochvolumige transaktionale &lt;em&gt;Datensätze&lt;/em&gt; (keine Multi-Row-Transaktionen) wie Tick-Daten oder Ledger.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ML-Feature-Stores&lt;/strong&gt; — Feature-Lookups mit niedriger Latenz zur Serving-Zeit, in einem Maßstab, der eine relationale Datenbank ins Schwitzen brächte.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Der rote Faden: Du kennst den Key, brauchst die Antwort schnell, und es gibt viel Traffic. Ist das dein Workload und brauchst du keine Joins oder Multi-Row-Transaktionen, ist Bigtable schwer zu schlagen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Der Row Key ist das ganze Spiel
&lt;/h2&gt;

&lt;p&gt;Alles Gute an Bigtable hängt an einer Entscheidung: dem &lt;strong&gt;Row Key&lt;/strong&gt;. Weil Zeilen sortiert gespeichert und nach zusammenhängenden Bereichen in Tablets aufgeteilt werden, bestimmt der Key, &lt;em&gt;welcher Node&lt;/em&gt; jeden Write bearbeitet. Machst du ihn falsch, hebelst du die gesamte Architektur aus.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8plab026y1vre8jbm5k0.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8plab026y1vre8jbm5k0.webp" alt="Row-Key-Design: sequenzielle Keys schicken jeden Write an einen heißen Node, während andere untätig sind; ein hochkardinales Präfix verteilt Writes gleichmäßig, sodass der Durchsatz linear skaliert." width="799" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Die Falle sind &lt;strong&gt;sequenzielle Keys&lt;/strong&gt; — ein roher Zeitstempel, ein hochzählender Counter, alles Monotone. Jeder neue Write sortiert sich ans Ende des Keyspace, also landet jeder Write im &lt;em&gt;selben&lt;/em&gt; Tablet, also nimmt &lt;em&gt;ein Node&lt;/em&gt; 100 % der Schreiblast, während der Rest untätig bleibt. Du hast ein Hundert-Node-Cluster gekauft und nutzt eines. Das ist der Bigtable-Performance-Bug Nummer eins — und komplett selbstverschuldet.&lt;/p&gt;

&lt;p&gt;Die Lösung ist ein &lt;strong&gt;hochkardinales Präfix&lt;/strong&gt; , das Writes über den Keyspace verteilt:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Field Promotion&lt;/strong&gt; — setze ein hochkardinales Attribut (wie &lt;code&gt;device_id&lt;/code&gt; oder &lt;code&gt;user_id&lt;/code&gt;) &lt;em&gt;vor&lt;/em&gt; den Zeitstempel: &lt;code&gt;device123#2026-07-13T10:00&lt;/code&gt;. Writes streuen jetzt über Geräte statt sich auf „jetzt“ zu türmen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Salting&lt;/strong&gt; — stell einen Hash-Bucket voran (&lt;code&gt;03#…&lt;/code&gt;), sodass Writes rundlaufend über N Tablets verteilt werden.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hashing / Umkehren&lt;/strong&gt; — kehre eine sequenzielle ID um oder hashe sie, sodass benachbarte Werte weit auseinanderliegen.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In der Praxis ist der Key ein zusammengesetzter String, und die Reihenfolge seiner Teile ist die ganze Entscheidung:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terminal window&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Gut: hochkardinales Präfix zuerst, dann umgekehrter Zeitstempel&lt;/span&gt;
&lt;span class="c"&gt;# device123#20260713T0959 → Writes streuen über Geräte&lt;/span&gt;
&lt;span class="c"&gt;# Schlecht: der Zeitstempel führt&lt;/span&gt;
&lt;span class="c"&gt;# 20260713T1000#device123 → jeder Write türmt sich auf "jetzt"&lt;/span&gt;

cbt createtable metrics &lt;span class="nv"&gt;families&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;m

cbt &lt;span class="nb"&gt;set &lt;/span&gt;metrics &lt;span class="s2"&gt;"device123#20260713T0959"&lt;/span&gt; m:temp&lt;span class="o"&gt;=&lt;/span&gt;21.4

cbt &lt;span class="nb"&gt;read &lt;/span&gt;metrics &lt;span class="nv"&gt;prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"device123#"&lt;/span&gt; &lt;span class="c"&gt;# schneller Range-Scan, ein Gerät&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Das Ziel ist immer dasselbe: &lt;strong&gt;Writes verteilen, nicht nach Zeit sortieren.&lt;/strong&gt; Halte zusammengehörige Daten nah genug, damit deine üblichen Range-Scans effizient bleiben, aber lass nie die „neuesten“ Zeilen alle auf ein Tablet fallen. In Bigtable ist der Row Key kein bloßer Bezeichner — er &lt;em&gt;ist&lt;/em&gt; das Performance-Modell.&lt;/p&gt;

&lt;h2&gt;
  
  
  Drei weitere Dinge, die in der Produktion beißen
&lt;/h2&gt;

&lt;p&gt;Das Row-Key-Design ist das große Thema, aber drei Einschränkungen erwischen Teams beim ersten Mal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Es gibt keine Sekundärindizes.&lt;/strong&gt; Du kannst nur per Row Key nachschlagen, also entwirfst du den Key für deinen primären Read — und für ein zweites Zugriffsmuster speicherst du &lt;em&gt;dieselben&lt;/em&gt; Daten oft erneut unter einem anderen Key oder in einer zweiten Tabelle. Plane bewusste Denormalisierung ein; ein ad-hoc &lt;code&gt;WHERE&lt;/code&gt; auf einer Nicht-Key-Spalte gibt es nicht.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Konsistenz hängt vom Cluster-Setup ab.&lt;/strong&gt; Eine Single-Cluster-Instanz ist stark konsistent. Multi-Cluster-Replikation ist &lt;em&gt;eventuell&lt;/em&gt; konsistent, und du steuerst den Traffic mit App-Profiles. Brauchst du starke Konsistenz über Regionen, ist das Spanner, nicht Bigtable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Du zahlst für Nodes × Zeit, plus Speicher.&lt;/strong&gt; Durchsatz wird bereitgestellt: untätige Nodes kosten trotzdem, also dimensioniere auf die Dauerlast und nutze Autoscaling für Spitzen. Und halte Zeilen &lt;em&gt;hoch, nicht breit&lt;/em&gt; — modelliere Events als viele Zeilen und halte jede einzelne Zeile deutlich unter dem ~256-MB-Limit, statt eine riesige Zeile wachsen zu lassen.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wann man Bigtable NICHT nutzen sollte
&lt;/h2&gt;

&lt;p&gt;Bigtable ist ein Spezialist, und der falsche Workload macht es schmerzhaft:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Du brauchst SQL-Analytics, Joins oder Ad-hoc-Aggregation&lt;/strong&gt; → das ist BigQuery. Bigtable scannt und gruppiert dir keine Milliarden Zeilen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Du brauchst Multi-Row-Transaktionen oder ein relationales Schema&lt;/strong&gt; → das ist Spanner. Bigtable garantiert Atomarität nur pro Zeile.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Du hast kleine Daten oder moderaten Traffic&lt;/strong&gt; → das Mindest-Cluster und das Betriebsmodell sind Overkill. Ein verwaltetes Postgres (Cloud SQL / AlloyDB) ist einfacher und günstiger.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dein Zugriffsmuster ist unvorhersehbar und query-getrieben&lt;/strong&gt; → ohne klares Key-Zugriffsmuster kämpfst du gegen das Row-Key-Modell, statt es zu reiten.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bigtable verdient sein Geld im großen Maßstab, auf einem bekannten Key. Darunter gewinnen einfachere Werkzeuge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Die Feldregel
&lt;/h2&gt;

&lt;p&gt;Passe die Engine an das Zugriffsmuster an, nicht an das „Petabytes“-Etikett. Bigtable für durchsatzstarken Punktzugriff auf einem bekannten Key; BigQuery für SQL-Analytics über riesige Scans; Spanner für relationale Transaktionen; Cassandra oder DynamoDB, wenn du außerhalb von Google Cloud bist. Und wenn du Bigtable wählst, verbring deine Design-Zeit mit dem Row Key — verteile Writes, halte Scans knapp und sortiere deinen Keyspace nie nach Zeit. Alles andere am Skalieren von Bigtable erledigt sich von selbst; der Row Key ist der Teil, den nur du richtig hinbekommen kannst.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Bigtable steht selten allein — meist sitzt es hinter einem Strom von Events, der es mit Writes füttert. Um diesen Ingestion-Pfad sauber zu halten, siehe &lt;a href="https://www.alekseialeinikov.com/de/blog/topics/architecture/pubsub-oder-eventarc-2026-event-driven-gcp-ohne-spaghetti" rel="noopener noreferrer"&gt;Pub/Sub oder Eventarc? Event-getriebenes GCP ohne Spaghetti&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Ursprünglich veröffentlicht auf &lt;a href="https://www.alekseialeinikov.com/de/blog/topics/data/cloud-bigtable-2026-wann-wide-column-bigquery-spanner-cassandra-schlaegt" rel="noopener noreferrer"&gt;alekseialeinikov.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cloudbigtable</category>
      <category>bigtable</category>
      <category>widecolumndatabase</category>
      <category>nosql</category>
    </item>
    <item>
      <title>Cloud Bigtable in 2026: When Wide-Column Beats BigQuery, Spanner, and Cassandra</title>
      <dc:creator>Aleksei Aleinikov</dc:creator>
      <pubDate>Mon, 13 Jul 2026 15:00:00 +0000</pubDate>
      <link>https://dev.to/aleksei_aleinikov/cloud-bigtable-in-2026-when-wide-column-beats-bigquery-spanner-and-cassandra-4gh8</link>
      <guid>https://dev.to/aleksei_aleinikov/cloud-bigtable-in-2026-when-wide-column-beats-bigquery-spanner-and-cassandra-4gh8</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flrv2b0j0uk74co14egnw.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flrv2b0j0uk74co14egnw.webp" alt="Cloud Bigtable in 2026: When Wide-Column Beats BigQuery, Spanner, and Cassandra" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bigtable is the most misunderstood database on Google Cloud. Teams reach for BigQuery when they need Bigtable, bolt an analytics warehouse onto a workload that just wants fast key lookups, and then wonder why the bill and the latency both went the wrong way. Others hear “NoSQL at Google scale” and throw Bigtable at a problem that actually needed relational transactions.&lt;/p&gt;

&lt;p&gt;The confusion is understandable — the names all blur together, and every one of them says “petabytes” on the tin. But these engines solve genuinely different problems, and picking the wrong one is expensive in a way you feel for years. This is a practical guide to what Cloud Bigtable actually is, when it beats BigQuery, Spanner, Cassandra and DynamoDB, and the single design decision that determines whether it flies or falls over.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Bigtable Actually Is
&lt;/h2&gt;

&lt;p&gt;Bigtable is a &lt;strong&gt;wide-column NoSQL store&lt;/strong&gt; : a single, enormous table where each row is addressed by one &lt;strong&gt;row key&lt;/strong&gt; , and columns are sparse and grouped into &lt;strong&gt;column families&lt;/strong&gt;. It descends directly from the 2006 Bigtable paper that inspired HBase, Cassandra, and much of the NoSQL era — and the same core ideas still explain how it behaves today.&lt;/p&gt;

&lt;p&gt;Under the hood, three things matter:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4zhyi08pwu6pi22hqg97.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4zhyi08pwu6pi22hqg97.webp" alt="How Bigtable works: one sorted wide-column table split into tablets, each served by a node, all backed by immutable SSTables on Colossus storage that is separated from compute." width="799" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Rows are stored sorted by row key.&lt;/strong&gt; The table is one long, lexicographically ordered keyspace — this is why range scans are cheap and why key design matters so much (more on that below).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The table is split into tablets.&lt;/strong&gt; Contiguous ranges of rows form &lt;em&gt;tablets&lt;/em&gt;, and each tablet is served by exactly one node. Add nodes and Bigtable rebalances tablets across them automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage is separated from compute.&lt;/strong&gt; Data lives as immutable &lt;strong&gt;SSTables&lt;/strong&gt; on Colossus, Google’s distributed file system. Nodes serve requests; they don’t own the data. That separation is why you scale throughput by adding nodes without ever moving a byte of data — and why Bigtable holds single-digit-millisecond latency from gigabytes to petabytes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is the whole mental model: a sorted wide-column table, sharded into tablets, served by a thin compute layer over durable storage. Everything Bigtable is good and bad at follows from it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where It Fits: Bigtable vs BigQuery vs Spanner vs Cassandra
&lt;/h2&gt;

&lt;p&gt;The fastest way to pick right is to place each engine by &lt;em&gt;how you access the data&lt;/em&gt;, not by the marketing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4egfp3kq0dgn7dar3yjw.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4egfp3kq0dgn7dar3yjw.webp" alt="Positioning matrix: Bigtable and Cassandra/DynamoDB sit in key/point access + wide-column NoSQL; Spanner adds SQL and transactions; BigQuery covers full-table analytics." width="799" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Bigtable&lt;/strong&gt; — point/key access, wide-column NoSQL. High-throughput reads and writes by row key, single-digit-ms latency, single-row atomicity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Spanner&lt;/strong&gt; — point/key access, but &lt;em&gt;relational&lt;/em&gt; with SQL and strong multi-row transactions. You pay more per operation for that correctness.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BigQuery&lt;/strong&gt; — the opposite corner: full-table analytical scans with SQL. Superb for aggregations over billions of rows, wrong for fetching one row fast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cassandra / DynamoDB&lt;/strong&gt; — the same wide-column family as Bigtable, the ones you reach for on AWS/Azure or in a specific hybrid setup.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is the same decision as a table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Cloud Bigtable&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;BigQuery&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Cloud Spanner&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Cassandra / DynamoDB&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Wide-column NoSQL (sparse)&lt;/td&gt;
&lt;td&gt;Columnar warehouse&lt;/td&gt;
&lt;td&gt;Relational (SQL)&lt;/td&gt;
&lt;td&gt;Wide-column NoSQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best at&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High-throughput key reads/writes&lt;/td&gt;
&lt;td&gt;Ad-hoc analytics over huge scans&lt;/td&gt;
&lt;td&gt;Global, strongly-consistent transactions&lt;/td&gt;
&lt;td&gt;Key reads/writes off-GCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Query&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Key + range scans, no joins&lt;/td&gt;
&lt;td&gt;Full SQL, joins, aggregates&lt;/td&gt;
&lt;td&gt;Full SQL + transactions&lt;/td&gt;
&lt;td&gt;Key/CQL API, no joins&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Transactions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Single-row atomic only&lt;/td&gt;
&lt;td&gt;None (analytics)&lt;/td&gt;
&lt;td&gt;Multi-row, external consistency&lt;/td&gt;
&lt;td&gt;Single-row / lightweight&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Latency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Single-digit ms at any scale&lt;/td&gt;
&lt;td&gt;Seconds (scan-based)&lt;/td&gt;
&lt;td&gt;Low ms (higher than Bigtable)&lt;/td&gt;
&lt;td&gt;Single-digit ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scale&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Petabytes, linear with nodes&lt;/td&gt;
&lt;td&gt;Petabytes, serverless&lt;/td&gt;
&lt;td&gt;Petabytes, global&lt;/td&gt;
&lt;td&gt;Petabytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pick when&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Time-series, IoT, adtech, ML features&lt;/td&gt;
&lt;td&gt;You need SQL analytics, not point reads&lt;/td&gt;
&lt;td&gt;You need relational + strong txn&lt;/td&gt;
&lt;td&gt;You are on AWS/Azure or hybrid&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The pattern is clear: &lt;strong&gt;Bigtable owns point access at massive scale.&lt;/strong&gt; The moment you need SQL analytics, that is BigQuery; the moment you need relational transactions, that is Spanner. If you are still choosing between the two warehouses for the analytics side, the trade-offs are laid out in &lt;a href="https://www.alekseialeinikov.com/en/blog/topics/data/bigquery-vs-snowflake-2026-honest-comparison" rel="noopener noreferrer"&gt;BigQuery vs Snowflake in 2026: An Honest Comparison&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Bigtable Is the Right Call
&lt;/h2&gt;

&lt;p&gt;Bigtable shines when a workload has a &lt;strong&gt;known key access pattern and a very high read/write rate&lt;/strong&gt;. The classic fits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Time-series and monitoring&lt;/strong&gt; — metrics, events, and sensor readings written continuously and read back by entity + time range.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IoT&lt;/strong&gt; — millions of devices each appending data; Bigtable absorbs the write firehose without breaking latency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adtech and personalization&lt;/strong&gt; — user profiles and real-time bidding state fetched in milliseconds, billions of times a day.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Financial / operational data&lt;/strong&gt; — high-volume transactional &lt;em&gt;records&lt;/em&gt; (not multi-row transactions) like tick data or ledgers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ML feature stores&lt;/strong&gt; — low-latency feature lookups at serving time, at a scale that would make a relational database sweat.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The common thread: you know the key, you need the answer fast, and there is a lot of traffic. If that is your workload and you do not need joins or multi-row transactions, Bigtable is hard to beat.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Row Key Is the Whole Game
&lt;/h2&gt;

&lt;p&gt;Everything good about Bigtable depends on one decision: &lt;strong&gt;the row key&lt;/strong&gt;. Because rows are stored sorted and split into tablets by contiguous range, the key determines &lt;em&gt;which node&lt;/em&gt; handles each write. Get it wrong and you defeat the entire architecture.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8plab026y1vre8jbm5k0.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8plab026y1vre8jbm5k0.webp" alt="Row-key design: sequential keys send every write to one hot node while others sit idle; a high-cardinality prefix spreads writes evenly so throughput scales linearly." width="799" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The trap is &lt;strong&gt;sequential keys&lt;/strong&gt; — a raw timestamp, an auto-incrementing counter, anything monotonic. Every new write sorts to the end of the keyspace, which means every write lands in the &lt;em&gt;same&lt;/em&gt; tablet, which means &lt;em&gt;one node&lt;/em&gt; takes 100% of the write load while the rest sit idle. You bought a hundred-node cluster and you are using one. This is the number-one Bigtable performance bug, and it is entirely self-inflicted.&lt;/p&gt;

&lt;p&gt;The fix is a &lt;strong&gt;high-cardinality prefix&lt;/strong&gt; that spreads writes across the keyspace:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Field promotion&lt;/strong&gt; — put a high-cardinality attribute (like &lt;code&gt;device_id&lt;/code&gt; or &lt;code&gt;user_id&lt;/code&gt;) &lt;em&gt;before&lt;/em&gt; the timestamp: &lt;code&gt;device123#2026-07-13T10:00&lt;/code&gt;. Writes now scatter across devices instead of piling onto “now.”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Salting&lt;/strong&gt; — prepend a hash bucket (&lt;code&gt;03#…&lt;/code&gt;) so writes distribute round-robin across N tablets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hashing / reversing&lt;/strong&gt; — reverse a sequential ID or hash it so adjacent values land far apart.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practice the key is a compound string, and the order of its parts is the whole decision:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terminal window&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Good: high-cardinality prefix first, then a reversed timestamp&lt;/span&gt;
&lt;span class="c"&gt;# device123#20260713T0959 → writes scatter across devices&lt;/span&gt;
&lt;span class="c"&gt;# Bad: the timestamp leads&lt;/span&gt;
&lt;span class="c"&gt;# 20260713T1000#device123 → every write piles onto "now"&lt;/span&gt;

cbt createtable metrics &lt;span class="nv"&gt;families&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;m

cbt &lt;span class="nb"&gt;set &lt;/span&gt;metrics &lt;span class="s2"&gt;"device123#20260713T0959"&lt;/span&gt; m:temp&lt;span class="o"&gt;=&lt;/span&gt;21.4

cbt &lt;span class="nb"&gt;read &lt;/span&gt;metrics &lt;span class="nv"&gt;prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"device123#"&lt;/span&gt; &lt;span class="c"&gt;# fast range scan for one device&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;The goal is always the same: &lt;strong&gt;distribute writes, don’t sort them by time.&lt;/strong&gt; Keep related data close enough that your common range scans stay efficient, but never let the “newest” rows all collapse onto one tablet. In Bigtable, the row key is not just an identifier — it &lt;em&gt;is&lt;/em&gt; the performance model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three More Things That Bite in Production
&lt;/h2&gt;

&lt;p&gt;Row-key design is the big one, but three constraints catch teams the first time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;There are no secondary indexes.&lt;/strong&gt; You can only look up by row key, so you design the key for your primary read — and for a second access pattern you often store the &lt;em&gt;same&lt;/em&gt; data again under a different key or in a second table. Plan for deliberate denormalization; there is no ad-hoc &lt;code&gt;WHERE&lt;/code&gt; on a non-key column.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency depends on your cluster setup.&lt;/strong&gt; A single-cluster instance is strongly consistent. Multi-cluster replication is &lt;em&gt;eventually&lt;/em&gt; consistent, and you steer traffic with app profiles. If you need strong consistency across regions, that is Spanner, not Bigtable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You pay for nodes × time, plus storage.&lt;/strong&gt; Throughput is provisioned: idle nodes still cost money, so size to sustained load and lean on autoscaling for spikes. And keep rows &lt;em&gt;tall, not wide&lt;/em&gt; — model events as many rows and keep any single row well under the ~256 MB limit, instead of growing one giant row.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When NOT to Use Bigtable
&lt;/h2&gt;

&lt;p&gt;Bigtable is a specialist, and the wrong workload makes it painful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;You need SQL analytics, joins, or ad-hoc aggregation&lt;/strong&gt; → that is BigQuery. Bigtable will not scan-and-group billions of rows for you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You need multi-row transactions or a relational schema&lt;/strong&gt; → that is Spanner. Bigtable guarantees atomicity only per row.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You have small data or modest traffic&lt;/strong&gt; → the minimum cluster and operational model are overkill. A managed Postgres (Cloud SQL / AlloyDB) is simpler and cheaper.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your access pattern is unpredictable and query-driven&lt;/strong&gt; → without a clear key access pattern, you will fight the row-key model instead of riding it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bigtable earns its keep at scale, on a known key. Below that bar, simpler tools win.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Field Rule
&lt;/h2&gt;

&lt;p&gt;Match the engine to the access pattern, not to the “petabytes” label. Bigtable for high-throughput point access on a known key; BigQuery for SQL analytics over huge scans; Spanner for relational transactions; Cassandra or DynamoDB when you are off Google Cloud. And if you do pick Bigtable, spend your design time on the row key — distribute writes, keep scans tight, and never sort your keyspace by time. Everything else about scaling Bigtable takes care of itself; the row key is the part only you can get right.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Bigtable rarely lives alone — it usually sits behind a stream of events feeding it writes. For keeping that ingestion path clean, see &lt;a href="https://www.alekseialeinikov.com/en/blog/topics/architecture/pubsub-vs-eventarc-2026-event-driven-gcp-without-spaghetti" rel="noopener noreferrer"&gt;Pub/Sub or Eventarc? Event-Driven GCP Without the Spaghetti&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://www.alekseialeinikov.com/en/blog/topics/data/cloud-bigtable-2026-when-wide-column-beats-bigquery-spanner-cassandra" rel="noopener noreferrer"&gt;alekseialeinikov.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cloudbigtable</category>
      <category>bigtable</category>
      <category>widecolumndatabase</category>
      <category>nosql</category>
    </item>
    <item>
      <title>Wie man 1.000.000 Benachrichtigungen versendet, ohne abzustürzen</title>
      <dc:creator>Aleksei Aleinikov</dc:creator>
      <pubDate>Mon, 13 Jul 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/aleksei_aleinikov/wie-man-1000000-benachrichtigungen-versendet-ohne-abzusturzen-1p98</link>
      <guid>https://dev.to/aleksei_aleinikov/wie-man-1000000-benachrichtigungen-versendet-ohne-abzusturzen-1p98</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk2x6m2qt2dc3y782b0b2.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk2x6m2qt2dc3y782b0b2.webp" alt="Wie man 1.000.000 Benachrichtigungen versendet, ohne abzustürzen" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Eine Benachrichtigung zu senden ist ein Funktionsaufruf. Eine Million zu senden ist ein Problem verteilter Systeme im Gewand eines Funktionsaufrufs.&lt;/p&gt;

&lt;p&gt;Die naive Variante wirkt harmlos: Ein Nutzer löst ein Event aus, du iterierst über eine Million Empfänger und rufst für jeden den Push-, E-Mail- oder SMS-Provider auf. Im Demo funktioniert es. Bei tausend Nutzern funktioniert es. Dann fächert ein Produkt-Launch ein einziges Event über die gesamte Nutzerbasis auf, jeder Send wartet auf eine langsame Drittanbieter-API, und der Request-Thread, der in 50 ms hätte antworten sollen, hält jetzt eine Million offene Aufrufe. Die API stürzt ab — nicht weil der Code falsch ist, sondern weil die &lt;em&gt;Form&lt;/em&gt; falsch ist.&lt;/p&gt;

&lt;p&gt;Das hier ist ein anbieterneutraler Durchgang durch die Form, die hält: eine &lt;strong&gt;Message-Queue-Architektur&lt;/strong&gt; mit Fan-out-Workern, Back-Pressure und den langweiligen Zuverlässigkeitsteilen, die verhindern, dass ein „Send“ zum Ausfall wird. Die Beispiele sind cloud-agnostisch — dasselbe Muster läuft auf RabbitMQ, Kafka, SQS oder Pub/Sub.&lt;/p&gt;

&lt;h2&gt;
  
  
  Der Fehler: Die Arbeit im Request erledigen
&lt;/h2&gt;

&lt;p&gt;Als Erstes muss man reparieren, &lt;em&gt;wo&lt;/em&gt; die Arbeit passiert. Wenn du im Request-Handler sendest, ist der Thread, der den HTTP-Aufruf angenommen hat, derselbe Thread, der auf einen langsamen externen Provider wartet — millionenfach.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx0b1atjynpqsw5a6ncle.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx0b1atjynpqsw5a6ncle.webp" alt="Der Versand im Request blockiert den Thread und flutet bei einer Spitze; Annehmen-und-Antworten hält die API schnell, während Worker die Queue abbauen." width="799" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Zwei Dinge gehen gleichzeitig schief. Erstens &lt;strong&gt;stapelt sich die Latenz&lt;/strong&gt; : Die Antwortzeit deiner API ist jetzt die Summe aller Provider-Aufrufe, also zieht ein langsamer Anbieter den ganzen Request nach unten. Zweitens &lt;strong&gt;explodiert die Nebenläufigkeit&lt;/strong&gt; : Eine Spitze reiht sich nirgends ein, sie öffnet eine Million gleichzeitige Sends gegen Provider, die dich bereitwillig rate-limiten oder abweisen, während dein eigener Connection-Pool und Speicher austrocknen.&lt;/p&gt;

&lt;p&gt;Die Faustregel ist einfach:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Der Request soll den Auftrag &lt;em&gt;annehmen&lt;/em&gt;, nicht &lt;em&gt;ausführen&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nimm das Event an, schreib es in eine dauerhafte Queue und antworte in Millisekunden mit &lt;code&gt;202 Accepted&lt;/code&gt;. Die schwere Arbeit wandert zu Hintergrund-Workern, die du unabhängig vom Request-Pfad skalieren, drosseln und wiederholen kannst. Die Spitze ist immer noch da — aber jetzt landet sie in einer Queue, wo ein Rückstau eine Unannehmlichkeit ist, kein Ausfall.&lt;/p&gt;

&lt;p&gt;In „schreib es in eine dauerhafte Queue“ versteckt sich eine Feinheit. Schreibst du in deine Datenbank &lt;em&gt;und&lt;/em&gt; publizierst in die Queue als zwei getrennte Schritte, verliert ein Absturz dazwischen das Event oder sendet ein Phantom. Die Lösung ist das &lt;strong&gt;transaktionale Outbox-Pattern&lt;/strong&gt; : Schreib das Event in &lt;em&gt;derselben&lt;/em&gt; Datenbank-Transaktion wie deinen fachlichen Write in eine &lt;code&gt;outbox&lt;/code&gt;-Tabelle, und ein separater Relay befördert diese Zeilen in die Queue. Ein atomarer Write, keine verlorenen Events, keine doppelten Sends.&lt;/p&gt;

&lt;h2&gt;
  
  
  Der Kern: Eine Fan-out-Pipeline
&lt;/h2&gt;

&lt;p&gt;Sobald die Arbeit vom Request-Pfad weg ist, wird die Architektur zur Pipeline. Ein Event kommt herein; kanalspezifische Benachrichtigungen gehen hinaus. Der Baustein, der sie skalieren lässt, ist &lt;strong&gt;Fan-out&lt;/strong&gt; : eine einzige Ingress-Queue, aufgeteilt in je eine isolierte Spur pro Kanal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm3095czhr7axrxxy2ic9.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm3095czhr7axrxxy2ic9.webp" alt="Ein Producer publiziert in ein Ingress-Topic; ein Fan-out-Schritt teilt die Arbeit in isolierte Push-, E-Mail- und SMS-Queues mit je eigenen Workern und Providern." width="799" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Geh den Pfad durch:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Producer → Ingress-Queue.&lt;/strong&gt; Die API (oder ein vorgelagertes Event) publiziert pro logischem Event eine Nachricht in ein einziges dauerhaftes Topic. Das ist das Einzige, was der Request-Pfad berührt, und es ist schnell und append-only.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fan-out.&lt;/strong&gt; Ein leichtgewichtiger Schritt liest das Ingress-Event, entscheidet welche Kanäle gelten (dieser Nutzer will Push + E-Mail, keine SMS) und publiziert eine Nachricht in die Queue jedes Kanals. Fan-out ist, wo aus „einem Event“ „drei Sends“ werden.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kanalspezifische Queues + Worker.&lt;/strong&gt; Jeder Kanal — Push, E-Mail, SMS — hat seine &lt;strong&gt;eigene&lt;/strong&gt; Queue und seinen &lt;strong&gt;eigenen&lt;/strong&gt; Worker-Pool. Diese Isolation ist der ganze Punkt: Ein langsames SMS-Gateway staut nur die SMS-Queue. Push und E-Mail fließen weiter.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provider.&lt;/strong&gt; Jeder Worker-Pool spricht mit seinem Provider (APNs/FCM, SMTP/SES, ein SMS-Gateway) in einem Tempo, das dieser Provider verkraften kann.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Die Isolation bringt drei Dinge, die ein einzelner geteilter Worker-Pool nicht kann: unabhängiges &lt;strong&gt;Skalieren&lt;/strong&gt; (mehr E-Mail-Worker hochfahren, ohne SMS anzufassen), unabhängiges &lt;strong&gt;Scheitern&lt;/strong&gt; (ein toter Provider staut die anderen nicht) und unabhängiges &lt;strong&gt;Tuning&lt;/strong&gt; (E-Mail verträgt Minuten Verzögerung; Push oft nicht).&lt;/p&gt;

&lt;p&gt;Zwei Hebel machen aus dem Diagramm ein Produktionssystem. &lt;strong&gt;Batche zum Provider&lt;/strong&gt; : Die meisten Push-, E-Mail- und SMS-APIs akzeptieren Hunderte Empfänger pro Aufruf, also sendet ein Worker, der seine Queue zu Batches bündelt, weit mehr pro Sekunde als einer, der einzeln sendet. Und &lt;strong&gt;trenne nach Priorität, nicht nur nach Kanal&lt;/strong&gt; : Ein transaktionaler OTP und eine Marketing-Blast dürfen sich nie eine Queue teilen — gib latenzkritischem Verkehr seine eigene Spur, damit eine Kampagne über eine Million Nachrichten keinen Login-Code verzögert. Wo die Reihenfolge pro Nutzer zählt, schlüssle diese Nachrichten auf dieselbe Partition, damit ein einzelner Worker sie der Reihe nach abarbeitet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Anhand der Queue-Tiefe skalieren, nicht der Request-Rate
&lt;/h3&gt;

&lt;p&gt;Die Worker sind der Ort, an dem eine Million Events tatsächlich versendet werden, und der Trick ist, &lt;em&gt;worauf&lt;/em&gt; man skaliert. Skaliere nicht auf CPU oder Request-Rate — skaliere auf &lt;strong&gt;Queue-Tiefe&lt;/strong&gt; und &lt;strong&gt;Nachrichtenalter&lt;/strong&gt;. Wächst der Rückstau über einen Schwellenwert, füge Worker-Replicas hinzu; leert er sich, skaliere zurück.&lt;/p&gt;

&lt;p&gt;Genau das entkoppelt Ankunftstempo von Sendetempo. Eine Million Events können in einer Minute eintreffen; deine Worker brauchen vielleicht eine Stunde zum Senden, gedrosselt auf das, was die Provider erlauben. Das ist in Ordnung — die Queue federt die Differenz ab. Die Aufgabe des Systems ist nicht, alles sofort zu senden. Sie ist, &lt;strong&gt;nie ein Event zu verlieren und nie abzustürzen&lt;/strong&gt; , während so schnell abgebaut wird, wie die nachgelagerten Provider es zulassen.&lt;/p&gt;

&lt;p&gt;Diese Worker-Pools laufen meist auf einer autoskalierenden Container-Plattform, und ist diese Plattform Kubernetes, zählt die Basis, auf der sie läuft, ebenso viel wie die Pipeline selbst — siehe &lt;a href="https://www.alekseialeinikov.com/de/blog/topics/architecture/secure-by-default-gke-referenzarchitektur-2026" rel="noopener noreferrer"&gt;Secure-by-Default GKE: Eine Referenzarchitektur für 2026&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Das ist dasselbe event-getriebene Rückgrat hinter jedem entkoppelten System. Baust du es speziell auf GCP, lohnt sich als Nächstes der Abgleich der Trade-offs zwischen Transport und Router: &lt;a href="https://www.alekseialeinikov.com/de/blog/topics/architecture/pubsub-oder-eventarc-2026-event-driven-gcp-ohne-spaghetti" rel="noopener noreferrer"&gt;Pub/Sub oder Eventarc? Event-getriebenes GCP ohne Spaghetti&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Unter Last oben bleiben: Die langweiligen Teile, die zählen
&lt;/h2&gt;

&lt;p&gt;Eine Queue und ein paar Worker bringen dich durchs Demo. Was einen Lauf über eine Million Nachrichten um 3 Uhr morgens am Leben hält, ist die Zuverlässigkeitsschicht — die Teile, die alle überspringen, bis die Produktion sie lehrt. Es sind vier, und sie funktionieren nur, &lt;em&gt;weil&lt;/em&gt; du eine Queue hast.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqbxtv55bm6ltgdb92os9.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqbxtv55bm6ltgdb92os9.webp" alt="Vier Schutzmechanismen halten es oben: Retry mit Backoff, eine Dead-Letter-Queue, Idempotenz-Schlüssel und Back-Pressure pro Provider." width="799" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retry mit Backoff.&lt;/strong&gt; Provider scheitern vorübergehend — ein Timeout, ein 503, ein kurzes Rate-Limit. Wiederhole, aber mit &lt;strong&gt;exponentiellem Backoff und Jitter&lt;/strong&gt; , nie in einer engen Schleife. Eine enge Retry-Schleife über Tausende Worker ist von einem Denial-of-Service-Angriff nicht zu unterscheiden — und das Ziel ist dein eigener Provider. Backoff verteilt die Retries, sodass ein Aussetzer sich erholt, statt sich zu verstärken.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dead-Letter-Queue (DLQ).&lt;/strong&gt; Manche Nachrichten gelingen nie: ein fehlerhaftes Payload, eine dauerhaft ungültige Adresse, ein Bug. Verschiebe die Nachricht nach N Versuchen in eine &lt;strong&gt;Dead-Letter-Queue&lt;/strong&gt; , statt sie endlos zu wiederholen. Die schlechte Nachricht wird zur Prüfung geparkt — nie verloren, nie die Linie blockierend — und der gesunde Verkehr dahinter läuft weiter. Ohne DLQ wiederholt sich eine Giftnachricht, bis sie die Queue aushungert.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Idempotenz.&lt;/strong&gt; Jede dauerhafte Queue stellt &lt;strong&gt;mindestens einmal&lt;/strong&gt; zu. Eine erneute Zustellung, ein langsames Ack, ein Worker, der nach dem Senden aber vor dem Ack abstürzt — jedes davon bedeutet, dass dieselbe Nachricht zweimal verarbeitet wird. Bedeutet „zweimal“ eine zweite E-Mail oder eine Doppelbelastung, ist das ein Bug, den du geschrieben hast. Dedupliziere auf einer &lt;strong&gt;stabilen Message-ID&lt;/strong&gt; : notiere „Nachricht &lt;code&gt;abc123&lt;/code&gt; bereits gesendet“ und behandle einen erneuten Lauf als No-op. Halte diesen Eintrag in einem schnellen Store mit einer TTL, die dein Retry-Fenster abdeckt — du musst nur jüngste IDs merken, nicht die ganze Historie. Die erneute Zustellung wird harmlos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Back-Pressure.&lt;/strong&gt; Das ist der Schutz, der das &lt;em&gt;gesamte System&lt;/em&gt; vom Kippen abhält. Jeder Worker respektiert ein &lt;strong&gt;Concurrency- und Rate-Limit pro Provider&lt;/strong&gt;. Wird ein Provider langsamer, werden die Worker mit ihm langsamer — die Queue wächst, aber nichts stürzt ab. Back-Pressure verwandelt „der Provider hat Mühe“ in „der Rückstau ist heute tiefer“, statt „wir haben ihn gehämmert, bis er uns blockiert hat“.&lt;/p&gt;

&lt;p&gt;Zusammengenommen sind diese vier der Grund, warum das Design seinen eigenen Erfolg überlebt. Die Queue macht sie möglich; überspringst du sie, wird deine Retry-Logik zu einem selbstverschuldeten DDoS gegen genau die Provider, von denen du abhängst.&lt;/p&gt;

&lt;h2&gt;
  
  
  Alles zusammengesetzt
&lt;/h2&gt;

&lt;p&gt;Verfolge einen Launch durch die fertige Form. Eine Kampagne feuert ein Event. Die API schreibt es in die Ingress-Queue und antwortet in Millisekunden — der nutzerseitige Pfad weiß nicht einmal, dass eine Million Sends kommen. Fan-out teilt das Event in Push-, E-Mail- und SMS-Arbeit auf drei isolierten Queues. Jeder Worker-Pool skaliert auf seinem eigenen Rückstau, sendet im Tempo seines Providers, wiederholt vorübergehende Fehler mit Backoff, verschiebt die hoffnungslosen in die DLQ und dedupliziert erneute Zustellungen auf einer Message-ID. Die Spitze wird zu drei abbauenden Queues. Nichts stürzt ab.&lt;/p&gt;

&lt;p&gt;Nichts davon ist exotisch. Es ist eine Queue, ein Fan-out-Schritt, Worker-Pools, die auf Tiefe skalieren, und vier Zuverlässigkeits-Schutzmechanismen. Der Fehler waren nie die Tools — es war, eine Aufgabe verteilter Systeme in einem einzigen Request-Thread zu erledigen. Nimm die Arbeit von diesem Thread, isoliere die Kanäle und lass Back-Pressure die Spitze abfedern — und „eine Million Benachrichtigungen senden“ hört auf, eine beängstigende Zahl zu sein, und wird zu einem Dienstag.&lt;/p&gt;

&lt;h3&gt;
  
  
  Die Feldregel
&lt;/h3&gt;

&lt;p&gt;Nimm den Auftrag an, führ ihn nicht aus. Fan-out auf je eine Queue pro Kanal, damit Fehler lokal bleiben. Skaliere Worker auf Queue-Tiefe, nicht auf Request-Rate. Und behandle Retries, Dead-Letter-Queues, Idempotenz und Back-Pressure als tragend, nicht optional — sie sind der Unterschied zwischen einem Rückstau und einem Ausfall.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ursprünglich veröffentlicht auf &lt;a href="https://www.alekseialeinikov.com/de/blog/topics/architecture/eine-million-benachrichtigungen-versenden-ohne-abzustuerzen-2026" rel="noopener noreferrer"&gt;alekseialeinikov.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>messagequeue</category>
      <category>eventdrivenarchitect</category>
      <category>fanout</category>
      <category>notificationsystem</category>
    </item>
    <item>
      <title>How to Send 1,000,000 Notifications Without Falling Over</title>
      <dc:creator>Aleksei Aleinikov</dc:creator>
      <pubDate>Mon, 13 Jul 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/aleksei_aleinikov/how-to-send-1000000-notifications-without-falling-over-302g</link>
      <guid>https://dev.to/aleksei_aleinikov/how-to-send-1000000-notifications-without-falling-over-302g</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk2x6m2qt2dc3y782b0b2.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk2x6m2qt2dc3y782b0b2.webp" alt="How to Send 1,000,000 Notifications Without Falling Over" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sending one notification is a function call. Sending a million is a distributed-systems problem wearing a function call’s clothes.&lt;/p&gt;

&lt;p&gt;The naive version looks innocent: a user triggers an event, you loop over a million recipients, and for each one you call the push, email, or SMS provider. It works in the demo. It works for a thousand users. Then a product launch fans a single event out to your whole user base, every send waits on a slow third-party API, and the request thread that was supposed to return in 50 ms is now holding a million open calls. The API falls over — not because the code is wrong, but because the &lt;em&gt;shape&lt;/em&gt; is wrong.&lt;/p&gt;

&lt;p&gt;This is a vendor-neutral walkthrough of the shape that holds: a &lt;strong&gt;message-queue architecture&lt;/strong&gt; with fan-out workers, back-pressure, and the boring reliability parts that keep a “send” from turning into an outage. The examples are cloud-agnostic — the same pattern runs on RabbitMQ, Kafka, SQS, or Pub/Sub.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Mistake: Doing the Work Inside the Request
&lt;/h2&gt;

&lt;p&gt;The first thing to fix is &lt;em&gt;where&lt;/em&gt; the work happens. When you send inside the request handler, the thread that accepted the HTTP call is the same thread waiting on a slow external provider — a million times over.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx0b1atjynpqsw5a6ncle.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx0b1atjynpqsw5a6ncle.webp" alt="Sending inside the request blocks the thread and floods on a spike; enqueue-and-return keeps the API fast while workers drain the queue." width="799" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two things go wrong at once. First, &lt;strong&gt;latency stacks&lt;/strong&gt; : your API’s response time is now the sum of every provider call, so one slow vendor drags the whole request down. Second, &lt;strong&gt;concurrency explodes&lt;/strong&gt; : a spike doesn’t queue anywhere, it opens a million concurrent sends against providers that will happily rate-limit or drop you, while your own connection pools and memory run dry.&lt;/p&gt;

&lt;p&gt;The rule of thumb is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The request should &lt;em&gt;accept&lt;/em&gt; the job, not &lt;em&gt;do&lt;/em&gt; the job.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Accept the event, write it to a durable queue, and return &lt;code&gt;202 Accepted&lt;/code&gt; in milliseconds. The heavy lifting moves to background workers that you can scale, throttle, and retry independently of the request path. The spike is still there — but now it lands in a queue, where a backlog is an inconvenience, not an outage.&lt;/p&gt;

&lt;p&gt;One subtlety hides in “write it to a durable queue.” If you write to your database &lt;em&gt;and&lt;/em&gt; publish to the queue as two separate steps, a crash between them loses the event or sends a phantom one. The fix is the &lt;strong&gt;transactional outbox&lt;/strong&gt; : commit the event to an &lt;code&gt;outbox&lt;/code&gt; table in the &lt;em&gt;same&lt;/em&gt; database transaction as your business write, then a separate relay ships those rows to the queue. One atomic write, no lost events, no double sends.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core: A Fan-Out Pipeline
&lt;/h2&gt;

&lt;p&gt;Once the work is off the request path, the architecture becomes a pipeline. One event enters; per-channel notifications leave. The piece that makes it scale is &lt;strong&gt;fan-out&lt;/strong&gt; : a single ingress queue, split into one isolated lane per channel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm3095czhr7axrxxy2ic9.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm3095czhr7axrxxy2ic9.webp" alt="One producer publishes to an ingress topic; a fan-out step splits work into isolated push, email, and SMS queues, each with its own workers and provider." width="799" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Walk the path:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Producer → ingress queue.&lt;/strong&gt; The API (or an upstream event) publishes one message per logical event to a single durable topic. This is the only thing the request path touches, and it’s fast and append-only.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fan-out.&lt;/strong&gt; A lightweight step reads the ingress event, decides which channels apply (this user wants push + email, not SMS), and publishes a message to each channel’s queue. Fan-out is where “one event” becomes “three sends.”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-channel queues + workers.&lt;/strong&gt; Each channel — push, email, SMS — has its &lt;strong&gt;own&lt;/strong&gt; queue and its &lt;strong&gt;own&lt;/strong&gt; worker pool. This isolation is the whole point: a slow SMS gateway backs up the SMS queue only. Push and email keep flowing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Providers.&lt;/strong&gt; Each worker pool talks to its provider (APNs/FCM, SMTP/SES, an SMS gateway) at a rate that provider can absorb.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The isolation buys you three things you can’t get from a single shared worker pool: independent &lt;strong&gt;scaling&lt;/strong&gt; (spin up more email workers without touching SMS), independent &lt;strong&gt;failure&lt;/strong&gt; (one dead provider doesn’t stall the others), and independent &lt;strong&gt;tuning&lt;/strong&gt; (email tolerates minutes of delay; push often can’t).&lt;/p&gt;

&lt;p&gt;Two levers turn this from a diagram into a production system. &lt;strong&gt;Batch to the provider&lt;/strong&gt; : most push, email, and SMS APIs accept hundreds of recipients per call, so a worker that groups its queue into batches sends far more per second than one that goes one-at-a-time. And &lt;strong&gt;split by priority, not just by channel&lt;/strong&gt; : a transactional OTP and a marketing blast should never share a queue — give latency-critical traffic its own lane so a million-message campaign can’t delay a login code. Where per-user ordering matters, key those messages to the same partition so a single worker handles them in sequence.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scale on Queue Depth, Not Request Rate
&lt;/h3&gt;

&lt;p&gt;The workers are where a million events actually get sent, and the trick is &lt;em&gt;what you scale on&lt;/em&gt;. Don’t autoscale on CPU or request rate — scale on &lt;strong&gt;queue depth&lt;/strong&gt; and &lt;strong&gt;message age&lt;/strong&gt;. When the backlog grows past a threshold, add worker replicas; when it drains, scale back down.&lt;/p&gt;

&lt;p&gt;This is what decouples arrival speed from send speed. A million events can arrive in a minute; your workers might take an hour to send them, throttled to what the providers allow. That’s fine — the queue absorbs the difference. The system’s job is not to send everything instantly. It’s to &lt;strong&gt;never lose an event and never fall over&lt;/strong&gt; , while draining as fast as the downstream providers permit.&lt;/p&gt;

&lt;p&gt;Those worker pools usually run on an autoscaling container platform, and if that platform is Kubernetes, the base it runs on matters as much as the pipeline itself — see &lt;a href="https://www.alekseialeinikov.com/en/blog/topics/architecture/secure-by-default-gke-reference-architecture-2026" rel="noopener noreferrer"&gt;Secure-by-Default GKE: A Reference Architecture for 2026&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is the same event-driven backbone behind any decoupled system. If you’re building it on GCP specifically, the trade-offs between the transport and the router are worth reading next: &lt;a href="https://www.alekseialeinikov.com/en/blog/topics/architecture/pubsub-vs-eventarc-2026-event-driven-gcp-without-spaghetti" rel="noopener noreferrer"&gt;Pub/Sub or Eventarc? Event-Driven GCP Without the Spaghetti&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Staying Up Under Load: The Boring Parts That Matter
&lt;/h2&gt;

&lt;p&gt;A queue and some workers will get you through a demo. What keeps a million-message run alive at 3 a.m. is the reliability layer — the parts everyone skips until production teaches them. There are four, and they only work &lt;em&gt;because&lt;/em&gt; you have a queue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqbxtv55bm6ltgdb92os9.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqbxtv55bm6ltgdb92os9.webp" alt="Four guards keep it up: retry with backoff, a dead-letter queue, idempotency keys, and per-provider back-pressure." width="799" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retry with backoff.&lt;/strong&gt; Providers fail transiently — a timeout, a 503, a brief rate-limit. Retry, but with &lt;strong&gt;exponential backoff and jitter&lt;/strong&gt; , never a tight loop. A tight retry loop across thousands of workers is indistinguishable from a denial-of-service attack, and the target is your own provider. Backoff spreads the retries out so a blip recovers instead of amplifying.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dead-letter queue (DLQ).&lt;/strong&gt; Some messages never succeed: a malformed payload, a permanently-invalid address, a bug. After N attempts, move the message to a &lt;strong&gt;dead-letter queue&lt;/strong&gt; instead of retrying forever. The bad message is parked for inspection — never lost, never blocking the line — and the healthy traffic behind it keeps moving. Without a DLQ, one poison message retries until it starves the queue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Idempotency.&lt;/strong&gt; Every durable queue delivers &lt;strong&gt;at-least-once&lt;/strong&gt;. A redelivery, a slow ack, a worker that crashes after sending but before acking — any of these means the same message gets processed twice. If “twice” means a second email or a double charge, that’s a bug you wrote. Dedupe on a &lt;strong&gt;stable message ID&lt;/strong&gt; : record “message &lt;code&gt;abc123&lt;/code&gt; already sent” and treat a re-run as a no-op. Keep that record in a fast store with a TTL that covers your retry window — you only need to remember recent IDs, not all of history. Redelivery becomes harmless.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Back-pressure.&lt;/strong&gt; This is the guard that keeps the &lt;em&gt;whole system&lt;/em&gt; from tipping over. Each worker respects a &lt;strong&gt;per-provider concurrency limit and rate limit&lt;/strong&gt;. When a provider slows down, workers slow with it — the queue grows, but nothing crashes. Back-pressure turns “the provider is struggling” into “the backlog is deeper today” instead of “we hammered them until they blocked us.”&lt;/p&gt;

&lt;p&gt;Put together, these four are why the design survives its own success. The queue makes them possible; skip them and your retry logic becomes a self-inflicted DDoS on the exact providers you depend on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Putting It Together
&lt;/h2&gt;

&lt;p&gt;Trace one launch through the finished shape. A campaign fires one event. The API writes it to the ingress queue and returns in milliseconds — the user-facing path never even knows a million sends are coming. Fan-out splits the event into push, email, and SMS work on three isolated queues. Each worker pool scales on its own backlog, sends at its provider’s pace, retries transient failures with backoff, dead-letters the hopeless ones, and dedupes redeliveries on a message ID. The spike becomes three draining queues. Nothing falls over.&lt;/p&gt;

&lt;p&gt;None of this is exotic. It’s a queue, a fan-out step, worker pools that scale on depth, and four reliability guards. The mistake was never the tools — it was doing a distributed-systems job inside a single request thread. Move the work off that thread, isolate the channels, and let back-pressure absorb the spike, and “send a million notifications” stops being a scary number and becomes a Tuesday.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Field Rule
&lt;/h3&gt;

&lt;p&gt;Accept the job, don’t do it. Fan out to one queue per channel so failures stay local. Scale workers on queue depth, not request rate. And treat retries, dead-letter queues, idempotency, and back-pressure as load-bearing, not optional — they’re the difference between a backlog and an outage.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://www.alekseialeinikov.com/en/blog/topics/architecture/send-one-million-notifications-without-falling-over-2026" rel="noopener noreferrer"&gt;alekseialeinikov.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>messagequeue</category>
      <category>eventdrivenarchitect</category>
      <category>fanout</category>
      <category>notificationsystem</category>
    </item>
    <item>
      <title>Sovereign by Design: Building a Sovereign Platform on Kubernetes</title>
      <dc:creator>Aleksei Aleinikov</dc:creator>
      <pubDate>Sun, 12 Jul 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/aleksei_aleinikov/sovereign-by-design-building-a-sovereign-platform-on-kubernetes-1nim</link>
      <guid>https://dev.to/aleksei_aleinikov/sovereign-by-design-building-a-sovereign-platform-on-kubernetes-1nim</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2yg98ccm68abxmuuhjkf.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2yg98ccm68abxmuuhjkf.webp" alt="Sovereign by Design: Building a Sovereign Platform on Kubernetes" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;“Sovereign cloud” is the loudest phrase in European IT right now, and most of it is a sticker. Vendors slap it on a region, a contract clause, or a compliance certificate and call the platform sovereign. But sovereignty is not something you buy at the checkout — it is a property of how you architect. If it is not designed in, no label puts it there.&lt;/p&gt;

&lt;p&gt;This is a practical, vendor-neutral architecture for building a genuinely sovereign platform. The core idea: stop treating sovereignty as one thing to procure, and start treating it as &lt;strong&gt;three independent layers you design for&lt;/strong&gt; — with Kubernetes as the portability spine that ties them together.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This builds on a security foundation rather than replacing it. If your platform is not hardened first, sovereignty is moot — start from the &lt;a href="https://www.alekseialeinikov.com/en/blog/topics/architecture/secure-by-default-gke-reference-architecture-2026" rel="noopener noreferrer"&gt;secure-by-default GKE reference architecture&lt;/a&gt; and layer sovereignty on top.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Sovereignty Is Three Layers, Not One
&lt;/h2&gt;

&lt;p&gt;The single biggest mistake is treating “sovereign” as a binary you either have or lack. It is really three separate questions, and a platform can score high on one while failing another.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F99pry76dyfiky4yvurky.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F99pry76dyfiky4yvurky.webp" alt="The three layers of sovereignty — data residency and access, operational control, and technical portability — and what keeps each one yours." width="799" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data sovereignty&lt;/strong&gt; — Where does the data physically live, and &lt;em&gt;who can legally compel access to it&lt;/em&gt;? Residency is only half; the legal reach over the operator is the other half.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operational sovereignty&lt;/strong&gt; — Who runs the control plane? Who can read, administer, or be compelled to expose the running system?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technical sovereignty&lt;/strong&gt; — Can you leave? Are your workloads portable, or welded to one provider’s proprietary APIs?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A typical “sovereign cloud” offering covers one of these convincingly and waves at the rest. Real sovereignty means designing for all three — so let’s take them in the order that gives you the most leverage.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Freedom to Leave: Portability as the Real Test
&lt;/h2&gt;

&lt;p&gt;Technical sovereignty has a brutally simple test: &lt;strong&gt;what does it cost you to leave?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If leaving a provider means rewriting your applications and re-architecting around a different set of proprietary services, you are locked in — and lock-in is the exact opposite of sovereignty. If leaving means redeploying the &lt;em&gt;same&lt;/em&gt; manifests onto a different conformant cluster, you are sovereign at the technical layer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fstr2mjobje0sw87wpbr1.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fstr2mjobje0sw87wpbr1.webp" alt="Portability as the freedom to leave: proprietary services force a rewrite, while Kubernetes manifests redeploy unchanged across GKE, EKS, AKS or an EU-hosted cluster." width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is where Kubernetes earns its place — not as a container scheduler, but as the &lt;strong&gt;portability layer&lt;/strong&gt;. Standard Kubernetes manifests, OCI images, Helm charts and infrastructure-as-code are conformant across every major platform and on-premises. The workload does not change when the ground underneath it does.&lt;/p&gt;

&lt;p&gt;Portability is not free, though. The workload &lt;em&gt;core&lt;/em&gt; travels; the &lt;em&gt;edges&lt;/em&gt; do not — storage classes, ingress controllers, load-balancer annotations, and cloud identity integration are provider-specific and have to be abstracted or swapped deliberately. Real portability means keeping that core clean and the provider-specific edges thin and replaceable, not pretending nothing changes when you move.&lt;/p&gt;

&lt;p&gt;The discipline is to keep your &lt;strong&gt;critical path&lt;/strong&gt; on portable, standards-based components and to treat every proprietary managed service as a deliberate trade. A queue expressed as a Kubernetes workload moves anywhere; a queue that is a provider-specific API is an anchor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Portable: the workload is a standard object, not a vendor API.&lt;/span&gt;
&lt;span class="c1"&gt;# The same manifest runs on GKE, EKS, AKS, or an EU-hosted cluster.&lt;/span&gt;

&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;

&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;

&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ingest&lt;/span&gt;

&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;

  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ingest&lt;/span&gt;

          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;registry.example.eu/ingest:1.8.0&lt;/span&gt; &lt;span class="c1"&gt;# your registry, your region&lt;/span&gt;

          &lt;span class="na"&gt;envFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;secretRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

                &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ingest-config&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Portability does not mean never using a managed service. It means knowing, for each one, exactly what leaving would cost — so “we could move” is a measured exit plan, not a comforting slogan.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who Holds the Keys: Residency Is Not Custody
&lt;/h2&gt;

&lt;p&gt;Here is the trap that sinks most “our data is in an EU region, so we’re sovereign” claims.&lt;/p&gt;

&lt;p&gt;Data residency chooses &lt;em&gt;where the bytes sit&lt;/em&gt;. It says nothing about &lt;em&gt;who can read them&lt;/em&gt;. A provider operating under a foreign legal regime — the US CLOUD Act is the canonical example — can be compelled to hand over data regardless of which region it lives in. Residency alone does not stop that.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzvva9sm0ik5hva583j69.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzvva9sm0ik5hva583j69.webp" alt="Key custody vs the CLOUD Act: when you hold the keys in an external manager, the provider stores only ciphertext and legal reach yields nothing readable." width="800" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The control that actually changes the outcome is &lt;strong&gt;key custody&lt;/strong&gt;. The pattern that truly delivers it is &lt;strong&gt;HYOK&lt;/strong&gt; (hold your own key) — an &lt;strong&gt;external key manager&lt;/strong&gt; such as Google’s External Key Manager (EKM) or AWS XKS, where the provider calls out to &lt;em&gt;your&lt;/em&gt; key service to decrypt and never holds the key material itself. Plain &lt;strong&gt;BYOK&lt;/strong&gt; , where you import a key into the provider’s own KMS, is weaker: the provider does hold the key, so it defends against a different and smaller threat. With true external custody:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The provider stores your data &lt;strong&gt;encrypted&lt;/strong&gt; , and ciphertext without your key is noise.&lt;/li&gt;
&lt;li&gt;If they are legally compelled to hand data over, what they can produce is that same worthless ciphertext.&lt;/li&gt;
&lt;li&gt;Revoke access to the key and new decryptions stop everywhere at once — already-cached data keys age out shortly after — which is effectively crypto-shredding the data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Residency and key custody are complementary: residency answers “where,” custody answers “who can read it.” Custody is the one that turns a legal request into a non-event.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Keys are the whole game at the identity layer too. The same “no long-lived secret to seize” principle applies to workload credentials — see &lt;a href="https://www.alekseialeinikov.com/en/blog/topics/security/kill-service-account-keys-workload-identity-federation-2026" rel="noopener noreferrer"&gt;Kill Your Service Account Keys with Workload Identity Federation&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Operational Sovereignty: Who Can Read and Run It
&lt;/h2&gt;

&lt;p&gt;The quietest layer is operational. Even with portable workloads and customer-held keys, sovereignty leaks if the people operating the plane can silently read or administer your systems from outside your jurisdiction.&lt;/p&gt;

&lt;p&gt;Designing for operational sovereignty means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;EU-only operations&lt;/strong&gt; for regulated workloads — support and administration performed within the jurisdiction, not routed globally.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access transparency&lt;/strong&gt; — every provider-side access to your environment is logged and visible to you, so “trust us” becomes “verify.”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Least privilege and just-in-time access&lt;/strong&gt; — no standing administrative access; elevation is scoped, time-boxed, and audited.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your own audit trail&lt;/strong&gt; — logs shipped to storage &lt;em&gt;you&lt;/em&gt; control, so the record of who did what does not depend on the provider’s goodwill.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this is exotic. It is the same access-control discipline you already apply to your own teams, extended to the provider as an untrusted operator.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sovereignty Without Dogma: A Decision Framework
&lt;/h2&gt;

&lt;p&gt;The failure mode on the other side is treating sovereignty as a purity test and paying a heavy velocity tax to make a marketing brochure with zero real workloads. Sovereignty is a &lt;strong&gt;spectrum&lt;/strong&gt; , and you apply it by classification, not by reflex.&lt;/p&gt;

&lt;p&gt;A pragmatic frame:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Classify the workload.&lt;/strong&gt; Regulated or high-sensitivity data, or a system whose compromise is existential? It earns the full treatment: portable components, external key custody, operational controls. A stateless internal tool with no sensitive data? A convenient managed service is a perfectly rational trade.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Measure the lock-in, don’t assume it.&lt;/strong&gt; For each proprietary dependency in the critical path, write down the real cost of leaving. Some are cheap to swap; some are anchors. You cannot manage what you have not measured.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Design the exit before you need it.&lt;/strong&gt; Portability that has never been exercised is a hope, not a capability. Keep the option real: standard manifests, your own registry, keys you hold, infrastructure-as-code that can target a second platform.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Applied this way, sovereignty stops being a religious argument and becomes an engineering trade-off you make consciously, workload by workload.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Honest Limits
&lt;/h2&gt;

&lt;p&gt;Sovereignty has a cost, and pretending otherwise is how you end up resenting it. Portable, standards-based components sometimes mean giving up the slickest proprietary service. External key custody adds operational complexity and a failure mode of its own — lose the key and the data really is gone. Full operational sovereignty can raise support costs. And no architecture removes the legal reality that if you run on a provider at all, you are trusting &lt;em&gt;something&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The point is not maximal sovereignty everywhere. It is that sovereignty becomes a &lt;strong&gt;property you designed on purpose&lt;/strong&gt; — measured, classified, and exercised — instead of a sticker someone sold you. Build the three layers deliberately, keep the exit real, hold your own keys, and “sovereign” stops being a claim you hope survives scrutiny and becomes one you can actually demonstrate.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://www.alekseialeinikov.com/en/blog/topics/architecture/sovereign-by-design-building-a-sovereign-platform-on-kubernetes-2026" rel="noopener noreferrer"&gt;alekseialeinikov.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>sovereigncloud</category>
      <category>digitalsovereignty</category>
      <category>kubernetes</category>
      <category>dataresidency</category>
    </item>
    <item>
      <title>Sovereign by Design: Eine souveräne Plattform auf Kubernetes bauen</title>
      <dc:creator>Aleksei Aleinikov</dc:creator>
      <pubDate>Sun, 12 Jul 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/aleksei_aleinikov/sovereign-by-design-eine-souverane-plattform-auf-kubernetes-bauen-1i1o</link>
      <guid>https://dev.to/aleksei_aleinikov/sovereign-by-design-eine-souverane-plattform-auf-kubernetes-bauen-1i1o</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2yg98ccm68abxmuuhjkf.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2yg98ccm68abxmuuhjkf.webp" alt="Sovereign by Design: Eine souveräne Plattform auf Kubernetes bauen" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;„Souveräne Cloud“ ist derzeit der lauteste Begriff in der europäischen IT — und das meiste davon ist ein Aufkleber. Anbieter kleben ihn auf eine Region, eine Vertragsklausel oder ein Compliance-Zertifikat und nennen die Plattform souverän. Aber Souveränität kauft man nicht an der Kasse — sie ist eine Eigenschaft davon, &lt;em&gt;wie&lt;/em&gt; du entwirfst. Ist sie nicht eingebaut, bringt sie kein Label hinein.&lt;/p&gt;

&lt;p&gt;Das hier ist eine praxisnahe, anbieterneutrale Architektur, um eine wirklich souveräne Plattform zu bauen. Die Kernidee: Souveränität nicht als eine zu beschaffende Sache behandeln, sondern als &lt;strong&gt;drei unabhängige Schichten, für die du entwirfst&lt;/strong&gt; — mit Kubernetes als Portabilitäts-Rückgrat, das sie verbindet.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Das baut auf einem Sicherheitsfundament auf, ersetzt es nicht. Ist deine Plattform nicht zuerst gehärtet, ist Souveränität irrelevant — starte mit der &lt;a href="https://www.alekseialeinikov.com/de/blog/topics/architecture/secure-by-default-gke-referenzarchitektur-2026" rel="noopener noreferrer"&gt;Secure-by-Default-GKE-Referenzarchitektur&lt;/a&gt; und lege Souveränität darüber.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Souveränität besteht aus drei Schichten, nicht aus einer
&lt;/h2&gt;

&lt;p&gt;Der größte Fehler ist, „souverän“ als Binärzustand zu behandeln, den man hat oder nicht. Es sind in Wahrheit drei getrennte Fragen — eine Plattform kann bei einer stark abschneiden und bei einer anderen durchfallen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F99pry76dyfiky4yvurky.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F99pry76dyfiky4yvurky.webp" alt="Die drei Schichten der Souveränität — Datenresidenz und Zugriff, betriebliche Kontrolle und technische Portabilität — und was jede davon dir erhält." width="799" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Datensouveränität&lt;/strong&gt; — Wo liegen die Daten physisch, und &lt;em&gt;wer kann rechtlich Zugriff erzwingen&lt;/em&gt;? Residency ist nur die halbe Miete; die rechtliche Reichweite über den Betreiber ist die andere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Betriebssouveränität&lt;/strong&gt; — Wer betreibt die Steuerungsebene? Wer kann das laufende System lesen, administrieren oder gezwungen werden, es offenzulegen?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technische Souveränität&lt;/strong&gt; — Kannst du gehen? Sind deine Workloads portabel oder an die proprietären APIs eines Anbieters geschweißt?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ein typisches „souveränes“ Angebot deckt eine davon überzeugend ab und winkt beim Rest ab. Echte Souveränität heißt, für alle drei zu entwerfen — nehmen wir sie in der Reihenfolge, die den größten Hebel gibt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Die Freiheit zu gehen: Portabilität als der echte Test
&lt;/h2&gt;

&lt;p&gt;Technische Souveränität hat einen brutal einfachen Test: &lt;strong&gt;Was kostet es dich zu gehen?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Bedeutet das Verlassen eines Anbieters, deine Anwendungen neu zu schreiben und um andere proprietäre Dienste herum neu zu architektieren, bist du gefangen — und Lock-in ist das genaue Gegenteil von Souveränität. Bedeutet Weggehen, &lt;em&gt;dieselben&lt;/em&gt; Manifeste auf einem anderen konformen Cluster neu auszurollen, bist du auf der technischen Schicht souverän.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fstr2mjobje0sw87wpbr1.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fstr2mjobje0sw87wpbr1.webp" alt="Portabilität als Freiheit zu gehen: proprietäre Dienste erzwingen ein Rewrite, während Kubernetes-Manifeste unverändert über GKE, EKS, AKS oder ein EU-gehostetes Cluster neu ausgerollt werden." width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hier verdient sich Kubernetes seinen Platz — nicht als Container-Scheduler, sondern als &lt;strong&gt;Portabilitätsschicht&lt;/strong&gt;. Standard-Kubernetes-Manifeste, OCI-Images, Helm-Charts und Infrastructure-as-Code sind über jede große Plattform und On-Premises konform. Der Workload ändert sich nicht, wenn sich der Boden darunter ändert.&lt;/p&gt;

&lt;p&gt;Portabilität ist aber nicht gratis. Der Workload-&lt;em&gt;Kern&lt;/em&gt; reist mit; die &lt;em&gt;Ränder&lt;/em&gt; nicht — Storage Classes, Ingress-Controller, LoadBalancer-Annotationen und Cloud-Identity-Integration sind anbieterspezifisch und müssen bewusst abstrahiert oder getauscht werden. Echte Portabilität heißt, diesen Kern sauber und die anbieterspezifischen Ränder dünn und austauschbar zu halten — nicht so zu tun, als ändere sich beim Umzug nichts.&lt;/p&gt;

&lt;p&gt;Die Disziplin besteht darin, deinen &lt;strong&gt;kritischen Pfad&lt;/strong&gt; auf portablen, standardbasierten Komponenten zu halten und jeden proprietären Managed Service als bewussten Kompromiss zu behandeln. Eine Queue als Kubernetes-Workload zieht überallhin; eine Queue, die eine anbieterspezifische API ist, ist ein Anker.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Portabel: der Workload ist ein Standard-Objekt, keine Vendor-API.&lt;/span&gt;
&lt;span class="c1"&gt;# Dasselbe Manifest läuft auf GKE, EKS, AKS oder einem EU-gehosteten Cluster.&lt;/span&gt;

&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;

&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;

&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ingest&lt;/span&gt;

&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;

  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ingest&lt;/span&gt;

          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;registry.example.eu/ingest:1.8.0&lt;/span&gt; &lt;span class="c1"&gt;# deine Registry, deine Region&lt;/span&gt;

          &lt;span class="na"&gt;envFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;secretRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

                &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ingest-config&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Portabilität heißt nicht, nie einen Managed Service zu nutzen. Sie heißt, für jeden zu wissen, was das Verlassen genau kosten würde — damit „wir könnten wechseln“ ein gemessener Ausstiegsplan ist und kein beruhigender Slogan.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wer hält die Schlüssel: Residency ist nicht Hoheit
&lt;/h2&gt;

&lt;p&gt;Hier ist die Falle, die die meisten „unsere Daten liegen in einer EU-Region, also sind wir souverän“-Behauptungen versenkt.&lt;/p&gt;

&lt;p&gt;Data Residency wählt, &lt;em&gt;wo die Bytes liegen&lt;/em&gt;. Sie sagt nichts darüber, &lt;em&gt;wer sie lesen kann&lt;/em&gt;. Ein Anbieter unter fremdem Rechtsregime — der US CLOUD Act ist das Paradebeispiel — kann gezwungen werden, Daten herauszugeben, egal in welcher Region sie liegen. Residency allein stoppt das nicht.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzvva9sm0ik5hva583j69.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzvva9sm0ik5hva583j69.webp" alt="Schlüsselhoheit vs. CLOUD Act: Hältst du die Schlüssel in einem externen Manager, speichert der Anbieter nur Ciphertext und rechtlicher Zugriff bringt nichts Lesbares." width="800" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Der Kontrollpunkt, der das Ergebnis wirklich ändert, ist &lt;strong&gt;Schlüsselhoheit&lt;/strong&gt;. Was sie wirklich liefert, ist &lt;strong&gt;HYOK&lt;/strong&gt; (Hold Your Own Key) — ein &lt;strong&gt;externer Key Manager&lt;/strong&gt; wie Googles External Key Manager (EKM) oder AWS XKS, bei dem der Anbieter zum Entschlüsseln &lt;em&gt;deinen&lt;/em&gt; Key-Dienst aufruft und das Schlüsselmaterial nie selbst hält. Reines &lt;strong&gt;BYOK&lt;/strong&gt; , bei dem du einen Schlüssel in das KMS des Anbieters importierst, ist schwächer: Der Anbieter hält den Schlüssel dann doch und schützt gegen eine andere, kleinere Bedrohung. Bei echter externer Hoheit gilt:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Der Anbieter speichert deine Daten &lt;strong&gt;verschlüsselt&lt;/strong&gt; , und Ciphertext ohne deinen Schlüssel ist Rauschen.&lt;/li&gt;
&lt;li&gt;Wird er rechtlich zur Herausgabe gezwungen, kann er nur denselben wertlosen Ciphertext produzieren.&lt;/li&gt;
&lt;li&gt;Widerrufe den Zugriff auf den Schlüssel und neue Entschlüsselungen stoppen überall auf einmal — bereits gecachte Data Keys laufen kurz danach aus — was effektiv Crypto-Shredding der Daten ist.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Residency und Schlüsselhoheit ergänzen sich: Residency beantwortet „wo“, Hoheit beantwortet „wer kann es lesen“. Die Hoheit macht aus einer rechtlichen Anfrage einen Nicht-Vorfall.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Schlüssel sind auch auf der Identitätsschicht das ganze Spiel. Dasselbe Prinzip „kein langlebiges Geheimnis zum Beschlagnahmen“ gilt für Workload-Credentials — siehe &lt;a href="https://www.alekseialeinikov.com/de/blog/topics/security/service-account-schluessel-abschaffen-workload-identity-federation-2026" rel="noopener noreferrer"&gt;Schluss mit Service-Account-Schlüsseln mit Workload Identity Federation&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Betriebssouveränität: Wer kann es lesen und betreiben
&lt;/h2&gt;

&lt;p&gt;Die leiseste Schicht ist die betriebliche. Selbst mit portablen Workloads und kundengehaltenen Schlüsseln leckt Souveränität, wenn die Betreiber der Ebene deine Systeme still von außerhalb deiner Jurisdiktion lesen oder administrieren können.&lt;/p&gt;

&lt;p&gt;Für Betriebssouveränität zu entwerfen heißt:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;EU-only-Betrieb&lt;/strong&gt; für regulierte Workloads — Support und Administration innerhalb der Jurisdiktion, nicht global geroutet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access Transparency&lt;/strong&gt; — jeder anbieterseitige Zugriff auf deine Umgebung wird protokolliert und ist für dich sichtbar, sodass aus „vertrau uns“ ein „überprüfe“ wird.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Least Privilege und Just-in-Time-Zugriff&lt;/strong&gt; — kein stehender Admin-Zugriff; Elevation ist scoped, zeitlich begrenzt und auditiert.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dein eigener Audit-Trail&lt;/strong&gt; — Logs in Speicher, den &lt;em&gt;du&lt;/em&gt; kontrollierst, damit der Nachweis, wer was getan hat, nicht vom Wohlwollen des Anbieters abhängt.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nichts davon ist exotisch. Es ist dieselbe Zugriffskontroll-Disziplin, die du bereits auf deine eigenen Teams anwendest — erweitert auf den Anbieter als nicht vertrauenswürdigen Betreiber.&lt;/p&gt;

&lt;h2&gt;
  
  
  Souveränität ohne Dogma: Ein Entscheidungsrahmen
&lt;/h2&gt;

&lt;p&gt;Der Fehlermodus auf der anderen Seite ist, Souveränität als Reinheitstest zu behandeln und eine schwere Velocity-Steuer zu zahlen, um eine Marketing-Broschüre mit null echten Workloads zu bauen. Souveränität ist ein &lt;strong&gt;Spektrum&lt;/strong&gt; , und du wendest sie per Klassifizierung an, nicht per Reflex.&lt;/p&gt;

&lt;p&gt;Ein pragmatischer Rahmen:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Klassifiziere den Workload.&lt;/strong&gt; Regulierte oder hochsensible Daten, oder ein System, dessen Kompromittierung existenziell ist? Es verdient die volle Behandlung: portable Komponenten, externe Schlüsselhoheit, Betriebskontrollen. Ein zustandsloses internes Tool ohne sensible Daten? Ein bequemer Managed Service ist ein völlig rationaler Kompromiss.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Miss das Lock-in, nimm es nicht an.&lt;/strong&gt; Notiere für jede proprietäre Abhängigkeit im kritischen Pfad die echten Kosten des Weggehens. Manche sind billig zu tauschen; manche sind Anker. Du kannst nicht steuern, was du nicht gemessen hast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Entwirf den Ausstieg, bevor du ihn brauchst.&lt;/strong&gt; Portabilität, die nie geübt wurde, ist Hoffnung, keine Fähigkeit. Halte die Option echt: Standard-Manifeste, deine eigene Registry, Schlüssel, die du hältst, Infrastructure-as-Code, die eine zweite Plattform ansteuern kann.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So angewandt hört Souveränität auf, ein Glaubensstreit zu sein, und wird zu einem Engineering-Kompromiss, den du bewusst triffst — Workload für Workload.&lt;/p&gt;

&lt;h2&gt;
  
  
  Die ehrlichen Grenzen
&lt;/h2&gt;

&lt;p&gt;Souveränität hat einen Preis, und das Gegenteil zu behaupten führt dazu, sie zu bereuen. Portable, standardbasierte Komponenten bedeuten manchmal, auf den schicksten proprietären Dienst zu verzichten. Externe Schlüsselhoheit fügt Betriebskomplexität und einen eigenen Fehlermodus hinzu — verlierst du den Schlüssel, sind die Daten wirklich weg. Volle Betriebssouveränität kann Support-Kosten erhöhen. Und keine Architektur entfernt die rechtliche Realität, dass du, wenn du überhaupt bei einem Anbieter läufst, &lt;em&gt;etwas&lt;/em&gt; vertraust.&lt;/p&gt;

&lt;p&gt;Der Punkt ist nicht maximale Souveränität überall. Er ist, dass Souveränität zu einer &lt;strong&gt;Eigenschaft wird, die du bewusst entworfen hast&lt;/strong&gt; — gemessen, klassifiziert und geübt — statt zu einem Aufkleber, den dir jemand verkauft hat. Baue die drei Schichten bewusst, halte den Ausstieg echt, halte deine eigenen Schlüssel, und „souverän“ hört auf, eine Behauptung zu sein, die hoffentlich der Prüfung standhält, und wird zu einer, die du tatsächlich belegen kannst.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ursprünglich veröffentlicht auf &lt;a href="https://www.alekseialeinikov.com/de/blog/topics/architecture/sovereign-by-design-eine-souveraene-plattform-auf-kubernetes-bauen-2026" rel="noopener noreferrer"&gt;alekseialeinikov.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>souveraenecloud</category>
      <category>digitalesouveraenita</category>
      <category>kubernetes</category>
      <category>dataresidency</category>
    </item>
    <item>
      <title>Podman 2026: Rootless und daemonlose Container ohne Docker</title>
      <dc:creator>Aleksei Aleinikov</dc:creator>
      <pubDate>Sat, 11 Jul 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/aleksei_aleinikov/podman-2026-rootless-und-daemonlose-container-ohne-docker-4gb3</link>
      <guid>https://dev.to/aleksei_aleinikov/podman-2026-rootless-und-daemonlose-container-ohne-docker-4gb3</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffwoidxhyda7ep27iwpme.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffwoidxhyda7ep27iwpme.webp" alt="Podman 2026: Rootless und daemonlose Container ohne Docker" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wer schon einmal einen Container von Hand gebaut hat — ein Overlay-Mount, eine cgroup, ein paar Namespaces, ein &lt;code&gt;pivot_root&lt;/code&gt; — versteht Podman bereits besser als die meisten Docker-Nutzer. Podman ist im Kern genau dieselben Kernel-Primitive, verpackt in eine freundliche CLI, bei der zwei von Dockers ältesten Design-Entscheidungen leise entfernt wurden: der &lt;strong&gt;Root-Daemon&lt;/strong&gt; und die Annahme, dass man als Root arbeitet.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Neu hier? Am besten &lt;em&gt;spürst&lt;/em&gt; du, was ein Container wirklich ist, wenn du einen von Grund auf zusammensetzt — siehe &lt;a href="https://www.alekseialeinikov.com/de/blog/topics/devops/kleinen-linux-container-ohne-docker-bauen-2026" rel="noopener noreferrer"&gt;Einen kleinen Linux-Container ohne Docker bauen&lt;/a&gt;. Dieser Artikel macht dort weiter: Was passiert, wenn jemand diese Primitive ordentlich zum Produkt macht.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Das ist kein „Docker ist tot“-Text. Docker ist weiterhin exzellent und überall. Aber 2026 ist &lt;code&gt;podman&lt;/code&gt; das Werkzeug, zu dem ich auf Servern und in CI zuerst greife — und es lohnt sich zu verstehen &lt;em&gt;warum&lt;/em&gt;, statt nur das Binary zu tauschen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dockers zwei Design-Entscheidungen, die schlecht gealtert sind
&lt;/h2&gt;

&lt;p&gt;Docker hat Container populär gemacht, traf aber zwei frühe Entscheidungen, die heute schwerer wirken als 2013.&lt;/p&gt;

&lt;p&gt;Die erste ist der &lt;strong&gt;Daemon&lt;/strong&gt;. Der &lt;code&gt;docker&lt;/code&gt;-Befehl, den du tippst, ist nur ein dünner Client; die eigentliche Arbeit macht &lt;code&gt;dockerd&lt;/code&gt;, ein dauerhaft laufender Hintergrunddienst. Dieser Daemon lief historisch als &lt;strong&gt;Root&lt;/strong&gt; , und alles, was du startest, ist ein Kindprozess davon.&lt;/p&gt;

&lt;p&gt;Die zweite ist genau diese &lt;strong&gt;Root&lt;/strong&gt; -Haltung. Jahrelang bedeutete Container-Betrieb, einem root-eigenen Daemon die Kontrolle über deinen Prozessbaum, deine Mounts und dein Netzwerk zu geben.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh5q4v1c9z43xc8yd9k8q.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh5q4v1c9z43xc8yd9k8q.webp" alt="Docker leitet jeden Container durch einen einzigen dauerhaft laufenden Root-Daemon; Podman forkt jeden Container direkt, ohne Daemon dazwischen." width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Keine der Entscheidungen ist ein Fehler. Aber beide konzentrieren Risiko. Ein einziger dauerhaft als Root laufender Prozess ist ein einziges, permanentes, hochwertiges Ziel — und ein Single Point of Failure. Stirbt &lt;code&gt;dockerd&lt;/code&gt;, sind alle beaufsichtigten Container betroffen. Wird er kompromittiert, ist der Host kompromittiert.&lt;/p&gt;

&lt;p&gt;Podman entfernt den Daemon vollständig.&lt;/p&gt;

&lt;h2&gt;
  
  
  Was „daemonlos“ tatsächlich bringt
&lt;/h2&gt;

&lt;p&gt;Wenn du &lt;code&gt;podman run&lt;/code&gt; ausführst, gibt es keinen Hintergrunddienst, mit dem geredet wird. Die CLI forkt und exect den Container direkt. Ein kleiner Helfer namens &lt;code&gt;conmon&lt;/code&gt; bleibt angehängt, um den Container zu überwachen und seine Logs zu halten, und die OCI-Runtime (&lt;code&gt;runc&lt;/code&gt; oder &lt;code&gt;crun&lt;/code&gt;) erledigt die Low-Level-Arbeit — aber es gibt keinen privilegierten, dauerhaft laufenden Vermittler dazwischen.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terminal window&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
podman run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; alpine sh

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Der Befehl sieht identisch zu Docker aus. Unter der Haube ist er grundlegend anders: &lt;strong&gt;Vorher lief nichts, und nach dem Beenden des Containers bleibt kein Root-Dienst zurück.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Die praktischen Vorteile:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Kleinere Angriffsfläche.&lt;/strong&gt; Es gibt keinen Root-Daemon-Socket, den man schützen, leaken oder versehentlich in einen Container mounten könnte.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Saubere Prozessüberwachung.&lt;/strong&gt; Weil jeder Container nur ein Kindprozess ist, kann dein Init-System ihn direkt beaufsichtigen — kein „Wer startet den Daemon neu, der den Container neu startet“-Rätsel.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kein Single Point of Failure.&lt;/strong&gt; Podman neu zu starten oder zu aktualisieren legt laufende Container nicht lahm, wie es ein Daemon-Neustart tun kann.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Der Kompromiss ist real und gehört benannt: Manche Bequemlichkeiten eines Daemons — ein zentraler Event-Stream, immer warmer Zustand, ein Hintergrund-API-Socket — brauchen nun einen anderen Mechanismus. Dazu kommen wir mit systemd.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rootless: Das Container-Root ist nicht das Host-Root
&lt;/h2&gt;

&lt;p&gt;Das ist die Funktion, die verändert hat, wie ich deploye.&lt;/p&gt;

&lt;p&gt;Im Rootless-Modus läuft der gesamte Container-Stack als dein normaler, unprivilegierter Benutzer. Es gibt keinen root-eigenen Daemon und kein setuid-Binary im heißen Pfad. Trotzdem sehen sich Prozesse &lt;em&gt;im&lt;/em&gt; Container weiterhin als &lt;code&gt;root&lt;/code&gt; (UID 0) und verhalten sich normal — weil Podman einen &lt;strong&gt;User-Namespace&lt;/strong&gt; nutzt, um Identitäten zu mappen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr8v7bagu753au5bltoxh.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr8v7bagu753au5bltoxh.webp" alt="Im Container ist ein Prozess UID 0; der User-Namespace mappt ihn auf eine unprivilegierte UID wie 100000 auf dem Host, sodass ein Ausbruch als Niemand landet." width="799" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Das Mapping stammt aus zwei Dateien, &lt;code&gt;/etc/subuid&lt;/code&gt; und &lt;code&gt;/etc/subgid&lt;/code&gt;, die deinem Benutzer einen Bereich untergeordneter IDs zuweisen:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terminal window&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/subuid

&lt;span class="c"&gt;# alex:100000:65536&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Diese Zeile sagt: Der Benutzer &lt;code&gt;alex&lt;/code&gt; besitzt die Host-UIDs &lt;code&gt;100000&lt;/code&gt; bis &lt;code&gt;165535&lt;/code&gt; zur Nutzung in Containern. Podman mappt Container-UID 0 auf &lt;code&gt;100000&lt;/code&gt;, Container-UID 1 auf &lt;code&gt;100001&lt;/code&gt; und so weiter.&lt;/p&gt;

&lt;p&gt;Die Sicherheitsfolge ist der ganze Punkt. Bricht ein Angreifer aus einem rootless Container aus, landet er nicht als Host-Root. Er landet als UID &lt;code&gt;100000&lt;/code&gt; — ein Konto, das auf dem Host nichts besitzt. Der Schaden schrumpft von „die Maschine gehört mir“ auf „ein Namespace gehört mir, der nichts Wichtiges anfassen kann“.&lt;/p&gt;

&lt;p&gt;Der Einstieg ist bewusst langweilig:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terminal window&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# kein sudo, kein Daemon-Setup&lt;/span&gt;

podman info | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; rootless

&lt;span class="c"&gt;# rootless: true&lt;/span&gt;

podman run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; web &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:80 docker.io/library/nginx

curl &lt;span class="nt"&gt;-s&lt;/span&gt; localhost:8080 | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Rootless-Portbindung unter 1024 ist der eine Stolperstein, den die meisten treffen — unprivilegierte Benutzer dürfen niedrige Ports standardmäßig nicht binden, deshalb mappt das Beispiel &lt;code&gt;8080&lt;/code&gt;. Du kannst die Schwelle per sysctl senken, wenn du wirklich &lt;code&gt;:80&lt;/code&gt; brauchst, aber ein hoher Port ist die sauberere Gewohnheit.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;podman unshare&lt;/code&gt;: Dieselben Namespaces, mit Netz
&lt;/h2&gt;

&lt;p&gt;Wer die Von-Hand-Container-Übung gemacht hat, hat &lt;code&gt;unshare --user --mount --pid ...&lt;/code&gt; getippt und danach alles sorgfältig selbst verdrahtet. &lt;code&gt;podman unshare&lt;/code&gt; gibt dir dieselbe Welt — eine Shell in deinem User-Namespace — aber mit bereits angewandtem UID-Mapping und ohne die scharfen Kanten.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terminal window&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
podman unshare &lt;span class="nb"&gt;cat&lt;/span&gt; /proc/self/uid_map

&lt;span class="c"&gt;# 0 100000 65536&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;In dieser Shell &lt;em&gt;bist&lt;/em&gt; du Root (UID 0), um Dateien zu bearbeiten, die ein Container erstellt hat. So korrigierst du Besitzrechte auf einem rootless Volume ohne &lt;code&gt;sudo&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terminal window&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
podman unshare &lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; 0:0 ./data

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Es ist die freundliche, abgesicherte Version des rohen &lt;code&gt;unshare&lt;/code&gt;-Tanzes — derselbe Kernel-Mechanismus, weit weniger Chance, den Host zu verletzen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pods: Die Idee, die Kubernetes übernommen hat
&lt;/h2&gt;

&lt;p&gt;Podmans Name ist ein Hinweis. Ein &lt;strong&gt;Pod&lt;/strong&gt; ist eine Gruppe von Containern, die sich einen Netzwerk- und IPC-Namespace teilen und sich daher über &lt;code&gt;localhost&lt;/code&gt; erreichen — ohne Bridge und ohne veröffentlichte Ports dazwischen.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terminal window&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
podman pod create &lt;span class="nt"&gt;--name&lt;/span&gt; app &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080

podman run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--pod&lt;/span&gt; app &lt;span class="nt"&gt;--name&lt;/span&gt; api my-api:latest

podman run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--pod&lt;/span&gt; app &lt;span class="nt"&gt;--name&lt;/span&gt; cache docker.io/library/redis

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Der &lt;code&gt;api&lt;/code&gt;-Container erreicht Redis unter &lt;code&gt;127.0.0.1:6379&lt;/code&gt;, weil sie sich einen Netzwerk-Namespace teilen. Das ist exakt das Modell, das Kubernetes nutzt — kein Zufall. Podman kann sogar Kubernetes-YAML ausgeben und lesen:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terminal window&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
podman kube generate app &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; app.yaml

podman kube play app.yaml

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Das macht Podman zu einer wirklich nützlichen lokalen Dev-Schleife für alle, die nach Kubernetes ausliefern: Prototype den Pod auf dem Laptop, übergib dann dasselbe Manifest ans Cluster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quadlet: systemd deine Container betreiben lassen
&lt;/h2&gt;

&lt;p&gt;Hier löst sich die „kein Daemon“-Geschichte auf. Dockers Daemon startet deine Container beim Boot und nach Absturz neu. Podman hat dafür keinen Daemon — also delegiert es an das Init-System, dem du ohnehin vertraust: &lt;strong&gt;systemd&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Der moderne Weg dafür ist &lt;strong&gt;Quadlet&lt;/strong&gt;. Du schreibst eine kleine deklarative Unit-Datei, legst sie in &lt;code&gt;~/.config/containers/systemd/&lt;/code&gt;, und systemd macht daraus einen voll verwalteten Dienst.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F31p2o8gprcbrkrqk7blh.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F31p2o8gprcbrkrqk7blh.webp" alt="Ein Pod speist eine Quadlet-.container-Unit, die systemd direkt liest, um beim Boot zu starten, nach Absturz neu zu starten und in journald zu loggen." width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;~/.config/containers/systemd/web.container&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[Container]&lt;/span&gt;

&lt;span class="py"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;docker.io/library/nginx:latest&lt;/span&gt;

&lt;span class="py"&gt;PublishPort&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;8080:80&lt;/span&gt;

&lt;span class="nn"&gt;[Service]&lt;/span&gt;

&lt;span class="py"&gt;Restart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;always&lt;/span&gt;

&lt;span class="nn"&gt;[Install]&lt;/span&gt;

&lt;span class="py"&gt;WantedBy&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;default.target&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Neu laden und starten wie jeden anderen Dienst:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terminal window&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
systemctl &lt;span class="nt"&gt;--user&lt;/span&gt; daemon-reload

systemctl &lt;span class="nt"&gt;--user&lt;/span&gt; start web

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Du hast jetzt einen Container, der beim Boot startet, nach Absturz neu startet, in &lt;code&gt;journald&lt;/code&gt; loggt und vollständig rootless läuft — beaufsichtigt vom selben Werkzeug, das den Rest deines Systems verwaltet. Kein Hintergrund-Container-Daemon nötig.&lt;/p&gt;

&lt;p&gt;Wer Podman schon genutzt hat, erinnert sich vielleicht an &lt;code&gt;podman generate systemd&lt;/code&gt;. Quadlet &lt;strong&gt;ersetzt&lt;/strong&gt; es. Der alte Befehl erzeugte brüchige, schwer editierbare Unit-Dateien; Quadlet-Units sind deklarativ, lesbar und der offiziell empfohlene Weg.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker vs. Podman auf einen Blick
&lt;/h2&gt;

&lt;p&gt;Docker vs. Podman auf einen Blick| | Docker | Podman |&lt;br&gt;
| --- | --- | --- |&lt;br&gt;
| Architektur | Client + dauerhafter Daemon | Daemonlos (fork/exec + conmon) |&lt;br&gt;
| Standard-Privileg | Historisch Root-Daemon | Rootless standardmäßig |&lt;br&gt;
| Container-Ausbruch landet als | Potenziell Host-Root | Unprivilegierte Host-UID |&lt;br&gt;
| Boot-/Neustart-Aufsicht | Docker-Daemon | systemd (via Quadlet) |&lt;br&gt;
| Pods | Kein natives Konzept | Erstklassig, Kubernetes-kompatibel |&lt;br&gt;
| CLI | &lt;code&gt;docker&lt;/code&gt; | &lt;code&gt;podman&lt;/code&gt; (gleiche Verben) |&lt;br&gt;
| Kubernetes-YAML | Drittanbieter-Tools | &lt;code&gt;generate kube&lt;/code&gt; / &lt;code&gt;play kube&lt;/code&gt; eingebaut |&lt;/p&gt;

&lt;h2&gt;
  
  
  Wo Podman noch nicht Docker ist
&lt;/h2&gt;

&lt;p&gt;Ein ehrlicher Leitfaden benennt die rauen Kanten. Podman ist keine strikte Obermenge von Docker, und ein paar Dinge brauchen Anpassung:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;macOS und Windows&lt;/strong&gt; führen Container in einer Linux-VM aus (&lt;code&gt;podman machine&lt;/code&gt;), genau wie Docker Desktop. Der Daemonlos-Vorteil ist ein Linux-Host-Vorteil; auf einem Mac redest du weiter mit einer VM.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compose&lt;/strong&gt; funktioniert über &lt;code&gt;podman compose&lt;/code&gt; (delegiert an die Compose-Engine) oder &lt;code&gt;podman-compose&lt;/code&gt;, und die Abdeckung ist sehr gut — aber es ist Kompatibilität, nicht dieselbe Codebasis, sodass exotische Compose-Dateien überraschen können.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Das Ökosystem&lt;/strong&gt; aus GUIs, IDE-Integrationen und Drittanbieter-Tools nimmt weiter zuerst Docker an. Podman Desktop hat das meiste davon geschlossen, aber „Docker zuerst, Podman auch“ ist noch der übliche Default.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Eine Hintergrund-API&lt;/strong&gt; für Tools, die einen Socket pollen wollen, braucht Podmans optionalen Dienst (&lt;code&gt;podman system service&lt;/code&gt;) — ironischerweise ein Daemon, den du bewusst einschaltest, statt einer, den du zwingend betreiben musst.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keiner dieser Punkte ist ein K.-o.-Kriterium auf Linux-Servern oder in CI — genau dort, wo daemonlos und rootless am meisten zahlen.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Namespaces und cgroups sind stark, aber sie bleiben eine Grenze mit geteiltem Kernel. Wenn du wirklich nicht vertrauenswürdigen Code ausführen musst — Multi-Tenant-Workloads, beliebige Nutzer-Einreichungen — greif zu einer stärkeren Isolationsschicht: siehe &lt;a href="https://www.alekseialeinikov.com/de/blog/topics/devops/microvms-firecracker-vs-gvisor-sichere-workloads-2026" rel="noopener noreferrer"&gt;microVMs: Firecracker vs. gVisor&lt;/a&gt;, wo die Container-Grenze endet und eine Hardware- oder Syscall-Sandbox beginnt.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Solltest du wechseln?
&lt;/h2&gt;

&lt;p&gt;Auf einem Linux-Server oder CI-Runner ist der Fall einfach: rootless, daemonloses Podman entfernt ein permanentes root-eigenes Ziel und übergibt die Aufsicht an systemd, das ohnehin läuft. Die CLI ist nah genug an Docker, dass die meiste Muskelerinnerung unverändert überträgt — oft mit einem einzigen &lt;code&gt;alias docker=podman&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Auf einem Entwickler-Laptop — besonders macOS oder Windows — ist der Gewinn kleiner, weil du wieder in einer VM sitzt und dich auf Compose-Kompatibilität stützt. Dort ist „wechsle, wenn es hilft, bleib, wenn nicht“ eine völlig vernünftige Antwort.&lt;/p&gt;

&lt;p&gt;Der tiefere Grund, Podman zu lernen, ist nicht das Logo. Es ist, dass Podman die &lt;em&gt;Gestalt&lt;/em&gt; eines Containers wieder offensichtlich macht: ein Kindprozess, in einem User-Namespace, beaufsichtigt von Init. Wenn du einmal einen von Hand gebaut und dann Podman dasselbe sauber tun gesehen hast, hören Container auf, Magie zu sein — und dieses Verständnis überdauert, welche CLI du auch tippst.&lt;/p&gt;

</description>
      <category>podman</category>
      <category>rootlesscontainer</category>
      <category>daemonlos</category>
      <category>quadlet</category>
    </item>
    <item>
      <title>Podman in 2026: Rootless, Daemonless Containers Without Docker</title>
      <dc:creator>Aleksei Aleinikov</dc:creator>
      <pubDate>Sat, 11 Jul 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/aleksei_aleinikov/podman-in-2026-rootless-daemonless-containers-without-docker-1fon</link>
      <guid>https://dev.to/aleksei_aleinikov/podman-in-2026-rootless-daemonless-containers-without-docker-1fon</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffwoidxhyda7ep27iwpme.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffwoidxhyda7ep27iwpme.webp" alt="Podman in 2026: Rootless, Daemonless Containers Without Docker"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have ever built a container by hand — an overlay mount, a cgroup, a few namespaces, a &lt;code&gt;pivot_root&lt;/code&gt; — you already understand Podman better than most Docker users. Podman is essentially those same kernel primitives, wrapped in a friendly CLI, with two of Docker’s oldest design decisions quietly removed: the &lt;strong&gt;root daemon&lt;/strong&gt; and the assumption that you run as root.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;New here? The clearest way to &lt;em&gt;feel&lt;/em&gt; what a container really is comes from assembling one from scratch — see &lt;a href="https://www.alekseialeinikov.com/en/blog/topics/devops/build-a-tiny-linux-container-without-docker-2026" rel="noopener noreferrer"&gt;Build a Tiny Linux Container without Docker&lt;/a&gt;. This article picks up where that leaves off: what happens when someone productizes those primitives properly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is not a “Docker is dead” piece. Docker is still excellent and still everywhere. But in 2026, &lt;code&gt;podman&lt;/code&gt; is the tool I reach for first on servers and CI, and it is worth understanding &lt;em&gt;why&lt;/em&gt; rather than just swapping the binary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker’s Two Design Decisions That Aged Badly
&lt;/h2&gt;

&lt;p&gt;Docker popularized containers, but it made two early choices that look heavier today than they did in 2013.&lt;/p&gt;

&lt;p&gt;The first is the &lt;strong&gt;daemon&lt;/strong&gt;. The &lt;code&gt;docker&lt;/code&gt; command you type is just a thin client; the real work happens in &lt;code&gt;dockerd&lt;/code&gt;, a long-running background service. That daemon has historically run as &lt;strong&gt;root&lt;/strong&gt; , and everything you launch is a child of it.&lt;/p&gt;

&lt;p&gt;The second is that &lt;strong&gt;root&lt;/strong&gt; posture. For years, running containers meant handing a root-owned daemon control over your process tree, your mounts, and your network.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh5q4v1c9z43xc8yd9k8q.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh5q4v1c9z43xc8yd9k8q.webp" alt="Docker routes every container through a single always-on root daemon; Podman forks each container directly with no daemon in the middle."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Neither choice is a bug. But both concentrate risk. A single always-on process running as root is a single, permanent, high-value target — and a single point of failure. If &lt;code&gt;dockerd&lt;/code&gt; dies, every container it supervises is affected. If it is compromised, the host is compromised.&lt;/p&gt;

&lt;p&gt;Podman removes the daemon entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  What “Daemonless” Actually Buys You
&lt;/h2&gt;

&lt;p&gt;When you run &lt;code&gt;podman run&lt;/code&gt;, there is no background service to talk to. The CLI forks and execs the container directly. A small helper called &lt;code&gt;conmon&lt;/code&gt; stays attached to monitor the container and keep its logs, and the OCI runtime (&lt;code&gt;runc&lt;/code&gt; or &lt;code&gt;crun&lt;/code&gt;) does the low-level work — but there is no privileged, always-on broker sitting in the middle.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terminal window&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
podman run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; alpine sh

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;That command looks identical to Docker. Under the hood it is fundamentally different: &lt;strong&gt;nothing was running before you typed it, and nothing lingers as a root service after the container exits.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The practical payoffs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A smaller attack surface.&lt;/strong&gt; There is no root daemon socket to protect, leak, or bind-mount into a container by accident.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clean process supervision.&lt;/strong&gt; Because each container is just a child process, your init system can supervise it directly — no “who restarts the daemon that restarts the container” puzzle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No single point of failure.&lt;/strong&gt; Restarting or upgrading Podman does not take down running containers the way bouncing a daemon can.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The trade-off is real and worth naming: some conveniences that a daemon provides — a central event stream, always-warm state, a background API socket — now need a different mechanism. We will get to that with systemd.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rootless: The Container Root Is Not Host Root
&lt;/h2&gt;

&lt;p&gt;This is the feature that changed how I deploy.&lt;/p&gt;

&lt;p&gt;In rootless mode, the entire container stack runs as your normal, unprivileged user. There is no root-owned daemon and no setuid binary in the hot path. Yet inside the container, processes still see themselves as &lt;code&gt;root&lt;/code&gt; (UID 0) and behave normally — because Podman uses a &lt;strong&gt;user namespace&lt;/strong&gt; to map identities.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr8v7bagu753au5bltoxh.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr8v7bagu753au5bltoxh.webp" alt="Inside the container a process is UID 0; the user namespace maps it to an unprivileged UID like 100000 on the host, so an escape lands as a nobody."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The mapping comes from two files, &lt;code&gt;/etc/subuid&lt;/code&gt; and &lt;code&gt;/etc/subgid&lt;/code&gt;, which grant your user a range of subordinate IDs:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terminal window&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/subuid

&lt;span class="c"&gt;# alex:100000:65536&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;That line says: the user &lt;code&gt;alex&lt;/code&gt; owns host UIDs &lt;code&gt;100000&lt;/code&gt; through &lt;code&gt;165535&lt;/code&gt; for use inside containers. Podman maps container UID 0 to &lt;code&gt;100000&lt;/code&gt;, container UID 1 to &lt;code&gt;100001&lt;/code&gt;, and so on.&lt;/p&gt;

&lt;p&gt;The security consequence is the whole point. If an attacker breaks out of a rootless container, they do not land as host root. They land as UID &lt;code&gt;100000&lt;/code&gt; — an account that owns nothing on the host. The blast radius shrinks from “own the machine” to “own a namespace that can’t touch anything important.”&lt;/p&gt;

&lt;p&gt;Getting started is deliberately boring:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terminal window&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# no sudo, no daemon setup&lt;/span&gt;

podman info | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; rootless

&lt;span class="c"&gt;# rootless: true&lt;/span&gt;

podman run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; web &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:80 docker.io/library/nginx

curl &lt;span class="nt"&gt;-s&lt;/span&gt; localhost:8080 | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Rootless port binding below 1024 is the one gotcha most people hit — unprivileged users cannot bind low ports by default, which is why the example maps &lt;code&gt;8080&lt;/code&gt;. You can lower the threshold with a sysctl if you truly need &lt;code&gt;:80&lt;/code&gt;, but mapping a high port is the cleaner habit.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;podman unshare&lt;/code&gt;: The Same Namespaces, With a Net
&lt;/h2&gt;

&lt;p&gt;If you have done the hand-built-container exercise, you have typed &lt;code&gt;unshare --user --mount --pid ...&lt;/code&gt; and then carefully wired up everything yourself. &lt;code&gt;podman unshare&lt;/code&gt; gives you that same world — a shell inside your user namespace — but with the UID mapping already applied and the sharp edges filed off.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terminal window&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
podman unshare &lt;span class="nb"&gt;cat&lt;/span&gt; /proc/self/uid_map

&lt;span class="c"&gt;# 0 100000 65536&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Inside that shell, you &lt;em&gt;are&lt;/em&gt; root (UID 0) for the purpose of manipulating files a container created. This is how you fix ownership on a rootless volume without &lt;code&gt;sudo&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terminal window&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
podman unshare &lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; 0:0 ./data

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;It is the friendly, guard-railed version of the raw &lt;code&gt;unshare&lt;/code&gt; dance — same kernel mechanism, far less chance of hurting the host.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pods: The Idea Kubernetes Borrowed
&lt;/h2&gt;

&lt;p&gt;Podman’s name is a hint. A &lt;strong&gt;pod&lt;/strong&gt; is a group of containers that share a network and IPC namespace, so they talk to each other over &lt;code&gt;localhost&lt;/code&gt; with no bridge and no published ports between them.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terminal window&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
podman pod create &lt;span class="nt"&gt;--name&lt;/span&gt; app &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080

podman run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--pod&lt;/span&gt; app &lt;span class="nt"&gt;--name&lt;/span&gt; api my-api:latest

podman run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--pod&lt;/span&gt; app &lt;span class="nt"&gt;--name&lt;/span&gt; cache docker.io/library/redis

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;The &lt;code&gt;api&lt;/code&gt; container reaches Redis at &lt;code&gt;127.0.0.1:6379&lt;/code&gt; because they share one network namespace. This is the exact model Kubernetes uses — which is not a coincidence. Podman can even emit and consume Kubernetes YAML:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terminal window&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
podman kube generate app &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; app.yaml

podman kube play app.yaml

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;That makes Podman a genuinely useful local dev loop for people who ship to Kubernetes: prototype the pod on your laptop, then hand the same manifest to the cluster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quadlet: Let systemd Run Your Containers
&lt;/h2&gt;

&lt;p&gt;Here is where the “no daemon” story resolves. Docker’s daemon restarts your containers on boot and on crash. Podman does not have a daemon to do that — so it delegates to the init system you already trust: &lt;strong&gt;systemd&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The modern way to wire this up is &lt;strong&gt;Quadlet&lt;/strong&gt;. You write a small declarative unit file, drop it in &lt;code&gt;~/.config/containers/systemd/&lt;/code&gt;, and systemd turns it into a fully managed service.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F31p2o8gprcbrkrqk7blh.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F31p2o8gprcbrkrqk7blh.webp" alt="A pod feeds a Quadlet .container unit, which systemd reads directly to start on boot, restart on crash, and log to journald."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;~/.config/containers/systemd/web.container&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[Container]&lt;/span&gt;

&lt;span class="py"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;docker.io/library/nginx:latest&lt;/span&gt;

&lt;span class="py"&gt;PublishPort&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;8080:80&lt;/span&gt;

&lt;span class="nn"&gt;[Service]&lt;/span&gt;

&lt;span class="py"&gt;Restart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;always&lt;/span&gt;

&lt;span class="nn"&gt;[Install]&lt;/span&gt;

&lt;span class="py"&gt;WantedBy&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;default.target&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Reload and start it like any other service:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terminal window&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
systemctl &lt;span class="nt"&gt;--user&lt;/span&gt; daemon-reload

systemctl &lt;span class="nt"&gt;--user&lt;/span&gt; start web

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;You now have a container that starts on boot, restarts on crash, logs to &lt;code&gt;journald&lt;/code&gt;, and runs entirely rootless — supervised by the same tool that manages the rest of your system. No background container daemon required.&lt;/p&gt;

&lt;p&gt;If you have used Podman before, you might remember &lt;code&gt;podman generate systemd&lt;/code&gt;. Quadlet &lt;strong&gt;replaces&lt;/strong&gt; it. The old command generated brittle, hard-to-edit unit files; Quadlet units are declarative, readable, and the officially recommended path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker vs Podman at a Glance
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Docker&lt;/th&gt;
&lt;th&gt;Podman&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Architecture&lt;/td&gt;
&lt;td&gt;Client + long-running daemon&lt;/td&gt;
&lt;td&gt;Daemonless (fork/exec + conmon)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Default privilege&lt;/td&gt;
&lt;td&gt;Historically root daemon&lt;/td&gt;
&lt;td&gt;Rootless by default&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Container escape lands as&lt;/td&gt;
&lt;td&gt;Potentially host root&lt;/td&gt;
&lt;td&gt;Unprivileged host UID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Boot / restart supervision&lt;/td&gt;
&lt;td&gt;Docker daemon&lt;/td&gt;
&lt;td&gt;systemd (via Quadlet)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pods&lt;/td&gt;
&lt;td&gt;No native concept&lt;/td&gt;
&lt;td&gt;First-class, Kubernetes-compatible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CLI&lt;/td&gt;
&lt;td&gt;&lt;code&gt;docker&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;podman&lt;/code&gt; (same verbs)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kubernetes YAML&lt;/td&gt;
&lt;td&gt;Third-party tools&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;generate kube&lt;/code&gt; / &lt;code&gt;play kube&lt;/code&gt; built in&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Where Podman Still Isn’t Docker
&lt;/h2&gt;

&lt;p&gt;An honest guide names the rough edges. Podman is not a strict superset of Docker, and a few things need adjusting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;macOS and Windows&lt;/strong&gt; run containers inside a Linux VM (&lt;code&gt;podman machine&lt;/code&gt;), exactly like Docker Desktop does. The daemonless benefit is a Linux-host benefit; on a Mac you are still talking to a VM.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compose&lt;/strong&gt; works through &lt;code&gt;podman compose&lt;/code&gt; (delegating to the Compose engine) or &lt;code&gt;podman-compose&lt;/code&gt;, and coverage is very good — but it is compatibility, not the same codebase, so exotic Compose files can surprise you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The ecosystem&lt;/strong&gt; of GUIs, IDE integrations, and third-party tooling still assumes Docker first. Podman Desktop has closed most of this gap, but “Docker first, Podman also” is still the common default.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A background API&lt;/strong&gt; for tools that expect to poll a socket needs Podman’s optional service (&lt;code&gt;podman system service&lt;/code&gt;) — which, ironically, is a daemon you opt into rather than one you are forced to run.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these are dealbreakers on Linux servers or CI, which is exactly where daemonless and rootless pay off most.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Namespaces and cgroups are strong, but they are still a shared-kernel boundary. When you need to run genuinely untrusted code — multi-tenant workloads, arbitrary user submissions — reach for a stronger isolation layer: see &lt;a href="https://www.alekseialeinikov.com/en/blog/topics/devops/microvms-firecracker-vs-gvisor-secure-workloads-2026" rel="noopener noreferrer"&gt;microVMs: Firecracker vs gVisor&lt;/a&gt; for where the container boundary ends and a hardware or syscall sandbox begins.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Should You Switch?
&lt;/h2&gt;

&lt;p&gt;On a Linux server or a CI runner, the case is easy: rootless, daemonless Podman removes a permanent root-owned target and hands supervision to systemd, which is already running. The CLI is close enough to Docker that most muscle memory transfers untouched, often with a single &lt;code&gt;alias docker=podman&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;On a developer laptop — especially macOS or Windows — the win is smaller, because you are back inside a VM and leaning on Compose compatibility. There, “switch if it helps, stay if it doesn’t” is a perfectly sane answer.&lt;/p&gt;

&lt;p&gt;The deeper reason to learn Podman is not the logo. It is that Podman makes the &lt;em&gt;shape&lt;/em&gt; of a container obvious again: a child process, in a user namespace, supervised by init. Once you have built one by hand and then watched Podman do the same thing cleanly, containers stop being magic — and that understanding outlasts whichever CLI you happen to type.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://www.alekseialeinikov.com/en/blog/topics/devops/podman-2026-rootless-daemonless-containers-without-docker" rel="noopener noreferrer"&gt;alekseialeinikov.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>podman</category>
      <category>rootlesscontainers</category>
      <category>daemonless</category>
      <category>quadlet</category>
    </item>
  </channel>
</rss>
