\n\n\n\n Meine Cloud-Rechnungen sind zu hoch: Was ich jetzt sehe - AgntMax \n

Meine Cloud-Rechnungen sind zu hoch: Was ich jetzt sehe

📖 11 min read2,188 wordsUpdated Mar 27, 2026

Hallo zusammen, Jules Martin hier, zurück auf agntmax.com!

Heute möchte ich über etwas sprechen, das mich und wahrscheinlich viele von euch im letzten Jahr gequält hat: die schleichenden Kosten der Cloud-Infrastruktur, insbesondere wenn es um serverlose Funktionen geht. Wir alle wurden mit dem Traum „Zahle nur, was du nutzt“ verkauft, und lange Zeit fühlte es sich wie eine Realität an. Aber in letzter Zeit habe ich gesehen, wie die Rechnungen steigen, manchmal unerklärlich, selbst wenn die Verkehrsmuster stabil zu sein scheinen. Es ist, als würden wir von der Flexibilität, die wir angenommen haben, schrittweise abgezockt. Lassen Sie uns also etwas ganz Spezielles und Zeitgemäßes erkunden: Das Serverless-Monster zähmen: Versteckte AWS-Lambda-Kosten aufdecken und senken.

Mein eigener Weg begann vor etwa sechs Monaten. Wir haben einen Kern-Mikroservice, der die Benutzerauthentifizierung und das Sitzungsmanagement behandelt. Er basiert fast ausschließlich auf AWS Lambda, API Gateway, DynamoDB und Cognito. Lange Zeit waren die Kosten perfekt vorhersehbar. Dann, letzten Sommer, sprang unsere AWS-Rechnung für diesen speziellen Dienst um etwa 15%. Keine neuen Funktionen, keine signifikanten Verkehrsspitzen. Zunächst schob ich es auf saisonale Schwankungen oder einen kleinen Bug, den ich noch nicht gefunden hatte. Aber als die Rechnung des nächsten Monats sogar höher ausfiel, wusste ich, dass ich nachforschen musste. Das war nicht nur ein kurzer Anstieg; es war ein Trend, und es kostete uns echtes Geld.

Die Illusion der „kostenlosen“ Stufen und die Realität der „winzigen“ Aufrufe

Einer der größten Verkaufsargumente von Serverless, insbesondere für Startups oder kleinere Teams, ist die großzügige kostenlose Stufe. Und sie ist großzügig! Eine Million kostenlose Aufrufe pro Monat für Lambda, plus eine bedeutende Menge an Rechenzeit. Das Problem ist, dass mit dem Wachstum Ihrer Anwendung diese „kostenlosen“ Aufrufe schneller verschwinden als ein Stück Pizza bei einem Tech Meetup. Oft wird das enorme Volumen von winzigen, scheinbar unbedeutenden Aufrufen übersehen, die sich summieren. Denken Sie an Cron-Jobs, interne Gesundheitsprüfungen oder auch Wiederholungsmechanismen von anderen Diensten. Jeder einzelne zählt.

Meine Untersuchung unseres Authentifizierungsdienstes enthüllte genau das. Wir hatten eine Lambda-Funktion, nennen wir sie auth-token-refresher, die dazu gedacht war, interne Servicetoken regelmäßig zu aktualisieren. Sie wurde alle fünf Minuten ausgeführt. Scheint harmlos, oder? 288 Aufrufe pro Tag. Multiplizieren Sie das mit 30 Tagen, und Sie erhalten 8.640 Aufrufe pro Monat. Wenn man dann unsere Entwicklungs-, Test- und Produktionsumgebungen hinzuaddiert, sind das plötzlich über 25.000 Aufrufe nur für eine kleine Wartungsaufgabe. Wir hatten ein Dutzend solcher Funktionen. Plötzlich waren unsere „winzigen“ Aufrufe nicht mehr so winzig.

Die Schuldigen finden: CloudWatch-Metriken sind Ihr bester Freund

