AWS Lambda: The Complete Guide β From Zero to Expert

AWS Lambda is one of the most widely used services in modern cloud and DevOps architectures β but many engineers still struggle to understand when to actually use it.
Should you use Lambda or EC2?
When does serverless make sense?
What are the real-world scenarios?
In this guide, weβll go from zero to advanced β covering how Lambda works, when to use it, key configurations, and production-grade patterns like API Gateway integration and SAM templates.
By the end, youβll not just understand Lambda β youβll know how to use it in real systems.
Lambda vs EC2: When to Use What
EC2 gives you full control over virtual servers β OS, networking, storage, patching β while Lambda abstracts all of that away.β
| Feature | Lambda (Serverless) | EC2 (Server-based) |
|---|---|---|
| Management | AWS manages OS, patching, scaling | You manage everything |
| State | Stateless (ephemeral) | Stateful (persistent) |
| Pricing | Pay per request + duration (ms) | Pay per hour/second for provisioned capacity |
| Scaling | Automatic, instant | Manual or Auto Scaling Groups |
| Max Execution | 15 minutes | Unlimited |
| Control | Low | Full OS-level control |
When to Use Lambda
Event-driven workloads: S3 file uploads triggering processing, DynamoDB stream handlers
API backends: Lightweight REST/GraphQL APIs behind API Gateway
Scheduled tasks: Cron-like jobs (e.g., daily tenant reports like the
Daily-tenant-reportfunction in the screenshot)Chatbot/IoT processing: Handling Alexa skills, IoT device dataβ
Automation: Infrastructure tasks triggered by CloudTrail or Config rulesβ
When to Use EC2
Long-running processes (>15 minutes)
Stateful applications needing persistent memory
Legacy monolithic apps requiring specific OS configurations
GPU/specialized hardware workloadsβ
Hybrid Approach
Many organizations use both β Lambda for bursty, event-driven tasks and EC2 for steady-state workloads requiring fine-grained control.
Creating a Lambda Function (Step by Step)
Step by Step When you click Create function in the console, you see four options: β
Author from Scratch Start with a Hello World example. You pick a runtime (e.g., nodejs24.x, python3.12), name your function, and Lambda sets up a basic handler.
Use a Blueprint Pre-built sample code for common use cases β S3 thumbnail generation, DynamoDB processing, Kinesis stream readers. Great for learning.
Container Image Deploy your function as a Docker container image stored in Amazon ECR. More on this in the advanced section below.

