Serverless vs Virtual Machines in AWS
Lambda and EC2 are both compute services in AWS, but they represent fundamentally different approaches to running software. Choosing the wrong one means either paying for idle servers or hitting hard limits at the worst moment.
What actually separates them
With EC2, you launch a virtual machine. It runs 24/7 whether your code is executing or not. You choose the OS, install your runtime, configure networking, and handle scaling yourself (or with Auto Scaling). The machine persists until you terminate it.
With Lambda, you write a function. AWS runs it when an event triggers it — an HTTP request, a file upload to S3, a message in a queue — and stops it when the function returns. You never provision a server, never SSH in, never patch an OS. If 10,000 requests arrive simultaneously, AWS scales Lambda to handle them automatically.
The difference is not just operational — it changes how you think about billing, architecture, and failure modes.
Lambda vs EC2 at a glance
| Dimension | Lambda | EC2 |
|---|---|---|
| Pricing model | Per invocation + per GB-second of execution | Per hour (On-Demand) or per second for some instance types |
| Startup time | Milliseconds to seconds (cold start); sub-millisecond (warm) | 60–90 seconds to launch a new instance |
| Max execution time | 15 minutes hard limit | No limit — runs as long as you want |
| Infrastructure management | None — AWS handles everything | Full — OS, patches, runtime, scaling |
| Scaling behavior | Automatic, to thousands of concurrent executions | Manual or via Auto Scaling Groups (minutes to scale out) |
| Max memory | 10 GB | Up to 24 TB (u-24tb1.metal) |
| Persistent state | Not supported in function memory — use external storage | Full in-memory state, local disk, whatever you need |
| OS / runtime control | Limited to AWS-provided runtimes or container images | Full control — any OS, any kernel, any runtime |
When Lambda is the right answer
Lambda wins in these situations:
Event-driven workloads. If your code runs in response to something — an HTTP request, a file upload, a scheduled cron job, a message in a queue — Lambda is purpose-built for this. You pay only when the code actually runs.
Variable or unpredictable traffic. A Lambda function handles a single request per day or a million requests per day without any configuration changes. EC2 requires you to provision for peak or manage Auto Scaling with a warmup delay.
Rapid deployment. No AMIs to build, no servers to configure. Deploying a new Lambda function is uploading a ZIP file. This matters for teams that deploy frequently.
Glue and integration code. Small functions that transform data between services, trigger notifications, validate inputs, or route events are exactly what Lambda is designed for. The overhead of managing an EC2 instance for 50 lines of glue code is not worth it.
Short background tasks. Image resizing, email sending, webhook processing, PDF generation — tasks that complete in seconds and can tolerate a small cold-start delay are Lambda’s home turf.
See Lambda overview for more on how Lambda executions work.
When EC2 is the right answer
Long-running processes. Lambda’s hard limit is 15 minutes. Any workload that exceeds that — or comes close enough that you’re nervous — belongs on EC2 or another service. Background workers, data pipelines, transcoding jobs, machine learning training runs: these need EC2 (or ECS/Batch).
Stateful applications. If your application maintains in-memory state between requests — a WebSocket server, a game server, a caching layer — Lambda’s ephemeral execution model doesn’t fit. EC2 runs continuously and can hold state in memory.
Specific OS or hardware requirements. Need a specific Linux kernel version? A Windows Server license? A GPU? Custom networking drivers? EC2 is the only option. Lambda runs in AWS-managed sandboxes with no OS-level control.
High sustained throughput. Lambda pricing adds up at very high request volumes. At sustained thousands of requests per second with non-trivial compute per request, a fleet of Reserved EC2 instances often costs less than the equivalent Lambda invocations. Run the numbers.
Legacy applications. Apps that were built to run on a server — requiring a persistent process, local file writes, or port listening — are much easier to run on EC2 than to refactor for Lambda.
See the EC2 overview for full details on instance types and configuration.
Real scenario: the scraping job that breaks Lambda
Imagine a web scraping job. Your team writes it as a Lambda function because it seems like a simple task: hit a list of URLs, extract data, store results in S3. In testing, it finishes in 8 minutes. You deploy it.
Three months later, the URL list grows. The job now takes 16 minutes. Lambda refuses to run it — the 15-minute timeout is a hard ceiling, not a soft limit. Your job fails midway through.
The fix is not to squeeze the code. The fix is EC2 Spot instances or ECS Fargate tasks. Both support arbitrary execution time. An EC2 Spot instance running a scraping job for 20 minutes, then terminating, costs pennies. You get the cost efficiency of not paying for idle time, with no execution time ceiling.
This is the pattern: Lambda is not wrong for scraping — it is wrong for this scraping job. The 15-minute limit is not a bug to work around. It defines what Lambda is for.
Pricing comparison for a real workload
Consider an API handling 100,000 requests per day, each taking 200ms on average, using 512MB of memory on Lambda.
Lambda cost:
- Invocations: 100,000 × $0.0000002 = $0.02/day
- GB-seconds: 100,000 × 0.2s × 0.5GB = 10,000 GB-seconds × $0.0000166667 = $0.17/day
- Total: ~$0.19/day / ~$5.70/month
EC2 cost (t3.small On-Demand, 2 vCPU, 2GB RAM):
- $0.0208/hour × 24 × 30 = ~$14.98/month
At this scale, Lambda is 2.6x cheaper than a t3.small — and you don’t manage a server.
Scale that to 10 million requests per day and Lambda reaches ~$57/month. The t3.small stays at ~$15 if it can handle the load. At some threshold, EC2 wins on cost. The break-even point depends on your workload’s duration and memory usage. Always model both before committing.
Operational complexity is the hidden cost
The pricing comparison above doesn’t include the cost of managing an EC2 instance: OS patching, security updates, monitoring agent setup, log shipping configuration, SSH key management, and the time engineers spend on all of it.
Lambda eliminates that entire category of work. AWS patches the runtime, handles OS updates, and you never think about the underlying host. For small teams, this operational savings is more valuable than any pricing delta.
EC2 operational overhead becomes acceptable when you need the control EC2 provides — specific hardware, persistent processes, custom OS configuration. If you don’t need that control, you’re paying the EC2 overhead tax for nothing.
See Auto Scaling Groups for how EC2 scales, and Lambda scaling for how Lambda handles concurrent execution.
Quick decision guide
- Choose Lambda if: your workload runs in under 15 minutes, is event-triggered, has variable or low traffic, and you want zero infrastructure management.
- Choose EC2 if: your workload runs longer than 15 minutes, needs persistent in-memory state, requires specific OS/hardware, or has sustained high throughput where per-invocation pricing exceeds reserved instance cost.
- If you’re on the fence: start with Lambda. You can always move to EC2. The reverse is harder.
- Never run a job that approaches 15 minutes on Lambda — leave margin. If it takes 12 minutes today, it will take 16 minutes next quarter.
Frequently asked questions
What is the main difference between serverless and virtual machines in AWS?
With serverless (Lambda), you write code and AWS handles all infrastructure — no servers to configure, patch, or scale. With EC2, you rent a virtual machine and are responsible for the OS, runtime, and scaling configuration. Lambda is event-triggered and short-lived; EC2 runs continuously until you stop it.
Does serverless mean there are no servers?
No — there are always physical servers underneath. Serverless means you do not manage them. AWS runs your code on infrastructure it owns and maintains. You never SSH into a Lambda function or patch its OS.
When is Lambda the wrong choice?
Lambda is the wrong choice for workloads that run longer than 15 minutes, processes that need persistent state in memory, applications requiring specific OS-level configuration, and workloads with very high sustained throughput where per-invocation pricing exceeds the cost of a reserved EC2 instance.