Der erste Schritt, um dieses Monster zu zähmen, besteht darin, zu wissen, wohin Ihr Geld fließt. AWS CloudWatch ist hier unverzichtbar. Schauen Sie sich nicht nur das hochrangige Abrechnungs-Dashboard an; erkunden Sie die spezifischen Metriken für Ihre Lambda-Funktionen.

Darauf habe ich mich konzentriert:

  1. Aufrufe: Dies ist die direkteste Metrik. Hohe Aufrufzahlen für Funktionen, die keinen direkten Benutzerverkehr verarbeiten, sind sofortige Alarmzeichen.
  2. Dauer: Wie lange läuft jeder Aufruf? Längere Dauern bedeuten höhere Kosten.
  3. Speicherverbrauch: Stellen Sie sicher, dass Sie nicht zu viel Speicher für Ihre Funktionen bereitstellen. Sie zahlen für das, was Sie zuweisen, nicht für das, was Sie nutzen.
  4. Fehlerquote: Hohe Fehlerquoten können zu Wiederholungen führen, was mehr Aufrufe und verschwendete Rechenzyklen bedeutet.

Für unseren auth-token-refresher habe ich mir die `Aufrufe`-Metrik angesehen. Und tatsächlich lief es wie am Schnürchen, alle fünf Minuten. Die Dauer war minimal, nur etwa 50 ms. Aber das enorme Volumen trug zu unseren Gesamtkosten für Aufrufe bei.

Praktisches Beispiel 1: Konsolidieren und intelligenter planen

Die Lösung für auth-token-refresher und mehrere andere ähnliche Wartungsfunktionen war überraschend einfach: Konsolidierung. Statt einzelne Lambda-Funktionen, die von CloudWatch Events (oder EventBridge heutzutage) zu unterschiedlichen Zeiten ausgelöst werden, zu haben, habe ich eine einzige „Wartungs-Runner“-Lambda erstellt.

Dieser „Wartungs-Runner“ wird durch eine einzige CloudWatch-Eventregel ausgelöst, sagen wir, einmal pro Stunde. Innerhalb dieses Runners habe ich einen einfachen Dispatcher, der die aktuelle Uhrzeit überprüft und die notwendigen Aufgaben ausführt. Zum Beispiel:


import os
import datetime

def lambda_handler(event, context):
 current_hour = datetime.datetime.now().hour
 current_minute = datetime.datetime.now().minute

 # Aufgabe 1: Auth-Token aktualisieren (wurde alle 5 Minuten ausgeführt)
 if current_minute % 10 == 0: # Jetzt alle 10 Minuten ausführen
 print("Auth-Token-Aktualisierung wird ausgeführt...")
 # Logik zur tatsächlichen Aktualisierung des Tokens oder eine andere interne Funktion aufrufen
 refresh_auth_token()

 # Aufgabe 2: Alte Protokolle bereinigen (wurde stündlich ausgeführt)
 if current_hour % 1 == 0 and current_minute == 0: # Zur vollen Stunde ausführen
 print("Protokollbereinigung wird ausgeführt...")
 cleanup_old_logs()

 # Aufgabe 3: Status externer Dienste überprüfen (wurde alle 30 Minuten ausgeführt)
 if current_minute == 0 or current_minute == 30:
 print("Überprüfung des Status externer Dienste...")
 check_external_service()

 return {
 'statusCode': 200,
 'body': 'Wartungsaufgaben ausgeführt.'
 }

def refresh_auth_token():
 # ... tatsächliche Logik zur Aktualisierung des Tokens ...
 pass

def cleanup_old_logs():
 # ... tatsächliche Logik zur Bereinigung von Protokollen ...
 pass

def check_external_service():
 # ... tatsächliche Logik zur Überprüfung externer Dienste ...
 pass