Architecture: arm64 vs x86_64
When creating a function, you choose the instruction set architecture:
| Architecture | Description | Best For |
|---|---|---|
| x86_64 | Traditional Intel/AMD. Default option. | Compatibility with existing libraries |
| arm64 | AWS Graviton2 processors. Up to 20% cheaper and often faster. | Cost optimization, new workloads |
Scenario: If you're writing a Python-based daily report generator (like Daily-tenant-report), arm64 is an easy win β most Python packages support it and you save money.
Lambda Configuration Deep Dive
General Configuration
Memory: 128 MB to 10,240 MB. CPU scales proportionally with memory.
Timeout: 1 second to 15 minutes max.
Ephemeral storage (
/tmp): 512 MB to 10,240 MB for temporary files.
Environment Variables
Key-value pairs injected at runtime. Use them for:
Database connection strings
API keys (encrypted with KMS)
Feature flags
Stage identifiers (
prod,staging)
import os
DB_HOST = os.environ['DB_HOST']
API_KEY = os.environ['API_KEY']
Permissions (Execution Role)
Every Lambda function needs an IAM execution role. By default, Lambda creates one with CloudWatch Logs permissions. You add policies for whatever the function accesses β S3, DynamoDB, SQS, etc.
Scenario: Your Daily-tenant-report function needs to read from DynamoDB and send emails via SES β attach AmazonDynamoDBReadOnlyAccess and AmazonSESFullAccess policies to the execution role.
VPC Configuration
Connect your Lambda to a VPC to access private resources like RDS databases or ElastiCache. When enabled, Lambda creates ENIs in your specified subnets.
Trade-off: VPC-connected functions may have slightly longer cold starts, though AWS has significantly improved this.
Function URL
Assign an HTTPS endpoint directly to your Lambda β no API Gateway needed. Great for simple webhooks or internal tools.
Triggers
Lambda can be triggered by 200+ AWS services:
API Gateway (HTTP requests)
S3 (file events)
DynamoDB Streams (data changes)
SQS/SNS (messages)
EventBridge (scheduled/event rules)
CloudWatch (alarms)
Destinations
Configure where successful or failed async invocation results go β SQS, SNS, Lambda, or EventBridge.
Concurrency and Recursion Detection
Concurrency simply means:
π How many times your Lambda function can run at the same time
Reserved concurrency: Guarantees a set number of concurrent executions
Think of this as:
π βI want to reserve a fixed number of slots for my functionβ
Guarantees that your function always has capacity available
Prevents other functions from using all resources
π Example:
You set reserved concurrency = 10
Your function can run up to 10 times simultaneously
Even if the system is busy, these 10 slots are reserved for you
βοΈ Useful for:
Critical applications
Preventing overload on downstream systems (like databases)
Provisioned concurrency: Pre-initializes execution environments to eliminate cold starts
Normally, Lambda may take a little time to start (called cold start).
Provisioned concurrency means:
π βKeep some instances of my function already runningβ
Removes cold start delays
Improves response time
π Example:
You configure 5 provisioned instances
These are always ready β faster execution
βοΈ Useful for:
APIs
User-facing applications
Low-latency requirements
Recursion detection: Prevents infinite loops where Lambda triggers itself
This is a safety feature.
π Prevents your Lambda from calling itself again and again in a loop.
Code Signing
Ensures only trusted, signed code runs in your function. You create a Code Signing Configuration linking to an AWS Signer signing profile.β
Monitoring and Operations Tools
Lambda integrates with CloudWatch Logs, X-Ray (tracing), and CloudWatch Lambda Insights for performance monitoring.
Versions and Aliases
Versions
A version is an immutable snapshot of your function's code + configuration. When you publish a version, Lambda assigns it a number (1, 2, 3...). The $LATEST version is always mutable β it's your working copy.β
Scenario: You deploy v1 of Daily-tenant-report to production. You make changes and publish v2. If v2 has a bug, v1 still exists untouched.
Aliases
An alias is a named pointer (like prod, staging, dev) to a specific version.
aws lambda create-alias \
--function-name Daily-tenant-report \
--name prod \
--function-version 5
Why aliases matter: Your API Gateway integration points to the alias ARN, not a version number. When you deploy v6, just update the alias β no need to change API Gateway.β
Additional Resources Explained
Layers
A layer is a .zip archive containing libraries, custom runtimes, or other dependencies. Instead of bundling everything in your deployment package, you attach shared layers.β
Scenario: Multiple Lambda functions use the pandas library. Create one layer with pandas, attach it to all functions. Update the layer once, and all functions get the update.
Each layer version is immutable and identified by a unique ARN.β
Event Source Mappings (ESMs)
An ESM is a Lambda resource that polls stream/queue-based services and invokes your function with batches of records.
Supported sources: SQS, Kinesis, DynamoDB Streams, MSK (Kafka), Amazon MQ, DocumentDB.
Scenario: An SQS queue receives order events. An ESM polls the queue and invokes your Lambda with batches of 10 messages. You configure batch size, batching window, retry policies, and parallelization.β
Capacity Providers (New β Lambda Managed Instances)
This is a new feature that lets Lambda functions run on EC2 instances managed by Lambda, combining serverless development experience with dedicated compute.
You create a capacity provider specifying VPC, subnets, security groups, IAM roles, and optionally instance types and scaling config. Functions using capacity providers get access to specialized EC2 instance types while Lambda still handles scaling and patching.β
Use case: Workloads needing GPU instances or specific hardware that standard Lambda doesn't offer.β
Code Signing Configurations
Ensures deployment integrity β only code signed by approved developers/CI pipelines can be deployed to your functions.
Replicas
Lambda@Edge replicas β when you associate a Lambda function with CloudFront distributions, AWS replicates your function to edge locations globally for low-latency execution.
Container Image Functions (Deep Dive)
Instead of uploading a .zip file, you can package your Lambda function as a Docker container image (up to 10 GB uncompressed) stored in Amazon ECR.
Three Ways to Build Container Images
AWS base image: Pre-loaded with runtime + runtime interface client. Easiest approach.β
AWS OS-only base image: Amazon Linux with just the OS. You add your runtime. Used for Go, Rust, or custom runtimes.β
Non-AWS base image: Alpine, Debian, or any custom image. You must include a runtime interface client.β
Example Dockerfile (Python)
FROM public.ecr.aws/lambda/python:3.12
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY app.py .
CMD ["app.handler"]
Deploy a Container Image Function
# Build and push to ECR
docker build -t daily-report .
docker tag daily-report:latest 076829085184.dkr.ecr.us-east-1.amazonaws.com/daily-report:latest
docker push 076829085184.dkr.ecr.us-east-1.amazonaws.com/daily-report:latest
# Create Lambda function
aws lambda create-function \
--function-name Daily-tenant-report \
--package-type Image \
--code ImageUri=076829085184.dkr.ecr.us-east-1.amazonaws.com/daily-report:latest \
--role arn:aws:iam::076829085184:role/lambda-execution-role
When to Use Container Images vs .zip
Container images: Complex dependencies, large packages (ML models), existing Docker workflows, need for custom OS packages
.zip archives: Simple functions, quick iterations, smaller codebases
Important: You cannot change deployment type after creation β a container image function stays container, a .zip stays .zip.β
Function Lifecycle for Container Images
After uploading, Lambda optimizes the image (function is in Pending state). Once Active, it can receive invocations. If unused for weeks, it goes Inactive and requires re-optimization on next invocation.β
Advanced: SAM Template with API Gateway + Lambda
What is AWS SAM?
AWS SAM (Serverless Application Model) is a tool that helps you define and deploy serverless applications using simple configuration files.
Instead of manually creating:
Lambda functions
API Gateway
IAM roles
Event triggers
You can define everything in one file and deploy it together.
Think of SAM as:
βA simplified way to write CloudFormation specifically for serverless applications.β
Why use SAM?
Without SAM:
You manually create resources from AWS Console
Difficult to manage and replicate
With SAM:
Everything is written as code
Easy to version control
Easy to reuse across environments (dev, prod)
Step 1: Install SAM CLI
SAM CLI is the tool used to build and deploy your application.
# macOS
brew install aws-sam-cli
# Linux
pip install aws-sam-cli
Step 2: Initialize a SAM Project
sam init --runtime python3.12 --name daily-report-api
This creates a project structure like:
template.yaml β Main configuration file
hello_world/ β Lambda code
tests/ β Unit tests
events/ β Sample test events
Step 3: Understanding template.yaml
This is the most important file.
It defines:
Lambda functions
API endpoints
Database
Permissions
Basic Structure
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
This tells AWS:
This is a SAM template
Use serverless transformation
Globals Section
Globals:
Function:
Timeout: 30
Runtime: python3.12
Architectures:
- arm64
This applies default settings to all Lambda functions.
Meaning:
Every function will use Python 3.12
Timeout = 30 seconds
Architecture = arm64
This avoids repeating configuration again and again.
Lambda Function Definition
DailyTenantReportFunction:
Type: AWS::Serverless::Function
This creates a Lambda function.
Key Properties Explained
CodeUri: src/
Handler: app.lambda_handler
CodeUri β Where your code is located
Handler β Entry point of your function
MemorySize: 256
Allocates memory to Lambda
More memory = faster execution
Environment:
Variables:
DB_TABLE: TenantReports
STAGE: production
Environment variables for configuration
Used inside your code
Permissions (Policies)
Policies:
- DynamoDBReadPolicy:
TableName: !Ref TenantReportsTable
This allows Lambda to:
- Read from DynamoDB table
- SESCrudPolicy:
IdentityName: "reports@shipsy.io"
Allows Lambda to:
- Send emails using SES
Event Triggers (Very Important)
This is where SAM becomes powerful.
API Gateway Integration
Events:
GetReport:
Type: Api
Properties:
Path: /reports/{tenantId}
Method: get
This means:
Create API endpoint
When someone calls:
/reports/{tenantId}Lambda will run
Another API Endpoint
GenerateReport:
Type: Api
Properties:
Path: /reports/generate
Method: post
Now you have:
GET API β fetch report
POST API β generate report
Scheduled Trigger (Cron Job)
DailySchedule:
Type: Schedule
Properties:
Schedule: cron(0 6 * * ? *)
This runs Lambda:
- Every day at 6 AM UTC
This is similar to your current EventBridge setup.
DynamoDB Table
TenantReportsTable:
Type: AWS::DynamoDB::Table
This creates a database table.
KeySchema:
- AttributeName: tenantId
KeyType: HASH
- AttributeName: reportDate
KeyType: RANGE
tenantId β Partition key
reportDate β Sort key
BillingMode: PAY_PER_REQUEST
No need to manage capacity
Pay only when used
Outputs (Important)
Outputs:
ApiEndpoint:
Value: !Sub "https://\({ServerlessRestApi}.executeapi.\){AWS::Region}.amazonaws.com/Prod"
After deployment, this gives:
- Your API URL
Step 4: Build and Test Locally
sam build
- Prepares your application
sam local invoke DailyTenantReportFunction --event events/test.json
- Runs Lambda locally
sam local start-api
- Starts local API server
Test using:
curl http://localhost:3000/reports/tenant-123
Step 5: Deploy to AWS
sam deploy --guided
This will:
Ask for configuration (region, stack name)
Upload code to S3
Create all resources
After Deployment
You will get an API like:
https://abc123.execute-api.us-east-1.amazonaws.com/Prod/reports/{tenantId}
Example API Calls
curl https://.../reports/tenant-456
Fetch report
curl -X POST https://.../reports/generate \
-H "Content-Type: application/json" \
-d '{"tenantId": "tenant-456"}'
Generate report
Final Architecture
Client β API Gateway β Lambda β DynamoDB β Scheduled Event (cron)




