Lambda vs EC2 in AWS
Lambda and EC2 are the two foundational compute services in AWS, and the decision between them shapes everything from your deployment process to your bill. This page covers the practical, technical details — actual limits, real cost comparisons, and the specific scenarios where each one is clearly the right choice.
Lambda’s actual limits — and what they mean
Lambda is not “just write a function and anything works.” It has hard limits that determine whether it fits your workload:
- Maximum execution timeout: 15 minutes. Hard ceiling. Non-negotiable. If your workload ever runs longer than 15 minutes — even occasionally — Lambda will fail those invocations. Budget in margin: don’t run 12-minute jobs on Lambda.
- Maximum memory: 10 GB. Lambda allocates vCPU proportionally to memory — more memory = more CPU. At 10 GB, you get 6 vCPUs. For most workloads this is adequate; for memory-intensive data processing it may not be.
- Ephemeral storage (/tmp): 10 GB. Lambda provides a /tmp directory for temporary files. It persists across invocations in a warm environment but is wiped when the environment is recycled. Don’t use it for durable storage.
- Concurrent executions: 1,000 per region (soft limit). Lambda scales by creating parallel execution environments. The default limit is 1,000 simultaneous executions per account per region — this can be raised, but it requires a support request.
- Deployment package size: 50 MB (ZIP) or 10 GB (container image). Lambda now supports container images up to 10 GB, which essentially removes the package size constraint for most applications.
- No persistent processes. Lambda does not run a daemon, a background thread that survives across invocations, or a listening socket. Each invocation is isolated (though execution environments can be reused in warm state).
Lambda vs EC2 technical comparison
| Dimension | Lambda | EC2 |
|---|---|---|
| Execution timeout | 15 minutes maximum | No limit |
| Max memory | 10 GB | Up to 24 TB (u-24tb1.metal) |
| Max vCPUs | 6 vCPUs (at 10 GB memory) | Up to 448 vCPUs (hpc6a.48xlarge) |
| Ephemeral storage | 10 GB (/tmp) | Depends on instance + attached EBS volumes |
| Persistent in-memory state | Not guaranteed — environments are recycled | Full — process runs continuously |
| Cold start latency | 100ms–3s depending on runtime | None once instance is running |
| Scaling speed | Seconds — Lambda scales instantly | 1–3 minutes for new EC2 instance via Auto Scaling |
| Pricing unit | Per invocation + per GB-second | Per second (most instance types) |
| OS access | None | Full SSH access, any OS |
| Container image support | Yes — up to 10 GB images | Yes — Docker, any container runtime |
Running a web server: how each approach works
Both Lambda and EC2 can serve HTTP traffic, but the architecture is completely different.
Lambda + API Gateway (or Function URLs): Your web framework (Flask, FastAPI, Express) is packaged as a Lambda function using an adapter like Mangum (for ASGI frameworks) or aws-lambda-powertools. API Gateway sits in front, receives HTTP requests, and translates them to Lambda invocation events. Each request is a separate invocation. The Lambda function starts, handles the request, returns a response, and stops. There’s no persistent server process. This is how FastAPI on Lambda works — the framework runs but each request is a cold function call.
EC2 + Load Balancer: You launch an EC2 instance, install your web server (nginx + gunicorn, Apache, Node.js), configure it to start on boot, and put an Application Load Balancer in front. The server process runs continuously, maintains a connection pool to your database, and can hold cached state in memory. A deploy means either connecting to the instance and restarting the process, or using Auto Scaling with a new launch template and rolling replacement.
The EC2 approach has more moving parts but allows persistent processes, connection pooling, and in-memory caching that Lambda cannot do. Lambda is simpler to deploy and scale but requires your application to be stateless.
Cost comparison: API handling 100K requests/day
Workload: 100,000 requests per day, 200ms average execution time, 512MB memory.
Lambda cost:
- Free tier: 1M invocations/month, 400,000 GB-seconds/month
- Invocations per month: 3,000,000 (100K/day × 30 days)
- Billable invocations: 3,000,000 − 1,000,000 = 2,000,000 × $0.0000002 = $0.40/month
- GB-seconds: 3,000,000 × 0.2s × 0.5GB = 300,000 GB-seconds
- Billable GB-seconds: 300,000 − 400,000 = 0 (covered by free tier)
- Total Lambda: ~$0.40/month (plus API Gateway costs: ~$3.50/month for 3M requests)
EC2 cost (t3.small On-Demand, 2 vCPU, 2GB RAM):
- $0.0208/hour × 720 hours = $14.98/month
At this scale Lambda + API Gateway wins at ~$4/month vs ~$15/month. But note:
- A t3.small Reserved Instance (1-year, no upfront) costs $8.76/month — the gap narrows
- EC2 can handle multiple services on one instance; Lambda can’t
- Lambda auto-scales to handle traffic spikes; a single t3.small has a ceiling
Scale to 10 million requests/day and Lambda costs approximately $57/month for invocations + $35/month for API Gateway = ~$92/month. A t3.medium On-Demand ($33/month) or Reserved ($18/month) may handle this load if the workload fits within 2 vCPU. At very high volume with substantial compute per request, EC2 wins.
When to use Lambda
Start with Lambda when: your workload is event-driven, runs in under 5 minutes (leave margin from the 15-minute limit), is stateless, and has variable or unpredictable traffic patterns. Lambda’s zero-management overhead means you spend time on code, not infrastructure.
Lambda is clearly right for: webhook handlers, API backends with moderate traffic, scheduled jobs (cron replacements), file processing triggers (resize an image when uploaded to S3), SQS/SNS message processors, and glue code between AWS services.
Lambda container images (up to 10 GB) largely eliminate the deployment package size constraint. If you’ve been avoiding Lambda because your application and dependencies are large, container images are the solution — you get Lambda’s execution model with full container flexibility.
When to use EC2
Start with EC2 when: your workload runs longer than 15 minutes, requires persistent in-memory state, needs specific hardware (GPU, high-memory), or runs an application not suited for event-driven invocation.
EC2 is clearly right for: background worker daemons that run continuously, WebSocket servers maintaining persistent connections, database servers, build servers, game servers, and machine learning inference services where you need a model loaded in memory at all times.
EC2 with Spot Instances is underused for batch workloads. A scraping job, data transformation pipeline, or video encoding task that takes 30–60 minutes should run on Spot EC2 — you get the cost efficiency of paying only for execution time (Spot can be 60–90% cheaper than On-Demand) without Lambda’s time constraints.
See Spot Instances for how to run batch workloads on Spot with low cost and fault tolerance.
Quick decision guide
- Choose Lambda if: your workload runs in under 15 minutes, is stateless, is event-driven, and you don’t need persistent in-memory state or OS-level access.
- Choose EC2 if: your workload runs longer than 15 minutes, needs a persistent process, requires specific hardware, or involves a legacy application that isn’t cloud-native.
- Cost check: at low-to-moderate traffic, Lambda is almost always cheaper once you account for managed infrastructure. At very high sustained throughput, run the numbers — Reserved EC2 may win.
- Don’t treat “cold starts” as a blocker unless you have measured latency requirements. For most APIs with regular traffic, warm Lambda environments handle requests with sub-10ms overhead.
Frequently asked questions
What is Lambda's maximum execution timeout?
Lambda has a hard maximum timeout of 15 minutes (900 seconds). You configure this per function. The default is 3 seconds — increase it for longer-running functions. If your workload runs longer than 15 minutes, Lambda is the wrong service regardless of other factors.
Can Lambda run a web server?
Lambda can handle HTTP requests through API Gateway or Lambda Function URLs, but it does not run a persistent web server process. Each request invokes a separate Lambda execution. Lambda does support container images, so you can package a web framework like FastAPI or Express, but the execution model is still one invocation per request — not a persistent server process.
What happens when a Lambda function cold starts?
A cold start occurs when Lambda must initialize a new execution environment because no warm environment is available. AWS downloads your code/image, starts the runtime, and runs your initialization code (code outside the handler). This typically adds 100–500ms for Node.js/Python, and 1–3 seconds for Java/.NET. Subsequent requests to a warm environment have no cold start overhead.