Diese einfache Änderung reduzierte die Aufrufanzahl für diese Wartungsaufgaben sofort von Hunderttausenden pro Monat auf einige Tausend. Die Kosteneinsparungen waren spürbar, nicht nur bei den Lambda-Aufrufen, sondern auch bei den damit verbundenen CloudWatch-Logs und API-Gateway-Aufrufen (falls einer dieser Aufrufe über das API Gateway verfügbar war).

Die Falle der Überprovisionierung von Speicher

Das ist ein weiterer subtiler Kostentreiber, der oft übersehen wird. Wenn Sie eine Lambda-Funktion erstellen, weisen Sie eine bestimmte Menge an Speicher zu (z. B. 128 MB, 256 MB, 512 MB). Sie zahlen für diesen zugewiesenen Speicher, unabhängig davon, wie viel Ihre Funktion tatsächlich nutzt. Darüber hinaus skaliert die CPU-Leistung proportional zur Speicherzuweisung. Wenn Sie also 1 GB Speicher für ein einfaches Python-Skript zuweisen, das nur 128 MB benötigt, zahlen Sie nicht nur zu viel für den Speicher; Sie zahlen auch zu viel für CPU-Zyklen, die nicht benötigt werden.

Ich habe das auf die harte Tour mit einer Datenverarbeitungs-Lambda gelernt, die ursprünglich mit 1 GB Speicher „just in case“ konfiguriert war. Als ich mir ihre CloudWatch-Metriken für den Speicherverbrauch ansah, blieb sie selbst während Spitzenlastzeiten konstant unter 200 MB. Wir haben im Grunde für 800 MB ungenutzten RAM und den entsprechenden CPU-Boost bezahlt.

Praktisches Beispiel 2: Optimierung der Speichernutzung mit Lambda Power Tuning

Manuelles Herausfinden der optimalen Speichereinstellung kann mühsam sein. Sie müssen bereitstellen, testen, überwachen, anpassen und wiederholen. Glücklicherweise gibt es ein fantastisches Open-Source-Tool namens AWS Lambda Power Tuning (entwickelt von Alex Casalboni bei AWS), das diesen Prozess zum Kinderspiel macht.

Es handelt sich um eine serverlose Anwendung, die Ihnen hilft, die optimale Speichereinstellung für Ihre Lambda-Funktionen basierend auf Kosten und Leistung zu visualisieren und zu identifizieren. Sie stellen es in Ihrem AWS-Konto bereit, und dann können Sie es verwenden, um Ihre Funktionen zu testen.

So funktioniert es generell:

  1. Sie stellen das Power Tuning-Tool über das Serverless Application Repository oder SAM bereit.
  2. Sie rufen eine Zustandsmaschine (die vom Tool erstellt wurde) mit dem ARN Ihrer Lambda-Funktion und einem Payload auf.
  3. Die Zustandsmaschine ruft Ihre Lambda mehrfach mit unterschiedlichen Speicherkonfigurationen (z. B. 128 MB, 256 MB, 512 MB, 1024 MB usw.) auf.
  4. Anschließend analysiert sie die Ausführungsprotokolle und bietet eine Visualisierung, die die Kosten- und Geschwindigkeitsabstimmungen für jede Speichereinstellung zeigt.

Für meine Datenverarbeitungs-Lambda zeigte der Test mit dem Power Tuner, dass 256 MB der ideale Punkt für die Kosten waren, mit vernachlässigbarem Leistungsverlust im Vergleich zu 1 GB. Wir haben die Speichermenge sofort auf 256 MB reduziert, was zu einer Einsparung von 75% der Rechenkosten für diese spezielle Funktion führte. Das war kein Einzelfall; ich habe es inzwischen zur Standardpraxis gemacht, neue oder erneut bewertete Funktionen durch dieses Tool zu leiten.

Um es zu verwenden, starten Sie normalerweise nach der Bereitstellung die Zustandsmaschine mit etwas wie diesem (ARN und Payload anpassen):


