19. August 2026
20 mins

AWS-Kosten senken: von 15.000 auf 2.500 Euro im Monat

Von Tim Rutte, Cloud & AI Architect

Kostenübersicht eines AWS-Accounts auf einem Laptop, daneben eine handschriftliche Liste umgesetzter FinOps-Maßnahmen

Vor zwölf Monaten habe ich die Verantwortung für zwei AWS-Accounts übernommen, Produktion und Staging, die zusammen jeden Monat rund 15.000 Euro kosteten. Heute kosten dieselben Accounts rund 2.500 Euro. Es laufen dieselben Anwendungen, für dieselben Nutzer, ohne Abstriche an der Produktionsverfügbarkeit. Nichts wurde abgeschaltet, was jemand vermisst hätte.

Alle Beträge in diesem Artikel sind gerundete Nettobeträge ohne Umsatzsteuer, aus den in US-Dollar abgerechneten Rechnungsbeträgen zum jeweiligen Monatskurs umgerechnet; Commitments sind amortisiert gerechnet. Was das heißt und warum es wichtig ist, erkläre ich weiter unten.

Dieser Artikel beschreibt, wie die 12.500 Euro Differenz zustande kamen. Nicht als Erfolgsgeschichte, sondern als Anleitung: welche Reihenfolge funktioniert, welche Werkzeuge man wirklich braucht, wo die großen Beträge lagen und wo ich Zeit verschwendet habe. Er richtet sich an Entwickler und Verantwortliche, die eine AWS-Rechnung vor sich haben, bei der niemand mehr sagen kann, warum sie so hoch ist.

Zwei Dinge vorweg. Erstens: Es gab keinen einzelnen großen Fehler. Kein vergessenes Kubernetes-Cluster, kein Krypto-Miner, keine Datenbank in dreifacher Ausführung. Die Rechnung war aus denselben Gründen hoch, aus denen die meisten AWS-Rechnungen hoch sind: vier Jahre Wachstum, in denen es immer Wichtigeres gab, als auf die Kosten zu schauen.

Zweitens, und das macht diesen Fall vielleicht interessanter als die üblichen Berichte: Es gab kaum klassische EC2-Flotte. Die Rechnung bestand fast vollständig aus Managed Services, also RDS, DynamoDB, ECS auf Fargate, S3, CloudWatch und Athena. Wer glaubt, mit Serverless und Managed Services erledige sich das Kostenthema von selbst, findet hier das Gegenbeispiel. Es verschiebt sich nur, wo das Geld versickert: nicht mehr in überdimensionierten Instanzen, sondern in Datenmengen, Abfragemustern und Beobachtbarkeit.

So sah der Verlauf über die zwölf Monate aus:

Balkendiagramm der monatlichen AWS-Kosten beider Accounts von August 2025 bis Juli 2026: ein treppenförmiger Rückgang von 14.700 auf 2.500 Euro netto
Monatliche Nettokosten beider Accounts, amortisiert. Die beiden großen Stufen: die Bereinigung von CloudWatch und Athena zum Jahreswechsel, danach Rightsizing, Commitments und die Speicher-Bereinigung im Frühjahr.

Die Ausgangslage: Niemand hatte etwas falsch gemacht

Das System war über Jahre gewachsen. Verschiedene Entwickler, verschiedene Prioritäten, verschiedene Jahre mit verschiedenen AWS-Moden. Jede einzelne Entscheidung war zu ihrem Zeitpunkt vertretbar gewesen: Die Task-Größen waren großzügig bemessen, weil ein Ausfall teurer gewesen wäre als der Aufschlag. Metriken wurden mit jeder Dimension aufgezeichnet, die irgendwann einmal jemand für nützlich gehalten hatte. Daten wurden aufbewahrt, weil nie jemand entschieden hatte, wie lange man sie braucht.

Das ist der Normalfall. AWS-Rechnungen explodieren selten. Sie sedimentieren.

Ich halte diesen Punkt für wichtig, weil er die Herangehensweise bestimmt. Wer nach dem einen Schuldigen sucht, dem einen Kollegen, der einen Fehlentscheidung, sucht am Problem vorbei. Es gibt ihn nicht. Es gibt nur hunderte kleine Entscheidungen, die einzeln vernünftig waren und in Summe 15.000 Euro pro Monat kosten. Das hat auch eine angenehme Konsequenz: Kostenarbeit muss niemanden bloßstellen. Sie räumt auf, was sich naturgemäß ansammelt.

Entsprechend war auch die Erwartungshaltung im Team: Man ging davon aus, dass vielleicht zehn, fünfzehn Prozent drin wären. Ein bisschen Aufräumen, ein paar Reservierungen, fertig. Dass am Ende über 80 Prozent wegfallen würden, hätte zu Beginn niemand unterschrieben, ich auch nicht.

Woche eins: Messen, bevor man irgendetwas anfasst

Der erste Reflex bei hohen AWS-Kosten ist, in den Cost Explorer zu schauen und die größten Posten anzugehen. Der Cost Explorer ist gut für einen Überblick, aber er hat eine entscheidende Schwäche: Er aggregiert. „CloudWatch: 2.600 Euro" ist keine Information, mit der man arbeiten kann. Dahinter verbergen sich Metriken, Logs, Dashboards und Alarme, alles Dinge mit völlig unterschiedlichen Ursachen und Lösungen.

