AWS / Cloud FinOps · Cost Optimization

AWS Cost Optimization: 10 Maßnahmen, die sofort Geld sparen

AWS-Rechnungen wachsen schneller als erwartet – das kennt fast jedes Team. Hier sind 10 konkrete Hebel, die ohne großen Umbauaufwand greifen: von ungenutzten Ressourcen bis zu smarten Kaufmodellen.

E
Emre Hayta
· · 12 Min. Lesezeit
AWS FinOps Cost Optimization EC2 S3

Irgendwann kommt bei jedem AWS-Nutzer der Moment: Die monatliche Rechnung liegt wieder höher als erwartet, und man weiß nicht genau, wofür. Das ist kein Versagen – das ist die Default-Situation. AWS macht es einfach, Ressourcen zu starten. Schwieriger ist es, den Überblick zu behalten.

Dieser Artikel zeigt 10 Maßnahmen, die sich in der Praxis bewährt haben – sortiert nach Aufwand und Sofortwirkung. Kein theoretisches FinOps-Framework, sondern konkrete Schritte, die du diese Woche umsetzen kannst.

Warum AWS-Rechnungen schneller wachsen als geplant

AWS hat über 200 Services. Viele davon rechnen sekundengenau ab, andere nach Datenmenge, wieder andere nach Anzahl der Anfragen. Die Komplexität des Preismodells ist kein Fehler – sie ist ein Feature für große Enterprise-Kunden. Für kleinere Teams bedeutet sie: Wer nicht aktiv schaut, zahlt zu viel.

Die häufigsten Kostentreiber, die ich in Projekten sehe:

  • EC2-Instanzen, die rund um die Uhr laufen, obwohl sie nur tagsüber gebraucht werden
  • EBS-Volumes, die nach dem Löschen einer Instanz vergessen wurden
  • NAT Gateways mit unnötig hohem Datendurchsatz
  • S3-Buckets mit Millionen kleiner Objekte und keiner Lifecycle-Policy
  • RDS-Instanzen, die zu groß provisioniert sind und nie ausgelastet werden
  • Snapshots, die seit Monaten niemand mehr braucht

Das Gute: Viele dieser Probleme lassen sich innerhalb weniger Stunden beheben. Fangen wir an.

1. Kostentransparenz herstellen: AWS Cost Explorer aktivieren

Bevor man optimiert, muss man wissen, wo das Geld hingeht. AWS Cost Explorer ist kostenlos und zeigt Ausgaben aufgeschlüsselt nach Service, Region, Tag und Zeitraum. Aktivieren kostet nichts, nicht aktivieren kostet Überblick.

Zwei Dinge, die ich sofort einrichte:

Cost Allocation Tags

Tags sind der Schlüssel zur Kostentransparenz. Ohne Tags weiß man nicht, welches Projekt oder Team welche Kosten verursacht. Im AWS Cost Management unter Cost Allocation Tags aktivieren:

Bash
# Alle EC2-Instanzen mit Projekt-Tag versehen (AWS CLI)
aws ec2 create-tags \
  --resources i-1234567890abcdef0 \
  --tags Key=Project,Value=myapp Key=Environment,Value=production Key=Owner,Value=emre

# Terraform-Beispiel: Tags auf alle Ressourcen setzen
locals {
  common_tags = {
    Project     = var.project_name
    Environment = var.environment
    ManagedBy   = "terraform"
    Owner       = var.owner
  }
}

resource "aws_instance" "app" {
  ami           = data.aws_ami.amazon_linux.id
  instance_type = "t3.medium"
  tags          = local.common_tags
}

AWS Trusted Advisor

Mit einem Business- oder Enterprise-Support-Plan gibt Trusted Advisor konkrete Optimierungshinweise: ungenutzte EC2-Instanzen, idle Load Balancer, underutilized RDS. Für kleinere Konten liefert AWS Compute Optimizer ähnliche Empfehlungen kostenlos.

Sofortaktion: Cost Explorer aktivieren, die letzten 3 Monate analysieren, Top-5-Kostentreiber identifizieren. Das dauert 20 Minuten und zeigt, wo der größte Hebel liegt.

2. Ungenutzte Ressourcen eliminieren

Das ist die einfachste und schnellste Maßnahme – und gleichzeitig die, bei der die meisten Teams am meisten liegen lassen. Ungenutzte Ressourcen laufen still im Hintergrund und produzieren Kosten, ohne irgendeinen Wert zu liefern.