aws stepfunctions start-execution \
 --state-machine-arn "arn:aws:states:REGION:ACCOUNT_ID:stateMachine:powerTuningStateMachine" \
 --input '{ "lambdaARN": "arn:aws:lambda:REGION:ACCOUNT_ID:function:YOUR_FUNCTION_NAME", "num": 100, "payload": {}, "parallel": 5 }'

Die Ausgabe bietet ein klares Diagramm, das genau zeigt, wo sich Kosten und Geschwindigkeit für optimale Leistung schneiden. Es ist ein erheblicher Schritt in Richtung Kostenoptimierung.

Protokollierungsdetails und Kaltstarts

Zwei weitere Bereiche, die oft unerwartet auftreten, sind die Protokollierungsdetails und Kaltstarts. CloudWatch-Logs sind nicht kostenlos. Jede Zeile, die Ihre Lambda-Funktion ausgibt, wird erfasst und gespeichert, und dafür zahlen Sie. Während gute Protokollierung entscheidend für das Debugging ist, kann eine übermäßig detaillierte Protokollierung (z. B. das Ausgeben ganzer Objekte oder das unnötige Wiederholen von Statusnachrichten) schnell Ihre CloudWatch-Logs-Rechnung in die Höhe treiben.

Ich habe einige Funktionen gefunden, die bei jedem Aufruf den vollständigen HTTP-Anforderungsinhalt protokollierten. Während dies für die initiale Entwicklung nützlich war, war es in der Produktion nur noch Rauschen und Kosten. Eine schnelle Anpassung, nur essenzielle Metadaten (Anforderungs-ID, Statuscode, Endpunkt) zu protokollieren, reduzierte unsere Protokollaufzeichnung erheblich.

Kalte Starts haben, obwohl sie nicht direkt als „Kosten“ betrachtet werden, Auswirkungen auf die Benutzererfahrung und können indirekt zu mehr Wiederholungen oder längeren Abrechnungszeiträumen führen, wenn Ihre Funktion auf Ressourcen warten muss. Während AWS erhebliche Fortschritte bei der Reduzierung der Kaltstartzeiten gemacht hat, kann die Optimierung der Paketgröße Ihrer Funktion und das Vermeiden komplexer Initialisierungseinheiten außerhalb des Handlers dennoch einen Unterschied machen. Für kritische, latenzempfindliche Funktionen ist die bereitgestellte Parallelität eine Option, aber seien Sie sich bewusst, dass Sie für diese zugewiesene Parallelität zahlen, auch wenn sie ungenutzt bleibt.

Praktisches Beispiel 3: Intelligentes Logging und Umgebungsvariablen

Für das Logging ist die einfachste Lösung oft die beste. Verwenden Sie Umgebungsvariablen, um die Protokollebene zu steuern. In Python können Sie beispielsweise Folgendes tun:


import os
import logging

LOG_LEVEL = os.environ.get('LOG_LEVEL', 'INFO').upper()
logging.basicConfig(level=LOG_LEVEL)
logger = logging.getLogger()

def lambda_handler(event, context):
 logger.debug("Dies ist eine Debug-Nachricht, die nur sichtbar ist, wenn LOG_LEVEL auf DEBUG steht")
 logger.info("Verarbeite Ereignis: %s", event.get('request_id'))
 try:
 # ... Funktionslogik ...
 logger.debug("Verarbeitung für request_id: %s abgeschlossen", event.get('request_id'))
 return {
 'statusCode': 200,
 'body': 'Erfolg'
 }
 except Exception as e:
 logger.error("Fehler bei der Verarbeitung von request_id %s: %s", event.get('request_id'), str(e), exc_info=True)
 return {
 'statusCode': 500,
 'body': 'Fehler'
 }

Indem Sie LOG_LEVEL in der Produktion auf INFO und in der Entwicklung/Staging auf DEBUG setzen, können Sie Ihre CloudWatch Logs-Rechnung deutlich reduzieren, ohne auf Sichtbarkeit zu verzichten, wenn Sie sie benötigen.