Das Werkzeug, das man wirklich braucht, ist AWS Data Exports mit dem Cost and Usage Report 2.0: die vollständige Rohdatenabrechnung, jede einzelne Verbrauchszeile, exportiert nach S3 und abfragbar mit Athena. Beim Anlegen des Exports die Ressourcen-IDs einschließen. Das ist der Punkt, den viele vergessen, und er liefert später die Spalte line_item_resource_id, die den Unterschied macht. Die Einrichtung kostet eine Stunde, und ab dann beantwortet man Kostenfragen mit SQL statt mit Vermutungen.

Eine Randnotiz mit Ironie: Athena taucht in diesem Bericht später als einer der größten Kostenposten wieder auf. Das ist kein Widerspruch. Die teuren Athena-Kosten entstanden im Anwendungsbetrieb, der Monat für Monat Terabytes scannte. Die Kostenanalyse-Abfragen hier kosten Cent-Beträge. Der Unterschied liegt nicht im Werkzeug, sondern in der Datenmenge pro Abfrage, ein Thema, das uns noch beschäftigen wird.

Die erste Abfrage, die ich auf jedem Account laufen lasse, gruppiert nicht nach Service, sondern nach Verbrauchsart:

SELECT
  line_item_product_code,
  line_item_usage_type,
  ROUND(SUM(line_item_unblended_cost), 2) AS kosten
FROM cur
WHERE line_item_usage_start_date >= DATE '2025-08-01'
  AND line_item_usage_start_date <  DATE '2025-09-01'
GROUP BY 1, 2
ORDER BY kosten DESC
LIMIT 50;

Das Ergebnis dieser Abfrage hat die Arbeit der folgenden Monate bestimmt. Die Überraschung war nicht, dass die Datenbanken Geld kosten, das tun sie immer. Die Überraschung war, dass Beobachtbarkeit und Analyse mit den Datenbanken gleichgezogen hatten: CloudWatch und Athena standen zusammen für mehr Geld als RDS. Zwei Posten, die in keinem Architekturdiagramm als Kostenstelle auftauchen, weil sie nebenbei mitlaufen.

Wenn eine Verbrauchsart auffällt, kommt die zweite Abfrage: dieselbe Position, aufgelöst nach Ressource. Dafür braucht man die Ressourcen-IDs im Export, deshalb der Hinweis oben.

SELECT
  line_item_resource_id,
  ROUND(SUM(line_item_unblended_cost), 2) AS kosten
FROM cur
WHERE line_item_product_code = 'AmazonCloudWatch'
  AND line_item_usage_start_date >= DATE '2025-08-01'
GROUP BY 1
ORDER BY kosten DESC
LIMIT 50;

Mit diesen beiden Abfragen, erst Verbrauchsart, dann Ressource, lässt sich fast jede Kostenfrage in Minuten beantworten. Aus der Analyse entstand eine Liste mit gut dreißig Positionen, jede mit drei Angaben: geschätzte Ersparnis pro Monat, Aufwand in Tagen, Risiko für den Betrieb. Diese Liste ist das eigentliche Arbeitsdokument. Alles Weitere ist Abarbeiten in der richtigen Reihenfolge.

Drei Messfallen, die Wochen kosten können

Bevor es an die Maßnahmen geht, drei Dinge über die Zahlen selbst. Jede davon hat mich in früheren Projekten Zeit gekostet, bis ich sie verstanden hatte.

Unblended, Blended, Amortized: Es gibt nicht „die" Kosten. Der CUR liefert mehrere Kostenspalten, und sie beantworten verschiedene Fragen. Unblended Costs zeigen die nicht amortisierten Nutzungskosten, gut für die Frage, was in einem Monat berechnet wurde. Sobald Reserved Instances oder Savings Plans ins Spiel kommen, nutze ich für Vergleiche zusätzlich die amortisierte Sicht, damit Vorauszahlungen und wiederkehrende Reservierungsgebühren über ihre Laufzeit verteilt werden. Dieses Projekt liefert dafür später selbst das beste Beispiel: Nach dem Kauf der Datenbank-Reservierungen fiel die RDS-Zeile in der Unblended-Ansicht auf einen Bruchteil. Wer daraus abliest, die Datenbanken seien jetzt fast gratis, misst falsch. Erst die amortisierte Sicht zeigt die echten laufenden Kosten. Und wer Maßnahmen bewerten will, muss außerdem Einmaleffekte herausrechnen: Ein Datenexport für eine Migration ist kein Trend, sondern ein Ereignis.

Credits, Rabatte und Steuern verzerren den Blick. Startup-Credits, Vertragsrabatte oder Gutschriften aus Support-Fällen tauchen als negative Posten auf, die Umsatzsteuer als eigene Zeile obendrauf. Wer den Erfolg einer Maßnahme an der Rechnungssumme abliest, während im selben Monat Credits ausliefen, misst Rauschen. Dasselbe gilt für den Wechselkurs: AWS rechnet in US-Dollar ab, und ein Euro-Vergleich zweier Monate bewegt sich auch dann, wenn am Verbrauch nichts anders war. Deshalb: Verbrauch messen, also Stunden, Gigabyte, gescannte Terabytes und Requests, nicht nur Euro. Der Verbrauch lügt nicht. Und alle Zahlen in diesem Artikel sind Nettobeträge, denn die Steuer optimiert man nicht weg.