Checkliste für sofortige Bereinigung:

Gestoppte EC2-Instanzen & verwaiste EBS-Volumes

Bash
# Gestoppte Instanzen finden
aws ec2 describe-instances \
  --filters "Name=instance-state-name,Values=stopped" \
  --query "Reservations[*].Instances[*].[InstanceId,Tags[?Key=='Name'].Value|[0],LaunchTime]" \
  --output table

# Ungenutzte EBS-Volumes (available = nicht attached)
aws ec2 describe-volumes \
  --filters "Name=status,Values=available" \
  --query "Volumes[*].[VolumeId,Size,CreateTime,Tags[?Key=='Name'].Value|[0]]" \
  --output table

# Ungenutzte Elastic IPs (kosten Geld wenn nicht attached!)
aws ec2 describe-addresses \
  --query "Addresses[?AssociationId==null].[PublicIp,AllocationId]" \
  --output table

Alte Snapshots bereinigen

EBS-Snapshots kosten $0.05 pro GB und Monat. Klingt wenig – aber bei Hunderten von Snapshots über Jahre summiert sich das schnell auf dreistellige Monatsbeträge.

Bash
# Snapshots älter als 90 Tage im eigenen Account finden
aws ec2 describe-snapshots \
  --owner-ids self \
  --query "Snapshots[?StartTime<='2025-12-21'].[SnapshotId,VolumeSize,StartTime,Description]" \
  --output table

Für automatisches Snapshot-Management empfehle ich AWS Data Lifecycle Manager – damit lassen sich Retention-Policies direkt in AWS definieren, ohne Cron-Jobs oder Lambda-Funktionen.

Brauchst du Unterstützung bei der Umsetzung?

30-Min Call — kostenlos, unverbindlich, konkret.

Termin buchen →

3. EC2 Right-Sizing: Instanzgröße an den echten Bedarf anpassen

Über-provisionierte EC2-Instanzen sind einer der größten Kostentreiber. Eine m5.xlarge kostet doppelt so viel wie eine m5.large – wenn die Auslastung nie über 20% liegt, zahlt man doppelt für nichts.

AWS Compute Optimizer analysiert CloudWatch-Metriken der letzten 14 Tage und gibt konkrete Empfehlungen. Alternativ: manuell über CloudWatch schauen.

Bash
# Durchschnittliche CPU-Auslastung der letzten 14 Tage
aws cloudwatch get-metric-statistics \
  --namespace AWS/EC2 \
  --metric-name CPUUtilization \
  --dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
  --start-time 2026-03-07T00:00:00Z \
  --end-time 2026-03-21T00:00:00Z \
  --period 86400 \
  --statistics Average \
  --query "Datapoints[*].[Timestamp,Average]" \
  --output table

Faustregel: Wenn die durchschnittliche CPU-Auslastung unter 10% liegt und Spitzenwerte unter 40% bleiben, ist die Instanz überprovisioniert. Eine Größe kleiner (z.B. m5.large statt m5.xlarge) ist meist problemlos möglich.

Außerdem lohnt sich der Wechsel zur aktuellen Instanzgeneration: m5m7i oder m7g (Graviton) kann bei gleicher oder besserer Performance 20–30% günstiger sein.

Instanztyp vCPU RAM Preis/h (eu-central-1) Ersparnis
m5.large 2 8 GB ~$0.107 Basis
m7i.large 2 8 GB ~$0.109 +15% Performance
m7g.large 2 8 GB ~$0.090 −16% (Graviton)

4. Reserved Instances: Rabatt durch Commitment

Wer EC2-Instanzen dauerhaft betreibt, sollte über Reserved Instances (RIs) oder Savings Plans nachdenken. Der Deal ist simpel: Du verpflichtest dich für 1 oder 3 Jahre, AWS gibt dir dafür 30–72% Rabatt.

Die Entscheidung hängt von der Nutzungssicherheit ab:

  • Standard Reserved Instances (1 Jahr, no upfront): ~30–40% Ersparnis, kein Vorabkapital nötig
  • Standard Reserved Instances (1 Jahr, all upfront): ~40–50% Ersparnis, Vorabzahlung
  • Convertible RIs: Weniger Rabatt, aber flexibel in Instanztyp/Region wechselbar
