AWS Lambda — Serverless Functions, Triggers, and Execution Model
A full walkthrough of AWS Lambda — runtimes, triggers, execution environment, concurrency, VPC integration, layers, and real-world serverless patterns
What is Lambda?
AWS Lambda is a serverless compute service. You upload your code and Lambda runs it — no servers to provision, no OS to patch, no capacity to manage. Lambda executes your function in response to events and automatically scales from zero to thousands of concurrent executions.
You pay only for the time your function runs — billed in 1ms increments. If nobody calls your function, you pay nothing.
Core Concepts
| Term | Meaning |
|---|---|
| Function | Your code + configuration (runtime, memory, timeout, environment variables) |
| Handler | The entry point — the specific function Lambda calls when triggered |
| Event | The JSON payload passed to your function by the trigger |
| Context | Metadata about the invocation (request ID, remaining time, function name) |
| Execution environment | The isolated runtime sandbox Lambda uses to run your function |
| Trigger | The event source that invokes your function |
| Layer | A zip archive of libraries or dependencies shared across functions |
Supported Runtimes
| Runtime | Versions |
|---|---|
| Python | 3.9, 3.10, 3.11, 3.12 |
| Node.js | 18.x, 20.x |
| Java | 8, 11, 17, 21 |
| Go | 1.x (provided.al2023) |
| .NET | 6, 8 |
| Ruby | 3.2 |
| Custom runtime | Any language via bootstrap binary on Amazon Linux 2023 |
Function Configuration
📸 SCREENSHOT: Lambda → Functions → Create Function. Show the runtime dropdown, handler field (e.g.
index.handler), and the architecture selection (x86_64 / arm64).
Memory and Timeout
Memory: 128 MB to 10,240 MB (in 1 MB increments). CPU is allocated proportionally to memory — more memory = more CPU. Timeout: 1 second to 15 minutes maximum.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Create a Lambda function
aws lambda create-function \
--function-name my-processor \
--runtime python3.12 \
--handler lambda_function.lambda_handler \
--role arn:aws:iam::123456789012:role/lambda-execution-role \
--zip-file fileb://function.zip \
--memory-size 512 \
--timeout 30 \
--environment Variables='{DB_HOST=db.internal,LOG_LEVEL=INFO}'
# Update function code
aws lambda update-function-code \
--function-name my-processor \
--zip-file fileb://function.zip
# Update configuration
aws lambda update-function-configuration \
--function-name my-processor \
--memory-size 1024 \
--timeout 60
Handler Structure
Python example:
1
2
3
4
5
6
7
8
9
10
11
import json
def lambda_handler(event, context):
print(f"Event: {json.dumps(event)}")
print(f"Request ID: {context.aws_request_id}")
print(f"Remaining time: {context.get_remaining_time_in_millis()}ms")
return {
'statusCode': 200,
'body': json.dumps({'message': 'OK'})
}
Node.js example:
1
2
3
4
5
6
7
exports.handler = async (event, context) => {
console.log('Event:', JSON.stringify(event));
return {
statusCode: 200,
body: JSON.stringify({ message: 'OK' })
};
};
Triggers and Event Sources
Lambda functions are invoked by triggers. Each trigger type passes a different event structure.
API Gateway / ALB
The most common pattern — HTTP request triggers a Lambda function. API Gateway passes the full request (method, path, headers, body) as JSON.
📸 SCREENSHOT: Lambda → Function → Configuration → Triggers → Add Trigger. Show the API Gateway trigger selected, and the HTTP API created with an open endpoint.
1
Client → API Gateway → Lambda → response
S3 Events
Lambda triggered when objects are created, deleted, or modified in an S3 bucket. Use for image resizing, document processing, ETL pipelines.
1
2
3
4
5
6
7
8
{
"Records": [{
"s3": {
"bucket": {"name": "my-uploads"},
"object": {"key": "images/photo.jpg", "size": 1024}
}
}]
}
SQS
Lambda polls an SQS queue and processes messages in batches. Lambda scales out consumers automatically. Failed messages go back to the queue (or DLQ after max retries).
1
2
3
4
5
6
# Add SQS trigger
aws lambda create-event-source-mapping \
--function-name my-processor \
--event-source-arn arn:aws:sqs:eu-west-1:123456789012:my-queue \
--batch-size 10 \
--maximum-batching-window-in-seconds 5
EventBridge (Scheduled)
Run Lambda on a schedule — like cron in the cloud.
1
2
3
4
5
6
7
8
9
# Create a rule to run every 5 minutes
aws events put-rule \
--name every-5-minutes \
--schedule-expression "rate(5 minutes)"
# Add Lambda as the target
aws events put-targets \
--rule every-5-minutes \
--targets "Id=1,Arn=arn:aws:lambda:eu-west-1:123456789012:function:my-processor"
DynamoDB Streams and Kinesis
Lambda processes records from a stream in order. Used for change data capture, real-time analytics, event sourcing.
Common Trigger Summary
| Trigger | Invocation Type | Retry Behaviour |
|---|---|---|
| API Gateway / ALB | Synchronous | Client handles errors |
| S3 | Asynchronous | Lambda retries 2x, then DLQ |
| SQS | Event source mapping (poll) | Visibility timeout, DLQ |
| SNS | Asynchronous | Lambda retries 2x, then DLQ |
| DynamoDB Streams | Event source mapping | Retry until TTL or shards exhausted |
| EventBridge | Asynchronous | Lambda retries 2x, then DLQ |
| Cognito | Synchronous | No retry — must return response |
Invocation Types
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Synchronous — waits for response
aws lambda invoke \
--function-name my-processor \
--payload '{"key": "value"}' \
--cli-binary-format raw-in-base64-out \
response.json
# Asynchronous — fire and forget
aws lambda invoke \
--function-name my-processor \
--invocation-type Event \
--payload '{"key": "value"}' \
--cli-binary-format raw-in-base64-out \
response.json
Execution Environment and Cold Starts
When Lambda receives a request, it:
- Provisions an execution environment (OS, runtime, your code)
- Runs your handler
If a warm environment is available (recent invocation), it reuses it — warm start, fast. If no warm environment exists, Lambda initialises a new one — cold start, adds 100ms–1000ms latency.
Cold Start Causes
- Function hasn’t been called recently (environment recycled)
- New deployment
- Concurrency spike — Lambda needs new environments
Reducing Cold Starts
- Provisioned Concurrency — pre-warm N execution environments, always ready
- Smaller deployment packages (less to load)
- Use arm64 architecture (Graviton2) — ~10-20% better performance and lower cost
- Avoid VPC for functions that don’t need it (VPC adds ~1-2s cold start for ENI attachment)
1
2
3
4
5
# Configure provisioned concurrency
aws lambda put-provisioned-concurrency-config \
--function-name my-processor \
--qualifier prod \
--provisioned-concurrent-executions 10
Concurrency
Concurrency is the number of function instances running simultaneously.
| Concurrency Type | Description |
|---|---|
| Unreserved | Shared pool across all functions in the account (default: 1000 per region) |
| Reserved | Guaranteed concurrency for a specific function — takes from shared pool |
| Provisioned | Pre-warmed environments — eliminates cold starts |
1
2
3
4
# Reserve 100 concurrent executions for critical function
aws lambda put-function-concurrency \
--function-name my-critical-function \
--reserved-concurrent-executions 100
📸 SCREENSHOT: Lambda → Function → Configuration → Concurrency. Show the reserved concurrency field set to 100, and the note about removing from the account pool.
IAM Execution Role
Every Lambda function needs an execution role — an IAM role that defines what AWS services the function can call.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
Minimum permissions every Lambda needs: logs:CreateLogGroup, logs:CreateLogStream, logs:PutLogEvents. Without these, your function runs but you cannot see any logs.
Lambda Layers
A layer is a zip archive containing libraries, a custom runtime, or data files. Multiple functions can share the same layer — you package dependencies once and reference them from any function.
1
2
3
4
5
6
7
8
9
10
# Publish a layer
aws lambda publish-layer-version \
--layer-name python-requests \
--zip-file fileb://requests-layer.zip \
--compatible-runtimes python3.11 python3.12
# Attach layer to a function
aws lambda update-function-configuration \
--function-name my-processor \
--layers arn:aws:lambda:eu-west-1:123456789012:layer:python-requests:3
Functions can use up to 5 layers simultaneously. Total unzipped size of function + layers must be under 250 MB.
VPC Integration
By default Lambda runs outside your VPC — it can reach the internet but not private resources (RDS, ElastiCache, internal services). You can attach Lambda to a VPC to give it access to private subnets.
Attaching to a VPC increases cold start time (Lambda must attach an ENI). Only put Lambda in a VPC when it actually needs to reach private resources.
1
2
3
aws lambda update-function-configuration \
--function-name my-processor \
--vpc-config SubnetIds=subnet-private-1a,subnet-private-1b,SecurityGroupIds=sg-lambda
When Lambda is in a VPC and needs internet access (to call external APIs), route its outbound traffic through a NAT Gateway — Lambda in a private subnet, NAT Gateway in a public subnet.
Destinations and Dead Letter Queues
For asynchronous invocations, you can configure:
- On success destination — SNS, SQS, EventBridge, or another Lambda
- On failure destination — same options
- Dead Letter Queue (DLQ) — SQS or SNS for failed events after retries
1
2
3
4
5
6
7
aws lambda put-function-event-invoke-config \
--function-name my-processor \
--maximum-retry-attempts 1 \
--destination-config '{
"OnSuccess": {"Destination": "arn:aws:sqs:...:success-queue"},
"OnFailure": {"Destination": "arn:aws:sqs:...:dlq"}
}'
Monitoring and Observability
Lambda automatically sends metrics to CloudWatch:
Invocations,Errors,Throttles,Duration,ConcurrentExecutions
Lambda automatically sends logs to CloudWatch Logs — each print() or console.log() appears there.
Enable X-Ray tracing to see end-to-end latency across Lambda → downstream services.
1
2
3
4
# Enable X-Ray active tracing
aws lambda update-function-configuration \
--function-name my-processor \
--tracing-config Mode=Active
📸 SCREENSHOT: CloudWatch → Log Groups → /aws/lambda/my-processor. Show the log streams list, then click into one stream to show a cold start init log line followed by function output.
Pricing
Lambda pricing has two components:
| Component | Price |
|---|---|
| Requests | $0.20 per 1 million requests (first 1M/month free) |
| Duration | $0.0000166667 per GB-second (first 400,000 GB-seconds/month free) |
GB-seconds = memory allocated (in GB) × execution duration (in seconds).
Example: a 512 MB function running for 200ms = 0.5 GB × 0.2s = 0.1 GB-second. At 1 million invocations per day = ~100,000 GB-seconds/day — well within the free tier initially, then fractions of a cent.
arm64 (Graviton) functions are ~20% cheaper than x86_64.
Real-World Patterns
Pattern 1 — REST API backend
1
Client → API Gateway → Lambda → DynamoDB
Completely serverless API. Lambda handles each request, scales to zero when idle.
Pattern 2 — S3 event processing
1
Upload to S3 → S3 Event → Lambda → resize image → save to S3 output bucket
Image resizer, PDF processor, virus scanner.
Pattern 3 — Scheduled jobs
1
EventBridge rule (cron) → Lambda → clean up database / send report / sync data
Replaces traditional cron jobs on EC2.
Pattern 4 — SQS worker
1
Producer → SQS queue → Lambda (batch processor) → downstream service
Decoupled, scalable message processing. Lambda scales consumers automatically based on queue depth.
Quick Reference
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# List functions
aws lambda list-functions --output table
# Invoke a function
aws lambda invoke \
--function-name my-processor \
--payload '{}' \
--cli-binary-format raw-in-base64-out \
/tmp/response.json && cat /tmp/response.json
# View recent logs
aws logs tail /aws/lambda/my-processor --follow
# Get function configuration
aws lambda get-function-configuration --function-name my-processor
# List event source mappings (SQS/Kinesis/DynamoDB triggers)
aws lambda list-event-source-mappings --function-name my-processor
# Delete a function
aws lambda delete-function --function-name my-processor