AWS compute comparison
AWS Lambda vs EC2
Two fundamentally different ways to run code on AWS. Lambda is serverless — event-driven, pay-per-invocation, zero maintenance overhead, but with hard limits on runtime and state. EC2 is a full virtual machine — always on, fully customisable, but you manage it and pay for uptime whether the instance is idle or busy.
TL;DR
- AWS Lambda — serverless functions, event-triggered, pay per 100 ms of execution, 15-minute maximum timeout, stateless, subject to cold starts. Ideal for event-driven workloads, APIs with variable traffic, and scheduled jobs.
- EC2 — virtual machine with persistent processes, full OS access, any runtime, any duration. You manage patching and scaling. Best for steady workloads, long-running servers, stateful applications.
- Also consider AWS Fargate (serverless containers, no 15-minute ceiling) as a middle ground for containerised workloads.
Side-by-side comparison
| Aspect | AWS Lambda | EC2 |
|---|---|---|
| Compute model | Serverless — AWS manages all underlying servers | Virtual machine — you provision, configure, and patch |
| Pricing model | Per invocation + per 100 ms of execution time | Per hour (On-Demand) or with Reserved/Spot discounts |
| Idle cost | Zero — you pay only when code is executing | Full price regardless of traffic |
| Cold start | Yes — 10 ms to 1 000 ms+ depending on runtime and package size | None — your process is always running |
| Execution timeout | Maximum 15 minutes per invocation | Unlimited |
| State | Stateless — no reliable persistence across invocations | Full disk, memory, and process state |
| Scaling | Automatic — concurrency scales to thousands in seconds | Manual or via Auto Scaling Groups (minutes to add instances) |
| OS / runtime access | Managed runtimes only; custom runtimes via Lambda Layers | Full root access — install any software, custom kernels, GPUs |
| Maintenance overhead | Near zero — AWS handles patches, OS updates, capacity | High — you manage AMIs, patching, monitoring agents |
| Best for | APIs, event processing, scheduled jobs, webhooks | Long-running servers, stateful apps, BYOL workloads, GPU |
What is AWS Lambda?
AWS Lambda is a serverless compute service introduced in 2014. You upload a function — a self-contained unit of code — and define what triggers it: an HTTP request via API Gateway, an object uploaded to S3, a message arriving in SQS, a schedule (EventBridge), or dozens of other AWS event sources.
When a trigger fires, AWS spins up an execution environment (or reuses a warm one), runs your function, and tears it down. You are billed for the number of invocations and the duration in 100 ms increments. At zero traffic you pay nothing.
The tradeoff is constraints. Lambda functions are stateless: you cannot rely on data persisting between invocations unless you store it externally in DynamoDB, S3, or RDS. Execution time is capped at 15 minutes. And when no warm environment exists, you suffer a cold start — the latency of initialising a fresh container, downloading your code, and starting the runtime.
Cold start in plain English
Imagine a restaurant kitchen where all the chefs go home when there are no orders. The moment a customer arrives, you must call the chefs back, have them put on their uniforms, and heat the oven — before cooking a single dish. That waiting time is the cold start. A warm instance is a kitchen with a chef already standing by.
What is Amazon EC2?
Amazon Elastic Compute Cloud (EC2), launched in 2006, is AWS's original compute service. You choose an instance type — a combination of vCPUs, RAM, storage, and network throughput — and launch a virtual machine running your choice of operating system. The instance runs continuously until you stop or terminate it.
Common instance families include:
- t3 / t4g — burstable general purpose; cheap, suitable for low-to-moderate workloads
- m6i / m7g — balanced CPU/memory; the default choice for web servers and APIs
- c7g / c6i — compute-optimised; for CPU-intensive workloads
- r6i / r7g — memory-optimised; for in-memory databases or large caches
- p4d / g5 — GPU instances; for machine learning training and inference
Unlike Lambda, EC2 supports persistent processes: a web server, a database, a long-running background worker, or any process that must maintain state in memory or on disk across many requests. You also get full SSH access, which makes debugging significantly easier than in a serverless environment.
EC2 demands maintenance overhead: you are responsible for OS patching, AMI updates, security group rules, monitoring agents, and capacity planning. Auto Scaling Groups help automate horizontal scaling, but the setup is far more involved than Lambda's automatic concurrency.
How engineers talk about Lambda vs EC2
These phrases come up regularly in architecture discussions, pull requests, and incident reviews. Learning them helps you follow technical conversations confidently.
-
"We're seeing cold starts on the Java runtime — let's switch to Node.js or enable Provisioned Concurrency."
Used when Lambda latency spikes for infrequent requests. Provisioned Concurrency keeps a set number of warm instances ready.
-
"Lambda scales to zero overnight — we pay nothing when there's no traffic."
Scales to zero is a key selling point of serverless: no idle instances means no idle cost.
-
"The function times out after 15 minutes — we need to break this job into smaller chunks."
The execution timeout is Lambda's hardest limit. Long jobs must be decomposed into smaller invocations, often via Step Functions or SQS.
-
"This workload is stateless, so Lambda is a good fit — we don't need the instance to remember anything between requests."
Stateless means each invocation is self-contained. The opposite — stateful — requires external state management or a persistent server.
-
"We're on a t3.medium — 2 vCPUs, 4 GB RAM — it handles our baseline traffic, and the Auto Scaling Group adds more instances during peak hours."
EC2 instance types follow a naming convention: family letter(s) + generation number + size (nano, micro, small, medium, large, xlarge, 2xlarge…).
-
"We moved the image-resizing pipeline to Lambda. It's event-driven — S3 triggers the function whenever a file is uploaded."
Event-driven architectures react to events (file upload, queue message, HTTP call) rather than polling. Lambda is purpose-built for this pattern.
-
"The Reserved Instance for this API server saves us 40% compared to On-Demand."
Reserved Instances commit you to 1 or 3 years in exchange for a significant discount. Contrast with Spot Instances, which are spare capacity sold cheaply but can be interrupted.
-
"Debugging Lambda in production is painful — there's no SSH, so we rely entirely on CloudWatch Logs and X-Ray traces."
The lack of a persistent process and SSH access is one of Lambda's practical downsides. Structured logging and distributed tracing become essential.
Lambda function skeleton (Node.js)
A Lambda handler receives an event object and a context object. It must complete within the configured timeout.
// handler.mjs — AWS Lambda (Node.js 20)
export const handler = async (event, context) => {
// event contains trigger-specific data
// (API Gateway request, S3 event, SQS message, etc.)
console.log('Request ID:', context.awsRequestId);
// Lambda is stateless — don't rely on module-level state
// across invocations. Use DynamoDB, S3, or RDS for persistence.
const result = await processEvent(event);
return {
statusCode: 200,
body: JSON.stringify(result),
};
};
EC2 deployment sketch (systemd service)
On EC2 you manage a persistent process. A typical Node.js API is kept alive by systemd and fronted by nginx.
# /etc/systemd/system/myapp.service
[Unit]
Description=My API Server
After=network.target
[Service]
Type=simple
User=deploy
WorkingDirectory=/srv/myapp
ExecStart=/usr/bin/node server.mjs
Restart=on-failure
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.target
Decision guide: Lambda or EC2?
- Event-driven, spiky, or unpredictable traffic → Lambda
- API with variable load, responds in under 15 minutes → Lambda
- Scheduled jobs, background tasks, webhook handlers → Lambda
- Zero infrastructure management required → Lambda
- Long-running server process (hours or days) → EC2
- Application needing local disk or in-memory state → EC2
- Custom OS, kernel module, GPU, or BYOL licence → EC2
- SSH access needed for debugging → EC2
- Steady high-throughput workload where Lambda cost exceeds EC2 → EC2 or Fargate
- Containerised workload, no 15-minute limit, no server management → Fargate
Frequently asked questions
What is the main difference between AWS Lambda and EC2?
EC2 (Elastic Compute Cloud) is a virtual machine you provision, configure, and pay for by the hour — whether or not it is handling traffic. Lambda is serverless: you deploy a function, and AWS runs it only when triggered by an HTTP request, an event, or a schedule. You pay per invocation and per 100 ms of execution time. Lambda removes all infrastructure management; EC2 gives you full control over the runtime environment.
What is a cold start and why does it matter?
A cold start occurs when Lambda needs to initialise a brand-new execution environment — downloading your deployment package, starting the runtime, and running initialisation code — before it can handle a request. This adds latency ranging from 10–100 ms for Node.js or Python to over a second for Java with a large classpath. Cold starts are most noticeable for infrequently invoked functions. Provisioned Concurrency pre-warms Lambda instances to eliminate cold starts, at an additional cost.
What are the hard limits of AWS Lambda?
Lambda has a maximum execution timeout of 15 minutes per invocation, up to 10 GB of RAM, 512 MB–10 GB of ephemeral /tmp storage, and a deployment package limit of 250 MB (unzipped). These constraints make Lambda unsuitable for long-running batch jobs, workloads requiring persistent local state, or anything demanding GPU access. For those scenarios, EC2, Fargate, or ECS is more appropriate.
Is Lambda always cheaper than EC2?
No. Lambda is extremely cost-effective for irregular or low-volume workloads — you pay nothing when idle. However, for steady high-throughput workloads (millions of requests per day with long execution durations) the per-invocation pricing can exceed the cost of a Reserved EC2 instance. Evaluate your traffic pattern: spiky or unpredictable load favours Lambda; steady and high-volume workloads often favour EC2 or Fargate.
Can Lambda maintain state between invocations?
Not reliably. Lambda execution environments may be reused (warm start) or replaced (cold start) at any time. Variables stored in the global scope of an execution environment persist within a warm instance, but you cannot depend on this behaviour. For persistent state, use external storage: S3, DynamoDB, RDS, or ElastiCache. Lambda is intentionally stateless by design.
What does BYOL mean in an EC2 context?
BYOL stands for Bring Your Own Licence. Certain commercial software (Oracle DB, Windows Server, some RHEL configurations) requires a paid licence that AWS does not include in the instance price. EC2 allows you to bring existing licences from on-premises environments to your instances under Dedicated Hosts — a scenario that does not exist in the serverless Lambda model.
When should I use Fargate instead of Lambda or EC2?
AWS Fargate is a serverless container runtime — a useful middle ground. Like Lambda, you do not manage underlying servers. Unlike Lambda, you can run long-lived containers without a 15-minute timeout, with more predictable CPU/RAM allocation and no cold-start penalty. Use Fargate when you need containerised workloads without server management, runtimes longer than 15 minutes, or more control over the environment than Lambda permits.