Wann macht RI Sinn? Wenn eine Instanz seit >3 Monaten läuft und du sie mit hoher Wahrscheinlichkeit noch 12+ Monate brauchst. Nicht für Entwicklungsumgebungen, die gelegentlich abgeschaltet werden.

Praktisch: Im AWS Cost Explorer gibt es eine RI-Purchase-Empfehlung, die auf Basis der aktuellen Nutzung genau berechnet, welche RIs sich lohnen und wie hoch die Ersparnis wäre.

5. Spot Instances für unterbrechbare Workloads

Spot Instances sind ungenutzte EC2-Kapazitäten, die AWS mit bis zu 90% Rabatt anbietet – mit dem Haken, dass sie mit 2 Minuten Vorwarnung zurückgezogen werden können. Für die richtigen Workloads ist das ein enormer Hebel.

Geeignet für Spot Instances:

  • CI/CD-Build-Jobs (Jenkins, GitHub Actions Self-Hosted Runner)
  • Batch-Verarbeitung (Datenimporte, Berechnungen, Rendering)
  • Entwicklungs- und Test-Umgebungen
  • Stateless Web-Tier hinter einem Load Balancer (mehrere Instanzen)
  • Machine-Learning-Training

Nicht geeignet:

  • Datenbanken (zustandsbehaftet)
  • Single-Point-of-Failure-Systeme ohne Redundanz
  • Workloads mit strikten Latenz-SLAs
yaml
# Terraform: Spot Instance mit On-Demand-Fallback (Mixed Instances Policy)
resource "aws_autoscaling_group" "app" {
  name               = "app-asg"
  vpc_zone_identifier = var.subnet_ids
  min_size           = 2
  max_size           = 10
  desired_capacity   = 3

  mixed_instances_policy {
    instances_distribution {
      on_demand_base_capacity                  = 1   # Mindestens 1 On-Demand
      on_demand_percentage_above_base_capacity = 20  # 20% On-Demand, 80% Spot
      spot_allocation_strategy                 = "capacity-optimized"
    }

    launch_template {
      launch_template_specification {
        launch_template_id = aws_launch_template.app.id
        version            = "$Latest"
      }

      # Mehrere Instanztypen für höhere Spot-Verfügbarkeit
      override {
        instance_type = "m5.large"
      }
      override {
        instance_type = "m5a.large"
      }
      override {
        instance_type = "m6i.large"
      }
    }
  }
}

6. S3 Lifecycle Policies: Alte Daten automatisch günstiger ablegen

S3 Standard kostet ca. $0.023 pro GB und Monat. S3 Glacier Instant Retrieval kostet $0.004 pro GB – also 83% weniger für Daten, die selten abgerufen werden. Mit Lifecycle Policies automatisiert AWS den Übergang.

json
{
  "Rules": [
    {
      "ID": "move-old-logs-to-glacier",
      "Status": "Enabled",
      "Filter": { "Prefix": "logs/" },
      "Transitions": [
        {
          "Days": 30,
          "StorageClass": "STANDARD_IA"
        },
        {
          "Days": 90,
          "StorageClass": "GLACIER_IR"
        },
        {
          "Days": 365,
          "StorageClass": "DEEP_ARCHIVE"
        }
      ],
      "Expiration": {
        "Days": 730
      }
    }
  ]
}

S3 Intelligent-Tiering ist eine Alternative für Daten mit unvorhersehbarem Zugriffsmuster: AWS verschiebt Objekte automatisch zwischen Tiers, ohne dass du Zugriffszeiten kennen musst. Sinnvoll ab ~$0.0025 pro 1.000 Objekten Monitoring-Gebühr.

Weitere S3-Kostenfallen:

  • Versionierung: Wenn aktiviert, sammeln sich alte Versionen an. Lifecycle Rule für nicht-aktuelle Versionen anlegen.
  • Incomplete Multipart Uploads: Fehlgeschlagene Uploads belegen Speicher. Lifecycle Rule mit AbortIncompleteMultipartUpload nach 7 Tagen.
  • Request-Kosten bei kleinen Objekten: Millionen kleiner Dateien (< 128 KB) machen S3 Intelligent-Tiering teuer. Kleine Objekte bündeln.

7. Data Transfer Costs im Griff behalten

