AWS Lambda — Complete Serverless Computing Guide
AWS Lambda is a serverless compute service that runs your code in response to events and automatically manages the underlying compute resources — you upload code, and AWS handles everything else: servers, scaling, and maintenance.
What You’ll Learn
By the end of this tutorial, you’ll write Lambda function handlers in Node.js and Python, connect them to event sources (API Gateway, S3, DynamoDB Streams), use environment variables and layers for configuration, monitor performance with CloudWatch, and apply best practices for production serverless applications.
Why AWS Lambda Matters
Lambda eliminates server management. No EC2 instances to patch, no auto-scaling groups to configure, no load balancers to maintain. You pay only for the compute time you consume — measured in milliseconds. DodaTech uses Lambda for Durga Antivirus Pro’s file scanning API: when a user uploads a file, Lambda processes it instantly without maintaining a fleet of servers.
AWS Lambda Learning Path
flowchart LR
A[Cloud Basics] --> B[AWS Lambda]
B --> C[API Gateway + Lambda]
B --> D[S3 + Lambda]
B --> E[DynamoDB + Lambda]
C --> F[Serverless Applications]
style B fill:#3b82f6,stroke:#fff,color:#fff
What is Serverless? — The Vending Machine Analogy
Imagine you want to serve coffee:
- Traditional (EC2): You buy a coffee machine (server), install it, maintain it, clean it daily, and it runs 24/7 — even when nobody wants coffee. You pay for the machine whether you use it or not.
- Serverless (Lambda): You call a vending machine company. The vending machine appears when someone orders coffee, dispenses it, and disappears. You pay only for each cup served. No maintenance, no idle costs.
This is AWS Lambda. Your code runs only when triggered, scales automatically to handle millions of requests, and you never pay for idle capacity.
Your First Lambda Function — Node.js Handler
// Node.js handler (index.js)
exports.handler = async (event) => {
// Parse the incoming request body
const { name } = JSON.parse(event.body);
// Return a formatted HTTP response
return {
statusCode: 200,
body: JSON.stringify({ message: `Hello, ${name}!` }),
headers: { "Content-Type": "application/json" }
};
};Line-by-line explanation:
exports.handler— Lambda looks for this exported function. It’s the entry point.async (event)— the function is async (returns a Promise).eventcontains the trigger data — HTTP request details, S3 file info, etc.JSON.parse(event.body)— for API Gateway triggers, the body is a JSON string. We parse it to access the data.statusCode: 200— HTTP status code. 200 = success.body: JSON.stringify(...)— the response payload must be a string. We convert the object.headers— tells the client the response format.
Python Handler
# Python handler (lambda_function.py)
import json
def lambda_handler(event, context):
name = json.loads(event["body"]).get("name", "World")
return {
"statusCode": 200,
"body": json.dumps({"message": f"Hello, {name}!"}),
"headers": {"Content-Type": "application/json"}
}Line-by-line:
def lambda_handler(event, context)— Lambda’s Python entry point.event= input data.context= runtime info (function name, timeout, etc.).json.loads(event["body"]).get("name", "World")— parse the JSON body and getname, defaulting to “World” if missing.json.dumps(...)— convert the response dict back to a JSON string.
Common Event Sources
Lambda can be triggered by many AWS services:
- API Gateway — HTTP requests → REST API backend
- S3 — File uploads → image resizing, video transcoding
- DynamoDB Streams — Database changes → data sync, notifications
- SQS/SNS — Queue/notification messages → async processing
- CloudWatch Events — Scheduled tasks (cron jobs)
- Cognito — User authentication → custom auth logic
API Gateway + Lambda — REST API
flowchart LR
A[Client] --> B[API Gateway]
B --> C[Lambda Function]
C --> D[DynamoDB / S3 / etc.]
- Create a Lambda function (your business logic)
- Create an API Gateway REST API
- Connect a route (e.g.,
GET /users) to your Lambda - Deploy — you now have a scalable REST API
Environment Variables
Store configuration outside your code:
# In Lambda console → Environment variables:
DB_TABLE=prod-users
STAGE=production
LOG_LEVEL=info// Access in code
const tableName = process.env.DB_TABLE;Why env vars? You can promote code through dev → staging → prod by changing env vars, not code. No hardcoded credentials, no config files.
Layers — Shared Dependencies
Layers package shared libraries across functions:
# Create a layer (zip dependencies)
mkdir python
pip install requests -t python/
zip -r requests-layer.zip python/
# Upload to Lambda → Layers
# Attach to functions — now requests is availableWhy layers? Without layers, you’d bundle dependencies in every deployment package. Layers reduce upload size, speed up deployments, and let you share common code (like SDKs or utility libraries) across functions.
Monitoring & Logging
Lambda automatically sends logs to CloudWatch:
# View logs
aws logs describe-log-groups --log-group-name-prefix /aws/lambda/my-function
aws logs tail /aws/lambda/my-function --follow
# Set up CloudWatch alarms
# - Error count > 0 in 5 minutes
# - Duration > 80% of timeout
# - Throttles > 0Best Practices
- Single responsibility — one function = one job. Don’t create a monolith Lambda
- Set appropriate timeout — default is 3 seconds. API functions may need 10-30s
- Set appropriate memory — more memory = more CPU. Test with 512MB-1GB
- Use environment variables — never hardcode configuration
- Implement structured logging — use JSON logs for CloudWatch Insights
- Enable X-Ray tracing — debug performance bottlenecks
- Use DLQs — Dead Letter Queues catch failed invocations
Common Mistakes
1. Setting timeout too low
Lambda’s default timeout is 3 seconds. If your function calls external APIs or processes large files, it will timeout and fail silently. Set timeout based on actual performance testing.
2. Forgetting IAM permissions
Lambda needs explicit permissions to access other AWS services. If DynamoDB calls fail, check the execution role — not your code.
3. Bundling unnecessary dependencies
A function with 50MB of node_modules takes longer to deploy and cold-start. Use layers for shared dependencies and exclude dev dependencies.
4. Hardcoding configuration
Database names, bucket names, and API URLs change between environments. Use environment variables and parameter store instead.
5. Not handling idempotency
Lambda may retry failed invocations. If your function processes payments or sends emails, ensure it can handle duplicates safely.
6. Ignoring cold starts
When a function hasn’t been invoked for a while, Lambda initializes it from scratch — adding latency. For latency-sensitive apps, use Provisioned Concurrency.
Practice Questions
1. What is the difference between serverless (Lambda) and traditional EC2 hosting?
Answer: EC2 requires manual server management, patching, and scaling — you pay for uptime. Lambda runs code on-demand, auto-scales, and you pay only for execution time in milliseconds.
2. How does a Lambda function receive input from API Gateway?
Answer: API Gateway sends the HTTP request as a JSON event object containing headers, body, query parameters, and path parameters.
3. What are Lambda layers and when should you use them?
Answer: Layers package shared dependencies (libraries, SDKs) across multiple functions. Use them to reduce deployment package size and avoid duplicating dependencies.
4. Why should you set up CloudWatch alarms for Lambda?
Answer: Alarms notify you of errors, throttles, or high duration — catching issues before they affect users. Without monitoring, failures go unnoticed.
Challenge
Build a serverless image thumbnail generator: an S3 bucket triggers a Lambda function on file upload, which resizes the image using Sharp (Node.js) and saves the thumbnail to another S3 bucket. This is a real-world pattern used by photo-sharing apps.
FAQ
Try It Yourself
Create and test your first Lambda function:
# 1. Go to AWS Console → Lambda → Create function
# 2. Choose "Author from scratch"
# 3. Name: hello-world
# 4. Runtime: Node.js 20.x
# 5. Create function
# 6. Replace the code with:
exports.handler = async (event) => {
const name = event.queryStringParameters?.name || "World";
return {
statusCode: 200,
body: JSON.stringify({ message: `Hello, ${name}!` }),
headers: { "Content-Type": "application/json" }
};
};
# 7. Click "Test" → create a test event
# 8. Run it — see the response
# 9. Add API Gateway trigger
# 10. Deploy API → get a public URL
# 11. Visit: https://your-api-id.execute-api.region.amazonaws.com/default/hello-world?name=DodaTechWhat’s Next
Explore more AWS services:
| Topic | Description |
|---|---|
| https://tutorials.dodatech.com/devops/cloud/aws/reference/ | AWS services quick reference |
| https://tutorials.dodatech.com/devops/cloud/cpanel/ | cPanel hosting management |
Related topics to explore:
- AWS Cloud Services
- DevOps Deployment
- Node.js Development
- Python Development
What’s Next
Congratulations on completing this Lambda tutorial! Here’s where to go from here:
- Practice daily — Consistency is more important than long study sessions
- Build a project — Apply what you learned by building something real
- Explore related topics — Check out other tutorials in the same category
- Join the community — Discuss with other learners and share your progress
Remember: every expert was once a beginner. Keep coding!
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro