What Makes Lambda Different from EC2
AWS Lambda runs your code in response to events without you provisioning or managing any server: you upload a function, AWS automatically provisions the underlying compute, executes your code in an isolated runtime environment, and scales the number of concurrent executions up or down based on incoming event volume — including scaling down to zero when there's no traffic, unlike an EC2 instance which keeps running (and billing) even when idle. Billing is based on the number of requests and the actual duration of each invocation measured in milliseconds, multiplied by the memory allocated to the function, which also proportionally determines the CPU power available during execution.
Cricket analogy: Lambda is like a stadium hiring a specific number of security staff only for the exact hours a match is being played, rather than paying full-time salaries for staff who stand around on non-match days, mirroring Lambda scaling to zero when idle.
Function Packaging, Handlers, and the Execution Environment
A Lambda function is defined by a handler — the specific method AWS invokes with an event payload and a context object — packaged either as a ZIP archive of code and dependencies or as a container image up to 10GB pushed to Amazon ECR, giving you flexibility for functions with large native dependencies like machine learning libraries. AWS reuses a 'warm' execution environment across consecutive invocations when possible to avoid repeatedly paying the initialization cost, but a 'cold start' occurs when Lambda must provision a brand-new environment — loading your code, initializing the runtime, and running any code outside the handler — which adds latency that matters most for latency-sensitive, user-facing APIs and can be mitigated with Provisioned Concurrency.
Cricket analogy: A cold start is like a substitute fielder coming on who first needs to warm up, stretch, and get positioned before being fully match-ready, versus a fielder already on the pitch, warm, who can react instantly to the next ball.
import json
def lambda_handler(event, context):
"""Triggered by an API Gateway HTTP request event."""
name = event.get("queryStringParameters", {}).get("name", "world")
body = {"message": f"Hello, {name}!", "request_id": context.aws_request_id}
return {
"statusCode": 200,
"headers": {"Content-Type": "application/json"},
"body": json.dumps(body),
}Triggers, Event Sources, and Execution Roles
Lambda functions are invoked by event sources such as API Gateway for HTTP APIs, S3 for object-created events, DynamoDB Streams for table change events, EventBridge for scheduled or rule-based events, and SQS for queue message processing, with each source delivering events either synchronously (the caller waits for a response, as with API Gateway) or asynchronously (Lambda queues the event and retries on failure, as with S3). Every function assumes an IAM execution role that grants it permission to interact with other AWS services — following least-privilege, a function that only reads from one specific S3 bucket should have a role scoped to exactly that bucket and action, not broad AmazonS3FullAccess, since the function's code inherits whatever permissions the role grants for the duration of each invocation.
Cricket analogy: An execution role scoped to least privilege is like a substitute fielder brought on only for boundary fielding duty, not handed the captain's authority to change the bowling attack — permissions matched exactly to the specific job needed.
Lambda functions have a maximum execution timeout of 15 minutes, and memory can be configured from 128 MB up to 10,240 MB in 1 MB increments; since CPU allocation scales proportionally with memory, increasing memory can sometimes reduce total cost by finishing the same work faster even though the per-millisecond rate is higher.
Never grant a Lambda execution role broader permissions than the function actually needs (e.g., avoid wildcard resources like "*" in IAM policies) — because the function's code runs with the full authority of its role for the entire invocation, an overly permissive role turns any code injection or dependency vulnerability into a much larger blast radius across your AWS account.
- Lambda runs code in response to events with no server provisioning, scaling automatically down to zero when idle.
- Billing is based on number of requests plus execution duration in milliseconds multiplied by allocated memory.
- Functions are packaged as ZIP archives or container images up to 10GB, invoked via a defined handler method.
- Cold starts occur when a new execution environment must be provisioned; Provisioned Concurrency mitigates this for latency-sensitive workloads.
- Event sources like API Gateway, S3, DynamoDB Streams, and EventBridge invoke functions either synchronously or asynchronously.
- Every function assumes an IAM execution role, and that role should follow least-privilege scoping to specific resources and actions.
- Maximum execution timeout is 15 minutes, with memory configurable from 128 MB to 10,240 MB, proportionally affecting CPU power.
Practice what you learned
1. How does AWS Lambda billing fundamentally differ from EC2 On-Demand billing?
2. What causes a Lambda 'cold start'?
3. Why should a Lambda execution role follow least-privilege principles?
4. Which statement about Lambda event source invocation is correct?
Was this page helpful?
You May Also Like
EC2 Fundamentals
Learn what Amazon EC2 is, how virtual server instances work in the cloud, and how to launch, connect to, and manage them safely.
Elastic Load Balancing
Learn how AWS Elastic Load Balancing distributes traffic across healthy targets, and the differences between Application, Network, and Gateway Load Balancers.
Auto Scaling Groups
Learn how EC2 Auto Scaling Groups automatically add and remove instances based on demand, using launch templates, scaling policies, and health checks.