Serverless computing is one of the biggest shifts in how developers build and deploy applications. With AWS Lambda, you write code and AWS handles everything else — the servers, the operating system, scaling, and availability. You pay only when your code runs, billed in milliseconds. No idle server costs. This guide demystifies Lambda and shows you how to build your first serverless function.
What Is Serverless?
Despite the name, serverless doesn't mean there are no servers. It means you don't manage them. AWS provisions the compute infrastructure, keeps it patched and available, and scales it automatically from zero to thousands of concurrent executions. You focus entirely on your application logic.
How AWS Lambda Works
Lambda executes your code in response to triggers — events from other AWS services or HTTP requests via API Gateway. Each execution is called an invocation. Lambda spins up a runtime environment, runs your function, and tears it down. You are billed only for the execution duration and number of invocations.
Supported Runtimes
- Node.js (20.x, 18.x)
- Python (3.12, 3.11, 3.10)
- Java (21, 17, 11)
- Go (1.x via provided.al2023)
- Ruby (3.3)
- Custom runtimes via container images (up to 10 GB)
Lambda Free Tier
Lambda has one of the most generous always-free tiers on AWS:
- 1 million free requests per month, every month
- 400,000 GB-seconds of compute time per month
A function using 128 MB of memory running for 1 second = 0.125 GB-seconds. You can run that 3.2 million times per month for free.
Creating Your First Lambda Function
In the AWS Console, go to Lambda > Create function. Choose Author from scratch, name it hello-world, and select Python 3.12 as the runtime.
# Simple Python Lambda function
import json
def lambda_handler(event, context):
name = event.get("name", "World")
return {
"statusCode": 200,
"body": json.dumps({"message": f"Hello, {name}!"})
}
Click Deploy, then Test. Create a test event with {"name": "Alice"} and run it. You'll see the response and execution logs immediately.
Deploying Lambda via the AWS CLI
# Package your function code
zip function.zip lambda_function.py
# Create the Lambda function
aws lambda create-function
--function-name hello-world
--runtime python3.12
--role arn:aws:iam::YOUR_ACCOUNT_ID:role/LambdaBasicRole
--handler lambda_function.lambda_handler
--zip-file fileb://function.zip
# Invoke the function
aws lambda invoke
--function-name hello-world
--payload '{"name": "Alice"}'
--cli-binary-format raw-in-base64-out
response.json
cat response.json
Common Lambda Triggers
- API Gateway / Function URL — Expose Lambda as an HTTP endpoint
- S3 — Trigger on file uploads (e.g. resize images, process CSVs)
- DynamoDB Streams — React to database changes in real time
- SQS — Process messages from a queue (great for async workloads)
- EventBridge (CloudWatch Events) — Run Lambda on a schedule (cron jobs)
- SNS — Fan-out notifications to multiple Lambda functions
Environment Variables and Configuration
# Set environment variables for your Lambda function
aws lambda update-function-configuration
--function-name hello-world
--environment "Variables={DB_HOST=mydb.cluster.amazonaws.com,STAGE=prod}"
Access these in your code via os.environ["DB_HOST"] in Python or process.env.DB_HOST in Node.js. For sensitive values like passwords, use AWS Secrets Manager or SSM Parameter Store instead of environment variables.
Lambda Limits to Know
- Timeout: Maximum 15 minutes per invocation
- Memory: 128 MB to 10,240 MB (CPU scales proportionally)
- Deployment package: 50 MB zipped, 250 MB unzipped (10 GB with containers)
- Concurrent executions: 1,000 per region by default (can be increased)
- Ephemeral storage (/tmp): 512 MB to 10,240 MB
Lambda Best Practices
- Keep functions small and single-purpose
- Initialize SDK clients outside the handler for connection reuse
- Use environment variables for configuration
- Set a timeout appropriate to your workload (don't leave it at 3s default if you need 30s)
- Enable X-Ray tracing for distributed tracing and performance visibility
- Use Lambda Layers for shared dependencies across functions
Summary
AWS Lambda eliminates infrastructure management entirely. Whether you're building APIs, processing files, running scheduled jobs, or handling real-time events, Lambda lets you ship code faster with zero server overhead. Combined with API Gateway, S3, DynamoDB, and EventBridge, Lambda becomes the foundation of powerful, cost-efficient serverless architectures.
Frequently Asked Questions
- What is a "cold start" in AWS Lambda and how do I reduce it?
A cold start happens when Lambda must initialize a new execution environment before running your function — this includes downloading your code package, starting the runtime, and running any initialization code outside your handler. Cold starts add 100ms to several seconds of latency depending on runtime (Java and .NET are slower; Python and Node.js are fast). To reduce cold starts: use Provisioned Concurrency to keep execution environments warm for latency-sensitive functions; keep deployment packages small; initialize heavy resources (database connections, SDK clients) outside the handler function but inside the module-level code, so they are reused across invocations; and prefer lighter runtimes (Python, Node.js) for latency-sensitive workloads. - What is the maximum execution time for a Lambda function?
Lambda functions can run for a maximum of 15 minutes (900 seconds) per invocation. The default timeout is 3 seconds — easy to hit accidentally if your function makes network calls. Always set the timeout explicitly in your function configuration based on what your function actually does, with a reasonable buffer. For tasks that take longer than 15 minutes (large data processing, ML inference on big datasets), use AWS Batch, ECS Fargate, or Step Functions to orchestrate multiple Lambda invocations or longer-running containers. - How does Lambda pricing work?
Lambda charges on two dimensions: number of requests and duration. You pay $0.20 per million requests and $0.0000166667 per GB-second of execution time. The free tier includes 1 million requests and 400,000 GB-seconds per month, permanently — not just the first 12 months. Duration is measured in 1ms increments. A function configured with 128 MB that runs for 200ms per invocation at 1 million invocations costs approximately $0.33 per month. Memory allocation directly affects cost and performance — doubling memory also doubles cost per duration but can more than halve execution time for CPU-bound functions. - What is the difference between synchronous and asynchronous Lambda invocation?
With synchronous invocation (used by API Gateway, ALB, and direct SDK calls), the caller waits for the function to complete and receives the response. With asynchronous invocation (used by S3, SNS, EventBridge, and the--invocation-type EventSDK flag), Lambda places the event on an internal queue and returns immediately with a 202 response. Lambda retries asynchronous failures up to twice automatically. Choose synchronous for request/response APIs; choose asynchronous for event-driven pipelines where the caller does not need an immediate result.