Der Monatsvergleich braucht Kontext. Ein Februar ist zehn Prozent kürzer als ein Januar. Ein Monat mit Marketingkampagne ist kein Vergleichsmaßstab für einen ohne. Ich vergleiche deshalb Wochenmittel gegen Wochenmittel und immer zusammen mit einer fachlichen Bezugsgröße, dazu später mehr.

Das klingt pedantisch, entscheidet aber darüber, ob das Projekt Vertrauen aufbaut oder verliert. Die erste Zahl, die sich als falsch herausstellt, kostet mehr Glaubwürdigkeit, als drei richtige wieder aufbauen.

Die richtige Reihenfolge, und warum Commitments am Ende stehen

Die Reihenfolge ist der Punkt, an dem die meisten Kostenprojekte schiefgehen. Sie lautet:

  1. Löschen und Aufbewahrung begrenzen, was niemand braucht
  2. Beobachtbarkeit prüfen: Logs, Metriken, Trails, die Nebenkosten des Betriebs
  3. Daten in den Griff bekommen: Speicherklassen, Datenmengen, Abfragemuster
  4. Verkleinern, was überdimensioniert ist
  5. Architektur ändern, wo sie Geld verbrennt
  6. Erst ganz am Ende: Commitments, also Reservierungen und Savings Plans

Der häufigste Fehler ist, mit Punkt 6 anzufangen, weil er der bequemste ist: keine Codeänderung, kein Risiko, ein paar Klicks, ein ordentlicher Rabatt. Aber ein Commitment ist ein Versprechen an AWS, eine bestimmte Menge Kapazität ein bis drei Jahre lang zu bezahlen, ob man sie nutzt oder nicht. Wer sich auf eine aufgeblähte Infrastruktur committet, zementiert die Verschwendung und macht jede spätere Optimierung wirtschaftlich sinnlos: Die verkleinerte Datenbank spart dann nichts mehr, weil die alte Größe längst bezahlt ist.

In diesem Projekt hätte ein Commitment auf den Ausgangszustand die damalige Datenbank- und Rechenlast für ein bis drei Jahre festgeschrieben, ein Vielfaches dessen, was nach der Bereinigung tatsächlich gebraucht wurde. Anders gesagt: Der bequemste erste Schritt hätte das Projekt beendet, bevor es angefangen hätte.

Es gibt noch einen zweiten Grund für diese Reihenfolge, und der ist psychologisch. Die frühen Phasen bestehen aus Maßnahmen mit sofort sichtbarem Ergebnis und praktisch keinem Risiko. Genau damit verdient man sich das Vertrauen, das man später für die Phasen braucht, in denen an laufenden Systemen gearbeitet wird. Wer mit dem riskantesten Umbau beginnt und dabei stolpert, bekommt für den Rest keine Rückendeckung mehr.

Phase 1: Löschen und Aufbewahrung. Der unglamouröse Teil

Die ersten Wochen bestanden fast nur aus Aufräumen, und wenig in den zwölf Monaten hatte ein besseres Verhältnis von Aufwand zu Ersparnis.

Was sich angesammelt hatte:

  • CloudWatch-Log-Gruppen ohne Retention. Log-Gruppen, die seit Jahren jedes Byte behalten. Eine Retention-Policy von 30 bis 90 Tagen ist eine Zeile Terraform.
  • Snapshots und Backups jenseits jeder Wiederherstellungsanforderung. Sicherungsautomatik, die fleißig anlegt, aber nie aufräumt.
  • Datenreste abgeschlossener Projekte. Exporte, Importrohdaten, Zwischenstände: Daten, deren einziger Job seit Jahren das Kostenverursachen war.

Der Befehl, der auf fast jedem gewachsenen Account sofort Geld findet:

# Log-Gruppen ohne Aufbewahrungsregel
aws logs describe-log-groups \
  --query 'logGroups[?!retentionInDays].[logGroupName,storedBytes]' \
  --output table

Die wichtigste Regel in dieser Phase ist nicht technisch, sondern organisatorisch: Nichts sofort endgültig löschen. Erst stoppen, archivieren oder per Snapshot sichern, dann zwei Wochen warten, ob jemand schreit, dann löschen. In zwölf Monaten hat genau einmal jemand geschrien, und das Wiederherstellen dauerte zwanzig Minuten. Diese Regel ist der Grund, warum man Aufräumen ohne Angst betreiben kann.

Sie ist auch die Antwort auf den Einwand, der in dieser Phase garantiert kommt: „Woher weißt du, dass das keiner braucht?" Ich weiß es nicht. Ich muss es auch nicht wissen. Ich muss nur einen Weg haben, der einen Irrtum in zwanzig Minuten korrigiert statt in einem Krisenmeeting. Stoppen ist umkehrbar. Zu diskutieren, ob etwas theoretisch noch gebraucht werden könnte, ist es nicht: Das kostet nur Wochen, in denen die Ressource weiter Geld verbrennt.

Ergebnis der Phase: rund 1.200 Euro pro Monat, bei praktisch null Risiko.

Phase 2: Beobachtbarkeit, als das Messen teurer wurde als das Gemessene

Der aufschlussreichste Einzelfund des Projekts steckte in CloudWatch, und er dürfte jedem bekannt vorkommen, der Custom Metrics mit Dimensionen betreibt: Jede einzigartige Kombination aus Metrikname und Dimensionswerten ist für AWS eine eigene Metrik, und wird einzeln bezahlt.