Ein weiterer Trick ist, darauf zu achten, was außerhalb des Handlers initialisiert wird. Jeder Code, der sich direkt im globalen Bereich Ihrer Lambda-Funktion befindet, wird während des Kaltstarts ausgeführt. Wenn Sie teure Vorgänge wie das Pooling von Datenbankverbindungen oder große Bibliotheksimporte haben, sollten Sie in Erwägung ziehen, diese bis zur tatsächlichen Notwendigkeit im Handler aufzuschieben oder sicherzustellen, dass sie effizient für nachfolgende warme Aufrufe zwischengespeichert werden.

Handlungsfähige Erkenntnisse für Ihre Serverless-Kostenreduzierung

Okay, wir haben einiges behandelt. Hier ist eine Zusammenfassung praktischer Schritte, die Sie jetzt unternehmen können, um diese heimlichen Lambda-Kosten zu senken:

  • Unermüdlich überwachen: Schauen Sie nicht nur flüchtig auf Ihre gesamte AWS-Rechnung. Untersuchen Sie die CloudWatch-Metriken für Aufrufe, Dauer und Speicherverbrauch für jede Lambda-Funktion. Richten Sie Warnungen für unerwartete Spitzen ein.
  • Cron-Jobs konsolidieren: Wenn Sie viele kleine, geplante Lambda-Funktionen haben, ziehen Sie in Betracht, diese zu einer einzelnen „Wartungsroutine“ zusammenzufassen, die Aufgaben nach einem weniger häufigen Zeitplan verteilt. Das reduziert die Aufrufanzahl drastisch.
  • Speicherzuweisung optimieren: Verwenden Sie Tools wie AWS Lambda Power Tuning, um die optimale Speichereinstellung für Ihre Funktionen zu finden. Schätzen Sie nicht einfach und überprovisionieren Sie. Denken Sie daran: Mehr Speicher bedeutet mehr CPU und Sie zahlen für beides.
  • Logging-Verbosity steuern: Implementieren Sie pro Umgebungsvariablen gesteuerte Protokollebene (z.B. INFO für die Produktion, DEBUG für die Entwicklung). Vermeiden Sie das Protokollieren ganzer Anforderungsinhalte oder übermäßiger interner Zustände in der Produktion. Ihre CloudWatch Logs-Rechnung wird es Ihnen danken.
  • Unbenutzte Funktionen überprüfen: Überprüfen Sie regelmäßig Ihre Lambda-Funktionen. Gibt es alte, experimentelle oder veraltete Funktionen, die noch aktiv sind und Kosten verursachen? Löschen Sie diese!
  • Paketgröße im Auge behalten: Kleinere Bereitstellungspakete bedeuten schnellere Kaltstarts und geringere Speicherkosten. Beziehen Sie nur notwendige Abhängigkeiten ein.
  • Preismodell verstehen: Lesen Sie die Lambda-Preisseite erneut. Verstehen Sie, wie Aufrufe, GB-Sekunden und Datenübertragungen abgerechnet werden. Wissen ist Macht, insbesondere wenn es um Ihr Geld geht.

Den Serverless-Riesen zu zähmen bedeutet nicht, Serverless zu vermeiden; es geht darum, schlau und bewusst damit umzugehen, wie wir es nutzen. Die Flexibilität und Skalierbarkeit sind unbezahlbar, aber ohne angemessene Wachsamkeit können diese „winzigen“ Kosten sich zu einem erheblichen Teil Ihres Budgets summieren. Gehen Sie voran, überwachen, optimieren und sparen Sie!

Das war’s für heute von mir. Lassen Sie mich in den Kommentaren wissen, wenn Sie weitere Tipps oder Tricks zur Optimierung der Lambda-Kosten haben!

🕒 Published:

✍️
Written by Jake Chen

AI technology writer and researcher.

Learn more →
Browse Topics: benchmarks | gpu | inference | optimization | performance

Recommended Resources

AgntdevClawseoAgntaiAgntwork
Scroll to Top