AWS Lambda Cheat Sheet
AWS Lambda runs Node.js handlers on demand: export an async function receiving event and context, return a response or throw for API Gateway and other triggers.
How to use this AWS Lambda cheat sheet Cold starts occur when AWS provisions a new execution environment—minimize bundle size, lazy-load heavy SDK clients, and use provisioned concurrency for latency-sensitive paths. Environment variables store config; secrets belong in Secrets Manager or SSM Parameter Store, not hard-coded.
IAM execution roles grant least-privilege permissions per function. API Gateway proxy events wrap HTTP request fields in event. Layers share dependencies across functions. Set timeout and memory—memory also scales CPU proportionally.
Quick AWS Lambda example export const handler = async (event, context) => {
context.callbackWaitsForEmptyEventLoop = false;
const body = JSON.parse(event.body ?? '{}');
const id = event.pathParameters?.id;
return {
statusCode: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id, received: body }),
};
}; Handler Signature & Response Element Example Notes Handler export export const handler = async (event, context) => {} CommonJS module.exports.handler also works event Trigger-specific JSON payload API Gateway, S3, SQS shapes differ context context.awsRequestId, getRemainingTimeInMillis() Request metadata and deadline Return (sync) return { statusCode: 200, body: "ok" } API Gateway proxy integration response callbackWaitsForEmptyEventLoop false for DB pools Exit without waiting for open handles Structured errors throw new Error("fail") → 502 from API GW Map to statusCode in try/catch for 4xx JSON body JSON.parse(event.body) Validate input; API GW may base64-encode binary Logging console.log(JSON.stringify({ reqId: context.awsRequestId })) CloudWatch Logs capture stdout
Cold Starts, Env & IAM Topic Example Notes Cold start First invoke or after idle scale-down Shrink bundle; avoid top-level heavy imports Provisioned concurrency Pre-warmed execution environments Costs more; cuts tail latency Env vars process.env.TABLE_NAME Set in function config or serverless.yml Secrets Secrets Manager ARN in env Fetch at cold start and cache in global scope Execution role lambda.amazonaws.com trust policy Attach AWSLambdaBasicExecutionRole + custom policies Least privilege DynamoDB table-scoped actions Avoid AdministratorAccess on Lambda roles VPC config Subnet + security group Adds ENI cold start latency; needed for private RDS ARM64 (Graviton) architectures: [arm64] Often better price/performance for Node
API Gateway Event & Layers Field Example Purpose httpMethod event.httpMethod === "POST" Route by verb in single Lambda path event.path Resource path; use pathParameters for {id} pathParameters event.pathParameters.id REST API route params queryStringParameters event.queryStringParameters?.page Query string map (may be null) headers event.headers.authorization Case-insensitive in API GW HTTP API v2 requestContext event.requestContext.authorizer JWT/Cognito claims after authorizer Layer arn:aws:lambda:region:acct:layer:deps:1 Shared node_modules up to 250 MB unzipped total Layer path /opt/nodejs/node_modules Node.js layer mount location
Timeout, Memory & Limits Setting Example Notes Timeout timeout: 30 seconds max 900 Set below upstream client timeout Memory memorySize: 512 MB (128–10240) More memory = more CPU and cost Ephemeral storage /tmp up to 10 GB Temp files; cleared between invocations maybe reused Concurrency limit Reserved vs account limit Throttle with 429 when exceeded Payload limit 6 MB sync invoke request/response Use S3 for large bodies DLQ SQS or SNS on async failure Capture failed async invocations Idempotency Store event id in DynamoDB Safe retries from SQS/Lambda pollers X-Ray AWS_XRAY_TRACING_NAME Trace cold starts and downstream calls
Reuse SDK client outside handler import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
import { DynamoDBDocumentClient, PutCommand } from '@aws-sdk/lib-dynamodb';
const doc = DynamoDBDocumentClient.from(new DynamoDBClient({}));
export const handler = async (event) => {
await doc.send(new PutCommand({ TableName: process.env.TABLE, Item: event.item }));
return { statusCode: 201, body: JSON.stringify({ ok: true }) };
}; Initialize clients in global scope so warm invocations skip construction cost.
SQS batch partial failure export const handler = async (event) => {
const failures = [];
for (const record of event.Records) {
try { await process(JSON.parse(record.body)); }
catch { failures.push({ itemIdentifier: record.messageId }); }
}
return { batchItemFailures: failures };
}; Report batchItemFailures so only failed messages retry (Lambda SQS trigger).
Serverless Framework function stub functions:
api:
handler: src/handler.main
timeout: 29
memorySize: 512
environment:
TABLE_NAME: ${self:custom.tableName}
events:
- httpApi:
path: /items/{id}
method: get Keep HTTP timeout (29s) below API Gateway 30s limit.
Common mistakes Creating new database connections on every invocation instead of reusing global clients. Setting callbackWaitsForEmptyEventLoop true with open HTTP agents, delaying freeze and billing. Granting Lambda roles broad s3:* or dynamodb:* instead of resource-scoped policies. Ignoring async invocation failures without DLQ or CloudWatch alarms. Key takeaways Export async handler; parse API Gateway event fields for HTTP APIs. Reuse SDK clients and secrets cache in global scope to reduce cold-start work. Right-size memory and timeout; memory increases CPU allocation. Layers share dependencies; IAM roles must follow least privilege per function.
Pro Tip
Enable Lambda Power Tuning (open-source tool) to find the memory sweet spot where duration drops enough to offset higher per-ms cost.
Common Lambda Mistakes Go to next item