Das klingt harmlos, bis man hochkardinale Werte in Dimensionen packt. Eine Metrik „Verarbeitungsdauer" ist eine Metrik. Dieselbe Metrik mit einer Dimension „Kunde" ist so viele Metriken, wie es Kunden gibt. Kommt eine zweite Dimension dazu, Container-ID, Job-Typ, Version, multipliziert sich das. Aus einer Handvoll gut gemeinter Messpunkte werden Zehntausende bezahlter Metriken, und niemand hat je eine Entscheidung getroffen, die sich falsch angefühlt hätte. Jede einzelne Dimension war zum Zeitpunkt ihrer Einführung eine gute Idee.

Hier war CloudWatch zeitweise der zweitgrößte Posten der gesamten Rechnung, mit einem Höchststand im Dezember, teurer als die Datenbanken, deren Verhalten es überwachen sollte. Beobachtbarkeit, die mehr kostet als das Beobachtete, ist keine Beobachtbarkeit mehr. Sie ist ein Leck.

Das Vorgehen:

  1. Metriken zählen, nicht schätzen. Eine Auswertung, welche Custom-Namespaces wie viele Metriken enthalten, und welche davon in den letzten 90 Tagen von irgendeinem Alarm oder Dashboard gelesen wurden. Das Ergebnis ist fast immer dasselbe: Der Großteil wird geschrieben und nie gelesen.
  2. Hochkardinale Werte raus aus den Dimensionen. IDs gehören in strukturierte Logs, wo man sie bei Bedarf mit Logs Insights abfragt, nicht in Metrik-Dimensionen, wo jede Ausprägung dauerhaft Geld kostet. Die Faustregel: Dimensionen beantworten „wie geht es dem System", Logs beantworten „was war mit Kunde X".
  3. Aggregieren, was zusammengehört. Wo vorher pro Einzelinstanz gemessen wurde, reicht fast immer die Summe oder das Perzentil über die Gruppe.

Wichtig ist die Prüfreihenfolge: erst herausfinden, welche Metriken in Alarmen und Dashboards referenziert werden, dann streichen. Eine gelöschte Metrik, an der ein Produktionsalarm hing, ist der Ausfall, den sich dieses Projekt nicht leisten kann.

Ergebnis der Phase: rund 1.800 Euro pro Monat.

Phase 3: Daten. Speichern, Abfragen, Wegwerfen

Der größte zusammenhängende Block des Projekts. Er bestand aus zwei Geschichten, die dieselbe Wurzel haben: zu viele Daten, zu lange aufbewahrt, zu breit abgefragt.

Athena: Der Preis des Vollscans. Athena rechnet pro gescanntem Terabyte ab. Das ist ein faires Modell, solange die Abfragen nur lesen, was sie brauchen. Die Daten hier waren unpartitioniert: Jede Abfrage, egal wie klein ihre Frage, scannte den gesamten Bestand. Und der Bestand wuchs jeden Tag. Das Ergebnis war ein Posten von rund 2.500 Euro im Monat, für Abfragen, deren Antworten in einem Bruchteil der Daten steckten.

Die Lösung hatte zwei Teile. Erstens Partitionierung, in diesem Fall nach Datum: Eine Abfrage über die letzte Woche liest dann nur die letzte Woche, nicht vier Jahre. Zweitens, und das war der unbequemere Teil, die Frage, warum der Bestand überhaupt so groß war. Die Antwort: kein Grund. Ein erheblicher Teil der Daten wurde für keine einzige Auswertung mehr gebraucht und konnte gelöscht werden. Weniger Daten heißt weniger Scan, weniger Speicher, weniger von allem. Wer zusätzlich auf ein Spaltenformat wie Parquet umstellt, verstärkt den Effekt noch einmal deutlich. Die Reihenfolge ist aber: erst wegwerfen, dann partitionieren, dann Formatfragen.

S3: Aufbewahrung ist eine Entscheidung, keine Voreinstellung. Die zweite Geschichte betraf vor allem die Staging-Umgebung. Sie war nie überflüssig, sie wird für jeden Test gebraucht. Aber ihre Daten wurden behandelt wie Produktionsdaten: aufbewahrt, als hinge etwas davon ab. Tut es nicht. Testdaten sind Verbrauchsmaterial. Heute gelten dort aggressive Lifecycle-Regeln, und Daten werden nach kurzer Zeit gelöscht. Der Effekt wurde erst im Frühsommer voll sichtbar, weil vorher die Aufbewahrungsfragen zu klären waren: Was braucht die Fachlichkeit wirklich, was verlangt eine Aufbewahrungspflicht, und was ist nur Gewohnheit. Diese Klärung dauert länger als die Terraform-Zeile danach, und sie ist der eigentliche Kern der Maßnahme.

Dazu kamen die üblichen Handgriffe: S3 Storage Lens und Access-Logging für zwei Wochen, um Lesemuster zu sehen, bevor Regeln geschrieben werden. Lifecycle-Regeln für alles mit klarem Muster. Abgebrochene Multipart-Uploads nach sieben Tagen löschen, ein unsichtbarer Posten, den fast jeder hat: Die Fragmente tauchen in keiner Bucket-Ansicht auf, kosten aber Speicher wie ganze Objekte. Intelligent-Tiering gezielt bei Daten mit unbekanntem oder wechselndem Zugriffsmuster, vorher Objektgrößen und Monitoring-Kosten gegenrechnen, denn Objekte unter 128 KB werden gar nicht überwacht und bleiben dauerhaft in der teuersten Speicherklasse. Und die RDS-Backup-Retention zurück auf ein Maß, das einer tatsächlichen Wiederherstellungsanforderung entspricht.