Datentransfer ist oft der unsichtbarste Kostentreiber. Grob gesagt: eingehender Traffic ist kostenlos, ausgehender kostet. Und Traffic zwischen AWS-Services in verschiedenen Availability Zones oder Regionen kostet extra.

Häufige Fallen:

  • NAT Gateway: Kostet $0.045 pro GB verarbeiteten Daten. Wenn EC2-Instanzen große Datenmengen über das NAT Gateway transferieren (z.B. S3-Zugriffe), summiert sich das schnell.
  • Cross-AZ-Traffic: $0.01 pro GB in jede Richtung. Datenbank-Replikas in anderen AZs, Load Balancer – das zählt alles.
  • CloudFront fehlt: Statische Assets direkt aus S3 ausliefern statt über CloudFront ist sowohl langsamer als auch teurer.

S3 Gateway Endpoint: NAT-Kosten bei S3-Zugriffen eliminieren

yaml
# Terraform: S3 Gateway Endpoint (kostenlos, kein NAT-Traffic mehr für S3)
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

  tags = {
    Name = "s3-gateway-endpoint"
  }
}

# DynamoDB-Endpoint ebenfalls kostenlos und empfehlenswert
resource "aws_vpc_endpoint" "dynamodb" {
  vpc_id            = aws_vpc.main.id
  service_name      = "com.amazonaws.eu-central-1.dynamodb"
  vpc_endpoint_type = "Gateway"
  route_table_ids   = aws_route_table.private[*].id
}

Ein S3 Gateway Endpoint ist kostenlos und leitet den Datenverkehr von EC2 zu S3 direkt über das AWS-interne Netzwerk – das NAT Gateway wird dabei umgangen. Bei S3-intensiven Workloads kann das die Monatsbill deutlich reduzieren.

8. RDS optimieren: Größe, Storage und Aurora Serverless

RDS ist oft der zweitgrößte Kostenblock nach EC2. Drei Hebel mit sofortiger Wirkung:

Right-Sizing bei RDS

Gleiche Logik wie bei EC2: CloudWatch-Metriken (CPUUtilization, FreeableMemory, DatabaseConnections) anschauen. Eine db.r6g.xlarge statt db.r5.xlarge kann bei gleicher Performance 10–15% günstiger sein.

RDS Storage-Typ prüfen

gp2 (älterer Storage-Typ) kostet $0.138 pro GB. gp3 kostet $0.115 pro GB und ist 20% günstiger – mit konfigurierbarem IOPS ohne zusätzliche Kosten bis 3.000 IOPS. Migration von gp2 auf gp3 ist ein Klick in der Konsole, ohne Downtime.

Bash
# RDS-Instanzen mit gp2-Storage finden und auf gp3 migrieren
aws rds describe-db-instances \
  --query "DBInstances[?StorageType=='gp2'].[DBInstanceIdentifier,AllocatedStorage,StorageType]" \
  --output table

# Migration auf gp3 (apply immediately = kein Wartungsfenster nötig)
aws rds modify-db-instance \
  --db-instance-identifier mydb \
  --storage-type gp3 \
  --apply-immediately

Aurora Serverless v2 für variable Workloads

Wenn Datenbankauslastung stark schwankt (nachts fast null, tagsüber Spitzen), ist Aurora Serverless v2 interessant: Die Kapazität skaliert in Sekunden von 0.5 bis 128 ACUs, und man zahlt nur für tatsächliche Nutzung. Für reine Dev-Datenbanken, die nachts nicht gebraucht werden, kann das 60–70% sparen.

9. Budget Alerts: Kosten-Explosionen frühzeitig erkennen

Alle Optimierungen nützen wenig, wenn beim nächsten Deployment aus Versehen 50 EC2-Instanzen gestartet werden und erst am Monatsende auffällt. AWS Budgets schickt Alarm, bevor das Budget überschritten wird.

yaml
# Terraform: Budget mit E-Mail-Alert bei 80% und 100% Threshold
resource "aws_budgets_budget" "monthly_cost" {
  name         = "monthly-cost-alert"
  budget_type  = "COST"
  limit_amount = "500"
  limit_unit   = "USD"
  time_unit    = "MONTHLY"

  notification {
    comparison_operator        = "GREATER_THAN"
    threshold                  = 80
    threshold_type             = "PERCENTAGE"
    notification_type          = "ACTUAL"
    subscriber_email_addresses = ["emre@example.com"]
  }

  notification {
    comparison_operator        = "GREATER_THAN"
    threshold                  = 100
    threshold_type             = "PERCENTAGE"
    notification_type          = "FORECASTED"  # Frühwarnung auf Basis von Trends!
    subscriber_email_addresses = ["emre@example.com"]
  }
}

