All Articles
This article is not yet available in your language and is shown in the original language.

Lambda Cold Starts verstehen und minimieren

Nicolai Lang

Nicolai Lang

Principal Cloud Architect & Founder of WABI Engineering. Specialized in Serverless and AWS CDK.

Cold Starts bei AWS Lambda sind ein Dauerbrenner in der Serverless-Community. Jeder hat eine Meinung, aber die wenigsten haben gemessen. In diesem Artikel räumen wir mit Mythen auf und zeigen, was wirklich funktioniert.

Was ist ein Cold Start?

Ein Cold Start tritt auf, wenn Lambda eine neue Execution Environment erstellen muss. Das passiert in drei Phasen:

  1. Environment-Provisioning — AWS allokiert einen Micro-VM Container
  2. Runtime-Init — Die Laufzeitumgebung (Node.js, Python, etc.) wird gestartet
  3. Handler-Init — Dein Code wird geladen, globale Variablen initialisiert
// Phase 3: Handler-Init — dieser Code läuft beim Cold Start
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb";

// SDK-Clients AUSSERHALB des Handlers initialisieren
const client = new DynamoDBClient({});
const docClient = DynamoDBDocumentClient.from(client);

// Dieser Handler läuft bei JEDEM Request
export async function handler(event: APIGatewayEvent) {
  // docClient wird wiederverwendet — kein Cold Start Overhead
  return docClient.send(
    new GetCommand({ TableName: "users", Key: { id: event.pathParameters!.id } }),
  );
}

Die wichtigsten Einflussfaktoren

Runtime-Wahl

Nicht alle Runtimes sind gleich schnell beim Starten:

RuntimeTypischer Cold StartBemerkung
Python 3.12150–250 msSehr schnell
Node.js 22200–350 msGut, mit ESM etwas langsamer
Go80–120 msAm schnellsten (compiled)
Java 21800–2000 msSnapStart nutzen!
.NET 8400–800 msAOT-Compilation hilft

Bundle-Größe

Je kleiner das Deployment-Paket, desto schneller der Cold Start. Das bedeutet:

  • Tree-Shaking konsequent nutzen (ESBuild, Rollup)
  • Nur importieren was nötig ist — nicht import * as AWS from 'aws-sdk'
  • Layers vermeiden wenn möglich — sie erhöhen die Init-Zeit
// ❌ Schlecht: Importiert das gesamte SDK
import { DynamoDB, S3, SQS } from "aws-sdk";

// ✅ Gut: Nur den benötigten Client importieren
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";

Strategien die funktionieren

1. Provisioned Concurrency

Die "Holzhammer-Methode" — AWS hält warme Environments bereit:

const alias = new lambda.Alias(this, "ProdAlias", {
  aliasName: "prod",
  version: fn.currentVersion,
  provisionedConcurrentExecutions: 5,
});

Kosten: ca. $15/Monat pro provisionierter Instanz. Lohnt sich für latenz-kritische APIs.

2. SnapStart (Java/JVM)

Für Java-basierte Lambdas ein Game-Changer. SnapStart erstellt einen Snapshot nach der Init-Phase:

  • Cold Start sinkt von ~2s auf ~200ms
  • Keine Code-Änderungen nötig
  • Seit 2023 GA verfügbar

3. Architektur-Entscheidungen

Oft ist die beste Strategie, Cold Starts gar nicht erst zum Problem werden zu lassen:

  • Asynchrone Verarbeitung — SQS/EventBridge statt synchroner API-Calls
  • Step Functions — Orchestrierung statt monolithischer Lambdas
  • Weniger, größere Functions — statt Micro-Functions, die selten aufgerufen werden

Fazit

Cold Starts sind in den meisten Fällen kein echtes Problem. Für 90% der Workloads liegt die zusätzliche Latenz unter 300ms — und das nur beim ersten Request. Bevor du in Provisioned Concurrency investierst, miss erstmal. CloudWatch Insights macht das einfach:

filter @type = "REPORT"
| stats avg(@initDuration) as avgColdStart,
        max(@initDuration) as maxColdStart,
        count(@initDuration) as coldStartCount,
        count(*) as totalInvocations
| display avgColdStart, maxColdStart, coldStartCount, totalInvocations

Die beste Optimierung ist die, die du nicht brauchst.