Ergebnis der Phase: rund 4.000 Euro pro Monat, der größte Einzelblock des Projekts. Und die Einsparung ist dauerhaft, denn sie beruht nicht auf einem Rabatt, sondern darauf, dass Arbeit wegfällt, die nie jemand gebraucht hat.

Phase 4: Rechenleistung, gegen die Angst dimensioniert

Jetzt erst die Rechenkapazität. Nicht früher, denn nach den Phasen 1 bis 3 war klar, welche Last überhaupt übrig bleibt. Rightsizing auf Workloads anzuwenden, deren Ursache gerade wegoptimiert wird, ist verschwendete Sorgfalt.

Das Muster bei den ECS-Services war dasselbe, das ich von EC2-Flotten kenne: dimensioniert gegen die Angst, nicht gegen die Last. Task-Größen, deren CPU- und Speicher-Reservierungen im Wochenmittel zu einem Bruchteil ausgelastet waren. Kapazität für einen Lastfall, der zweimal im Jahr eintritt, rund um die Uhr vorgehalten.

Ich verstehe diese Angst. Wer einen Task zu klein dimensioniert und damit einen Ausfall verursacht, hat ein Gespräch vor sich. Wer ihn doppelt so groß macht wie nötig, hat keins, die Kosten fallen ja niemandem auf. Die Anreize zeigen alle in Richtung Überdimensionierung. Genau deshalb funktioniert Rightsizing nur mit Daten, die diese Angst ersetzen.

Konkret:

  • Task-Größen anhand von 14-Tage-Metriken, nicht anhand von Bauchgefühl. Container Insights liefert die tatsächliche Auslastung pro Service, daraus die passende Reservierung abgeleitet, meist eine bis zwei Stufen kleiner. Wichtig ist die Schrittfolge: erst eine Stufe runter, eine Woche beobachten, dann die nächste. Wer in einem Schritt auf ein Viertel springt, erzeugt den Ausfall, der das ganze Projekt diskreditiert.
  • Lambda-Speicher gemessen statt geraten. Die Speichereinstellung bestimmt bei Lambda auch die CPU, abgerechnet wird in GB-Sekunden. Das bedeutet: Mehr Speicher lohnt sich genau dann, wenn die Laufzeit überproportional zur Speichererhöhung fällt. Mehrere Funktionen hier wurden mit mehr Speicher so viel schneller, dass die Gesamtkosten trotz höherer Zuweisung sanken, bei anderen war die alte Einstellung bereits das Optimum. Mit Lambda Power Tuning gibt es ein fertiges Open-Source-Werkzeug, das genau diese Kurve pro Funktion ausmisst. Eine halbe Stunde pro Funktion, statt zu schätzen.
  • Fargate Spot für alles, was unterbrechbar ist. Batch-Verarbeitung und ähnliche Jobs vertragen einen Abbruch mit zwei Minuten Vorwarnung, wenn sie Checkpoints setzen und wieder aufsetzen können, dafür gibt es einen erheblichen Rabatt. Wo das nicht gegeben war, blieb reguläre Kapazität. Spot für Systeme zu erzwingen, die Unterbrechungen nicht vertragen, ist keine Kostenoptimierung, sondern ein verschobener Ausfall.

Ergebnis der Phase: rund 2.000 Euro pro Monat. Zeitlich ein aufwendiger Teil, weil jede Änderung beobachtet werden will.

Phase 5: Architektur, wo die Rechnung ein Symptom ist

Ab einem gewissen Punkt sind hohe Kosten kein Konfigurationsproblem mehr, sondern ein Architekturproblem. Drei Beispiele aus diesem Projekt:

Die Staging-Umgebung lief rund um die Uhr. Genutzt an Werktagen zwischen 9 und 18 Uhr, das sind 45 von 168 Wochenstunden, 73 Prozent der Laufzeit waren unbenutzt. Ein Scheduler, der die Umgebung abends herunterfährt und morgens hochfährt, ist ein Nachmittag Arbeit: ECS-Services auf null skalieren, RDS-Instanzen stoppen, morgens in umgekehrter Reihenfolge wieder hoch, gesteuert über den EventBridge Scheduler. In diesem Setup dauerte der morgendliche Start typischerweise rund zehn Minuten, der Scheduler läuft deshalb vor Arbeitsbeginn. Die anfänglichen Einwände gegen das Abschalten verschwanden nach der ersten Woche. Niemand hat je wieder danach gefragt.

Dieselbe teure Abfrage lief hundertfach pro Minute. Ein Teil der Datenbanklast bestand aus identischen Leseabfragen, deren Ergebnis sich selten änderte. Ein Cache davor nahm der Datenbank genau diese Last ab. Caching ist in dieser Hinsicht keine Performance-, sondern eine Kostenmaßnahme: Die günstigste Abfrage ist die, die gar nicht erst bei der Datenbank ankommt.

Polling wurde durch Ereignisse ersetzt. Prozesse, die im Minutentakt nachfragten, ob es etwas zu tun gibt, erzeugten Grundlast rund um die Uhr. Event-getriebene Auslösung über EventBridge und SQS bedeutet: Rechenleistung nur, wenn tatsächlich etwas passiert. Bei Lasten, die in Wellen kommen, ist das der Unterschied zwischen Dauerbetrieb und echter verbrauchsbasierter Abrechnung.