# Anomalie-Erkennung: AWS meldet ungewöhnliche Kostenausreißer
resource "aws_ce_anomaly_monitor" "service" {
  name         = "AWSServiceCostAnomaly"
  monitor_type = "DIMENSIONAL"
  monitor_dimension = "SERVICE"
}

resource "aws_ce_anomaly_subscription" "realtime_alert" {
  name      = "realtime-anomaly-alert"
  threshold = 20  # Alert wenn Anomalie > $20
  frequency = "IMMEDIATE"

  monitor_arn_list = [aws_ce_anomaly_monitor.service.arn]

  subscriber {
    type    = "EMAIL"
    address = "emre@example.com"
  }
}

Die Anomaly Detection ist besonders wertvoll: Sie lernt das normale Ausgabemuster und schlägt Alarm, wenn ein Service plötzlich viel mehr kostet als üblich – auch wenn das Budget-Limit noch nicht erreicht ist.

10. Compute Savings Plans: Flexibler als Reserved Instances

Compute Savings Plans sind eine neuere Alternative zu Reserved Instances – mit einem entscheidenden Vorteil: Sie gelten für jeden EC2-Instanztyp, jede Region, Lambda und Fargate. Man committet sich auf einen stündlichen Ausgabebetrag (z.B. $2/h), nicht auf eine spezifische Instanzgröße.

Vergleich der Commitment-Modelle:

Modell Flexibilität Ersparnis Empfehlung
On-Demand Maximum 0% Dev / volatile
Compute Savings Plan (1J) Hoch ~33% Guter Einstieg
EC2 Instance SP (1J) Mittel ~40% Wenn Instanzfamilie fix
Standard RI (3J, all upfront) Gering ~60–72% Stabile, lange Planung

Für die meisten Teams empfehle ich als Einstieg: Compute Savings Plan für 1 Jahr, no upfront. Kein Vorabkapital, ~33% Ersparnis, und man ist nicht an eine Instanzgröße gebunden. Erst wenn klar ist, welche Instanztypen langfristig stabil bleiben, lohnt sich der Wechsel zu spezifischeren (und günstigeren) Modellen.

Fazit: Prioritäten setzen, nicht alles auf einmal

10 Maßnahmen auf einmal umzusetzen ist unrealistisch. Die Empfehlung: Mit Transparenz starten, dann die Quick Wins mitnehmen, dann die strategischen Hebel angehen.

Sofort umsetzbar (diese Woche):

  1. Cost Explorer aktivieren, Top-Kostentreiber identifizieren
  2. Ungenutzte Ressourcen (EBS, EIPs, alte Snapshots) bereinigen
  3. S3 Gateway Endpoint einrichten (kostenlos, kein Aufwand)
  4. Budget Alerts und Anomaly Detection einrichten

Kurzfristig (nächste 2–4 Wochen):

  1. RDS gp2 → gp3 migrieren
  2. S3 Lifecycle Policies für Log-Buckets einrichten
  3. EC2 Right-Sizing auf Basis von CloudWatch-Daten

Strategisch (nächster Monat):

  1. Compute Savings Plan kaufen
  2. Spot Instances für CI/CD und Batch-Jobs einführen
  3. Data Transfer Costs analysieren und NAT Gateway-Optimierung
In meiner Erfahrung lassen sich bei den meisten AWS-Konten mit diesen Maßnahmen 20–40% der monatlichen Kosten einsparen – oft ohne eine einzige Zeile Anwendungscode anzufassen. Der größte Feind ist nicht mangelndes Wissen, sondern das Aufschieben des ersten Überblicks.

Wenn du wissen möchtest, wo bei deinem AWS-Setup die größten Hebel liegen, helfe ich gerne mit einem kurzen Review weiter. Schreib mich einfach an.

AWS-Kosten unter Kontrolle bringen?

Ich helfe kleinen Teams und KMUs, ihre Cloud-Infrastruktur kosteneffizient aufzusetzen – von Cost Reviews über Terraform-Optimierungen bis zur langfristigen FinOps-Strategie.