Imagine hiring someone who only works exactly when needed, bills you per second of work, and never complains about overtime.
That's AWS Lambda.
You write a function. Upload it. It sits dormant costing you nothing. Then something triggers it — an API call, a file upload, a scheduled time — and it springs to life, does its job, and goes back to sleep.
You pay only for the seconds it ran. If nobody uses it for a month, you pay nothing.
This is serverless computing at its finest. And once you get it, you'll start seeing Lambda-shaped solutions everywhere.
New to AWS? Start with AWS for beginners to understand core services first. Or dive into serverless computing concepts to understand the bigger picture.
What Exactly Is AWS Lambda?
Lambda is AWS's serverless compute service. You give it code, and it runs that code in response to events.
No servers to manage. No operating systems to update. No scaling to configure. Just code.
Think of it like hiring a boda boda rider instead of buying a motorcycle:
- You don't own the bike (no server)
- You don't maintain it (no ops)
- You only pay when you actually ride (pay-per-execution)
- The rider handles everything else (AWS handles infrastructure)
How Lambda Actually Works
Here's the flow:
1. You write a function
Could be Node.js, Python, Java, Go, Ruby, C#, or even custom runtimes. Just a regular function that does something.
2. You upload it to Lambda
Either through the AWS console, CLI, or as part of your deployment pipeline.
3. You configure a trigger
What makes this function run?
- API Gateway request (someone hits an endpoint)
- S3 event (file uploaded)
- DynamoDB stream (database change)
- EventBridge schedule (cron job)
- SNS notification
- Dozens of other options
4. The trigger fires
Something happens (user clicks button, file gets uploaded, time hits 3 AM, etc.)
5. Lambda executes your function
AWS spins up a container, runs your code, returns the result.
6. Lambda shuts down
Function finishes. Container goes dormant. You stop getting charged.
Entire execution might take 200 milliseconds. You pay for 200 milliseconds of compute time.
Real-World Lambda Use Cases
1. API Backends
Build your entire API using Lambda + API Gateway. Each endpoint is a Lambda function.
User hits /users/create? Lambda function runs, creates user, returns response.
No servers to manage. Scales automatically.
See a complete implementation in building serverless APIs with Lambda and Node.js.
2. Image Processing
User uploads a profile picture to S3. This triggers a Lambda function that:
- Resizes the image
- Creates thumbnails
- Optimizes for web
- Saves the processed versions
All happens automatically. No cron jobs. No background workers.
3. Scheduled Jobs
Run tasks at specific times. Daily reports. Data cleanup. Backups.
Set up a CloudWatch Event to trigger your Lambda at 2 AM every day. Done.
4. Real-Time File Processing
CSV uploaded? Lambda parses it and imports to database.
Video uploaded? Lambda starts a transcoding job.
Invoice generated? Lambda emails it to the customer.
5. Chatbots and Webhooks
External service sends a webhook. Lambda receives it, processes it, does something.
Slack bot? Lambda. WhatsApp bot? Lambda. Payment notification? Lambda.
6. Data Transformation
Move data between services. Transform formats. Sync databases.
Lambda sits between systems and acts as the glue code.
Why Lambda Is Awesome
1. Zero Server Management
You literally never think about servers. AWS handles everything.
No SSH. No software updates. No security patches. No capacity planning.
2. Automatic Scaling
One user? One Lambda invocation.
One million users? One million concurrent Lambda invocations.
It scales instantly, automatically, without you doing anything.
3. Pay-Per-Use Pricing
You're billed by:
- Number of requests
- Duration of execution (rounded up to nearest millisecond)
- Memory allocated
No execution = no cost.
4. Huge Free Tier
AWS gives you:
- 1 million free requests per month
- 400,000 GB-seconds of compute time
For most side projects and small apps, Lambda is basically free.
5. Integrates With Everything
Lambda connects natively to almost every AWS service. And non-AWS services via API calls.
Building blocks that snap together easily.
Why Lambda Can Be Frustrating
1. Cold Starts (The Annoying Wait)
When a Lambda function hasn't run in a while, AWS needs to initialize it. This takes time — anywhere from 100ms to several seconds.
For the next few requests, it's fast (warm start). But that initial cold start can be noticeable.
Mitigation: Keep functions warm with periodic pings. Or pay for "provisioned concurrency" (defeats the pay-per-use model, but eliminates cold starts).
2. Execution Time Limits
Lambda functions time out after 15 minutes max. Most are configured for much less (seconds to a few minutes).
Long-running jobs? Lambda's not the answer. Use EC2, ECS, or batch processing instead.
Compare Lambda with EC2 vs ECS vs Fargate for compute options.
3. Stateless Nature
Each invocation is independent. No shared memory between executions. Can't maintain persistent connections easily.
If you need state, store it externally (database, S3, ElastiCache, etc.).
4. Debugging Is Harder
Can't SSH into a Lambda function. Debugging is mostly reading CloudWatch logs and hoping they're helpful.
5. Vendor Lock-In
Your code might be portable, but the Lambda-specific setup (triggers, IAM roles, integrations) ties you to AWS.
Switching to another platform requires rework.
6. Cost Can Sneak Up on You
For low traffic, Lambda is incredibly cheap. For high-frequency invocations, costs can skyrocket.
A function that runs 100 million times a month with long execution time? That's expensive.
Writing Your First Lambda Function
Let's build a simple Lambda that resizes images uploaded to S3.
Step 1: Write the Function
Python example:
import boto3
from PIL import Image
import io
s3 = boto3.client('s3')
def lambda_handler(event, context):
# Get the bucket and key from the S3 event
bucket = event['Records'][0]['s3']['bucket']['name']
key = event['Records'][0]['s3']['object']['key']
# Download the image
image_obj = s3.get_object(Bucket=bucket, Key=key)
image = Image.open(io.BytesIO(image_obj['Body'].read()))
# Resize it
image.thumbnail((200, 200))
# Save to buffer
buffer = io.BytesIO()
image.save(buffer, 'JPEG')
buffer.seek(0)
# Upload thumbnail
thumbnail_key = f"thumbnails/{key}"
s3.put_object(Bucket=bucket, Key=thumbnail_key, Body=buffer)
return {
'statusCode': 200,
'body': f'Thumbnail created: {thumbnail_key}'
}
Step 2: Package It
Zip your code and any dependencies (like PIL/Pillow).
Step 3: Upload to Lambda
Via console or CLI:
aws lambda create-function \
--function-name ImageResizer \
--runtime python3.9 \
--zip-file fileb://function.zip \
--handler lambda_function.lambda_handler \
--role arn:aws:iam::YOUR_ACCOUNT:role/lambda-execution-role
Step 4: Configure Trigger
Set S3 bucket to trigger this Lambda on object creation.
Step 5: Test
Upload an image. Watch it auto-resize. Feel like a wizard.
Lambda Best Practices
1. Keep Functions Small and Focused
One function, one job. Don't create monolithic Lambda functions.
Easier to debug. Faster cold starts. Better reusability.
2. Minimize Package Size
Smaller deployment packages = faster cold starts.
Only include necessary dependencies.
3. Use Environment Variables
Store configuration (API keys, database URLs) in environment variables, not hardcoded.
For sensitive credentials, use AWS Secrets Manager instead of environment variables.
4. Set Appropriate Timeouts and Memory
Default timeout might be too short or too long. Adjust based on your function's needs.
More memory = more CPU = faster execution (but higher cost). Test to find the sweet spot.
5. Monitor with CloudWatch
Set up CloudWatch Logs. Track errors. Set alarms for failures.
You can't debug what you can't see.
6. Handle Errors Gracefully
Lambda will retry failed executions. Make sure your function is idempotent (safe to run multiple times).
7. Use Layers for Shared Dependencies
If multiple functions use the same libraries, put them in a Lambda Layer. Reduces duplication and package size.
Lambda Pricing (Real Numbers)
Free Tier (per month):
- 1 million requests
- 400,000 GB-seconds of compute
After Free Tier:
- 0.20 USD per 1 million requests
- 0.0000166667 USD per GB-second
Example:
Your function uses 512MB RAM and runs for 200ms average.
1 million executions:
- Requests: 1M * 0.20 USD = 0.20 USD
- Compute: 1M 0.2s 0.5GB * 0.0000166667 = 1.67 USD
Total: ~1.87 USD for 1 million executions.
Compare that to running a server 24/7 even when idle.
When NOT to Use Lambda
1. Long-Running Jobs
Anything over 15 minutes. Use ECS, Batch, or EC2 instead.
2. Persistent Connections
WebSockets, database connection pools, long-lived TCP connections. Lambda's not built for this.
3. Extremely Latency-Sensitive Apps
Cold starts matter. If every millisecond counts, Lambda might not be ideal.
4. High-Frequency, Predictable Traffic
If your function runs constantly at high volume, a dedicated server might be cheaper.
Lambda shines with unpredictable, bursty traffic.
The Bottom Line
AWS Lambda is a paradigm shift. You stop thinking about servers and start thinking about functions.
It's perfect for event-driven architectures, background jobs, API backends, and glue code between services.
It's not perfect for long-running tasks, persistent connections, or ultra-latency-sensitive workloads.
But for the right use case, Lambda is magic. Write code, deploy it, forget about infrastructure, and watch it scale effortlessly.
Takeaway: AWS Lambda lets you run code without managing servers. You write functions, set up triggers, and pay only for execution time. Perfect for APIs, image processing, scheduled jobs, webhooks, and event-driven architectures. Limitations include cold starts, 15-minute max execution, and stateless nature. Pricing is pay-per-use, making it nearly free for low-traffic apps and cost-effective for bursty workloads. Use it for short-lived, event-driven tasks — not long-running or persistent connection workloads.