Was diese Fälle gemeinsam haben: Keiner davon wäre in einem Kostentool als Fund aufgetaucht. Ein Tool sieht eine ausgelastete Datenbank und empfiehlt eine Reservierung dafür. Dass die Last selbst überflüssig ist, sieht nur jemand, der das System versteht. Das ist der Punkt, an dem Kostenarbeit von Konfigurationspflege zu Engineering wird, und der Grund, warum sie sich nicht vollständig automatisieren lässt. Warum solche Posten so selten dort stehen, wo man sie sucht, habe ich in Schlechte Architektur schickt keine Alerts ausführlicher beschrieben.

Ergebnis der Phase: rund 800 Euro pro Monat, der kleinste Posten der Liste, aber der mit dem größten betrieblichen Nebeneffekt: ein System mit weniger Grundrauschen.

Was dieses Projekt nicht hatte, und trotzdem auf Ihre Prüfliste gehört

Diese beiden Accounts hatten kaum klassisches EC2. Die meisten gewachsenen Accounts, die ich sehe, haben es, und dort liegen die Klassiker, die hier fehlten. Der Vollständigkeit halber, weil dieser Artikel eine Anleitung sein soll und keine reine Fallgeschichte:

  • Verwaiste EBS-Volumes und Snapshots. Beim Beenden von Instanzen bleiben Volumes erhalten, wenn DeleteOnTermination nicht gesetzt war. Sie kosten weiter, jahrelang.
# EBS-Volumes, die an keiner Instanz hängen
aws ec2 describe-volumes \
  --filters Name=status,Values=available \
  --query 'Volumes[].[VolumeId,Size,CreateTime]' --output table
  • gp2 auf gp3 migrieren. Rund 20 Prozent günstiger, IOPS von der Größe entkoppelt, Migration ohne Unterbrechung per API-Aufruf. Für die meisten Standard-Workloads gibt es 2026 keinen Grund mehr, gp2 zu betreiben.
  • EC2-Rightsizing und Graviton. Dieselbe Logik wie oben bei den Task-Größen: 14-Tage-Metriken statt Bauchgefühl, Speicher braucht den CloudWatch-Agent, stufenweise verkleinern. ARM-Instanzen bringen bei Managed Services rund 20 Prozent bei minimalem Aufwand, bei eigenen Workloads dort, wo Container ohnehin multi-arch gebaut werden.
  • NAT-Gateway-Verkehr zu S3 und DynamoDB. Der Standardpfad schickt Verkehr aus privaten Subnetzen für Geld durch das NAT Gateway, auch zu AWS-Diensten in derselben Region. Ein Gateway-Endpunkt leitet ihn AWS-intern und kostet nichts. Ich habe noch keinen gewachsenen EC2-Account gesehen, auf dem NatGateway-Bytes kein Fund war:
resource "aws_vpc_endpoint" "s3" {
  vpc_id            = aws_vpc.main.id
  service_name      = "com.amazonaws.eu-central-1.s3"
  vpc_endpoint_type = "Gateway"
  route_table_ids   = aws_route_table.private[*].id
}
  • Datenverkehr zwischen Availability Zones kostet in beide Richtungen. AZ-bewusstes Routing hilft, ist aber ein Zielkonflikt mit der Ausfallsicherheit: Was mehrzonig sein muss, bleibt mehrzonig.
  • Interface-Endpunkte ohne Nutzung kosten eine Stundenrate je Availability Zone. Die Rechnung gehört pro Endpunkt aufgemacht.
  • Internet-Egress ohne Auslieferungsnetz: die teuersten Bytes im ganzen Katalog.

Nichts davon war hier ein großer Posten. Auf Ihrem Account kann jeder einzelne davon fünfstellig pro Jahr sein.

Phase 6: Jetzt erst Commitments, auf die bereinigte Grundlast

Nach etwa einem halben Jahr war die Rechenlast bereinigt und stabil: Athena partitioniert, CloudWatch entschlackt, ECS auf realistische Größen gebracht. Erst jetzt kamen Commitments, bewusst nur auf die Last, die mit Sicherheit bleibt. Nicht auf die Spitzen, nicht auf alles, was noch im Umbau war. Die Speicher-Bereinigung lief danach sogar noch weiter; die Rechnung fiel also auch nach den Commitments weiter, was genau die richtige Reihenfolge belegt.

Kurz zur Begrifflichkeit, weil sie oft durcheinandergeht: Savings Plans gibt es nur für Rechenleistung, also EC2, Fargate und Lambda. Für RDS heißen Commitments Reserved Instances, bei DynamoDB Reserved Capacity. Die Mechanik ist überall dieselbe: Preisnachlass gegen Bindung. Hier wurden alle drei eingesetzt, Reserved Instances für die Datenbanken, Reserved Capacity für DynamoDB, ein Compute Savings Plan für die Fargate-Last, jeweils mit einem Jahr Laufzeit. Drei Jahre sind in dieser Branche eine Ewigkeit; der zusätzliche Rabatt der langen Laufzeit ist eine Wette darauf, dass sich an der Architektur nichts Wesentliches mehr ändert. Nach einem halben Jahr Umbau wollte ich diese Wette nicht eingehen.

Meine Faustregel: Ich binde höchstens 70 bis 80 Prozent der nachgewiesenen Grundlast, nie 100 Prozent. Der Rest bleibt flexibel. Ein zu großes Commitment ist die einzige Kostenoptimierung, die sich nicht rückgängig machen lässt.

Ergebnis: rund 2.700 Euro pro Monat auf die verbleibende Last.

Governance: Damit es nicht zurückwächst

Der unbequemste Befund aus zwölf Monaten Kostenarbeit: Ohne Gegenmaßnahmen wächst alles wieder nach. Dieselben Kräfte, die die Rechnung auf 15.000 Euro gebracht haben, wirken weiter. Jeder neue Service bringt neue Metriken mit, jede neue Pipeline neue Daten, jeder neue Entwickler dimensioniert wieder gegen die Angst. Deshalb war der letzte Monat kein Optimierungs-, sondern ein Einrichtungsmonat:

  • Tagging mit Durchsetzung. Vier Pflicht-Tags, also Team, Umgebung, Anwendung und Kostenstelle, erzwungen über Tag Policies und Prüfungen in der IaC-Pipeline. Ein Tag, der freiwillig ist, fehlt nach einem halben Jahr auf einem Drittel der Ressourcen, und dann ist jede Auswertung wertlos. Durchsetzung heißt: Ein Deployment ohne Pflicht-Tags schlägt fehl. In meinen bisherigen Projekten hat freiwilliges Tagging langfristig nicht zuverlässig funktioniert.
  • Budgets mit Alarmen je Account und Umgebung, nicht nur fürs Gesamtkonto. Interessant ist nicht der absolute Betrag, sondern die Abweichung vom erwarteten Verlauf. Ein Budget, das erst am Monatsende Alarm schlägt, ist ein Nachruf.
  • Anomaly Detection für die Fälle, an die kein Budget denkt. Der Dienst ist kostenlos und meldet Ausreißer je Service. Er ersetzt keine Analyse, aber er verkürzt die Zeit zwischen „etwas ist teuer geworden" und „jemand weiß es". Der CloudWatch-Posten aus Phase 2 wäre damit Monate früher aufgefallen.
  • Aufbewahrung als Standard, nicht als Ausnahme. Jede neue Log-Gruppe, jeder neue Bucket bekommt im IaC-Modul eine Retention beziehungsweise Lifecycle-Regel als Pflichtparameter. Wer unbegrenzt aufbewahren will, muss es explizit hinschreiben und begründen können.
  • Kosten im Entwicklungsalltag. Die wirksamste Einzelmaßnahme des ganzen Governance-Pakets: eine Kostenzahl pro Woche im Team-Channel, aufgeschlüsselt nach Anwendung. Nicht als Kontrolle, sondern als Sichtbarkeit. Entwickler treffen kostenbewusste Entscheidungen, sobald sie die Zahlen überhaupt sehen, vorher haben sie schlicht keine Chance dazu.
  • Kosten pro fachlicher Einheit statt Gesamtsumme: Kosten pro tausend Requests, pro Kunde, pro Import. Eine steigende Gesamtrechnung bei stärker steigender Nutzung ist Erfolg, keine Krise. Ohne Bezugsgröße kann man das nicht unterscheiden, und genau diese Unterscheidung überführt Kostendiskussionen von Panik in Steuerung.

Was Zeit verschwendet hat

Der Vollständigkeit halber auch die Sackgassen. Die Liste ist kürzer als die Erfolgsliste, aber sie existiert.

Die Jagd nach Kleinbeträgen. Irgendwann in Monat drei habe ich einen halben Tag damit verbracht, einen 40-Euro-Posten zu verstehen. Der Betrag war seitdem jeden Monat 40 Euro wert, die Analyse war es nicht. Seitdem gilt eine harte Schwelle: Was unter einem definierten Monatsbetrag liegt, wird nicht untersucht, solange darüber noch etwas offen ist. Die Pareto-Verteilung auf AWS-Rechnungen ist brutal, die zehn größten Verbrauchsarten erklärten hier über 80 Prozent der Summe.

Werkzeuge evaluieren statt Abfragen schreiben. Es gibt einen ganzen Markt an Kostenoptimierungs-Tools, und ich habe zwei davon ernsthaft angesehen. Beide hätten gefunden, was die erste Athena-Woche auch fand, zu einem Preis von mehreren Prozent der Ersparnis, dauerhaft. Für Konzerne mit hunderten Accounts mag die Rechnung anders ausgehen. Für zwei Accounts dieser Größe ist der CUR plus ein Nachmittag SQL das bessere Geschäft. Die unbequeme Wahrheit über diese Tools: Finden ist nicht das Problem. Ändern ist das Problem, und das nimmt einem kein Dashboard ab.

Zu frühe Diskussionen über Architekturumbauten. In Woche zwei gab es eine lange Debatte, ob ein Teil des Systems umgebaut werden sollte. Rückblickend war das Prokrastination auf hohem Niveau: Die Phasen 1 bis 3 erforderten keine einzige Architekturentscheidung und brachten den Großteil der Gesamtersparnis. Die Umbaudiskussion war Monate später deutlich kürzer, weil dann Daten vorlagen statt Meinungen.

Wie das neben dem Tagesgeschäft funktioniert

Zwölf Monate klingen lang. Tatsächlich war es kein Vollzeitprojekt, sondern ein Rhythmus: eine Maßnahme pro Woche, jede mit demselben Ablauf, also umsetzen, eine Woche beobachten, Ergebnis notieren, nächste. Der Rhythmus hatte zwei Effekte, die ich nicht erwartet hatte.

Erstens macht er das Projekt unterbrechbar. Es gab Wochen, in denen nichts passierte, weil Wichtigeres anlag. Das kostete nichts außer Zeit, keine halb fertigen Umbauten, kein Zustand, den man erst wieder verstehen muss. Kostenarbeit konkurriert immer mit Feature-Arbeit, und sie verliert diesen Konflikt zu Recht, wenn sie sich wie ein Großprojekt aufführt. Als Wochenrhythmus verliert sie ihn nicht, weil sie nie groß genug wird, um im Weg zu stehen.

Zweitens erzeugt er eine Erfolgsliste. Nach drei Monaten stand in einem Dokument: Maßnahme, erwartete Ersparnis, tatsächliche Ersparnis. Diese Liste hat mehr Diskussionen beendet als jedes Argument. Gegen „ich habe mit sieben Maßnahmen mehrere tausend Euro pro Monat eingespart, hier sind die nächsten fünf" argumentiert niemand mehr an.

Die Bilanz, und die ehrlichen Fußnoten

MaßnahmeErsparnis pro Monat (ca.)
Phase 1: Löschen, Aufbewahrung begrenzen1.200 €
Phase 2: Beobachtbarkeit, CloudWatch-Metriken1.800 €
Phase 3: Daten, Athena-Partitionierung, S3-Lifecycle4.000 €
Phase 4: Rightsizing, Lambda-Speicher, Fargate Spot2.000 €
Phase 5: Architektur, Scheduler, Caching, Events800 €
Phase 6: Commitments auf die bereinigte Grundlast2.700 €
Summe~12.500 €

Von rund 15.000 auf rund 2.500 Euro, also gut 83 Prozent. Die Verteilung ist die eigentliche Botschaft der Tabelle: Die drei Phasen ohne jede Architekturänderung, also Löschen, Beobachtbarkeit und Daten, machen mit 7.000 Euro mehr als die Hälfte aus. Der Teil, den man sich als Kostenoptimierung vorstellt, also Reservierungen und Rabatte, steht am Ende und ist nicht einmal der größte Posten.

Drei Fußnoten, die in Erfolgsgeschichten gern fehlen:

Erstens: Die 83 Prozent sind kein universeller Maßstab. Diese Accounts hatten vier Jahre Sediment angesetzt. Ein Account, auf den regelmäßig jemand schaut, gibt vielleicht 20 bis 30 Prozent her. Die Methode ist übertragbar, die Quote nicht.

Zweitens: Es hat zwölf Monate gedauert, weil es neben dem Tagesgeschäft lief und weil jede Änderung beobachtet wurde, bevor die nächste kam. Man kann das in drei Monaten Vollzeit erledigen, aber nicht in einem Sprint, und schon gar nicht per Knopfdruck mit einem Werkzeug.

Drittens: Der Leistungsumfang blieb gleich, aber das System ist nicht dasselbe geblieben. Es ist einfacher geworden. Das ist kein Zufall und kein Nebeneffekt: Die meisten Kostenoptimierungen sind verkleidete Vereinfachungen. Weniger ungenutzte Ressourcen, weniger Sonderfälle, weniger Dinge, die nachts kaputtgehen können. Die Rechnung ist ein erstaunlich guter Indikator für Architekturqualität, sie ist nur der einzige, der in Euro gemessen wird.

Womit Sie morgen anfangen können

Wenn Sie eine AWS-Rechnung haben, bei der niemand mehr weiß, warum sie so hoch ist:

  1. Cost and Usage Report aktivieren und mit Athena abfragbar machen, mit Ressourcen-IDs. Eine Stunde Aufwand, die Grundlage für alles Weitere.
  2. Die erste Abfrage von oben laufen lassen und die fünfzig größten Verbrauchsarten ansehen, nicht die größten Services.
  3. Verwaiste Ressourcen suchen: Log-Gruppen ohne Retention, Volumes ohne Instanz, Snapshots ohne Volume, abgebrochene Multipart-Uploads. Das ist der Teil mit Ergebnis am selben Tag.
  4. Die Kosten der Beobachtbarkeit aufmachen. Wenn CloudWatch in Ihren Top fünf steht, liegt dort mit hoher Wahrscheinlichkeit ein vierstelliger Jahresbetrag in Metriken, die niemand liest.
  5. NatGateway-Bytes prüfen. Steht dort ein nennenswerter Betrag und ist S3 oder DynamoDB im Spiel: Gateway-Endpunkt. Kostenlos, zwanzig Minuten.
  6. Keine Commitments abschließen, bevor die Punkte 1 bis 5 durch sind.

Und wenn Sie dabei auf die Frage stoßen, ob sich eine gründliche Analyse für Ihren Account lohnt: Bei allem oberhalb von ein paar tausend Euro im Monat lautet die Antwort nach meiner Erfahrung ja. Die Frage ist nur, ob die Ersparnis vierstellig oder fünfstellig pro Jahr ausfällt.

Dieselbe Analyse für Ihren Account

Die Bestandsaufnahme aus Woche eins gibt es als Festpreispaket: CUR-Analyse, priorisierte Maßnahmenliste mit Ersparnis, Aufwand und Risiko, dazu die Architekturfunde, die kein Werkzeug findet.

AWS-Kosten senken
Zur Leistung