EC2, Lambda, or Fargate — choosing the wrong compute option costs you money and performance. Here is exactly when to use each one in production.
Three services. One decision that determines your bill, your scaling behaviour, and how many 2 AM pages your team gets. Getting this wrong at Swiggy during the IPL final means dropped orders. Getting it wrong at Razorpay during a payment spike means failed transactions and chargebacks.
This is not a theoretical comparison. It is a practical decision framework built on what actually happens in Indian production environments.
Before comparing numbers, understand what each service actually is:
EC2: You rent a virtual machine. The machine runs 24/7. You manage: OS, patching, scaling, monitoring. You pay: every hour the instance is running, used or not. Fargate: You run a Docker container. AWS manages the underlying VM. You manage: container image, CPU/memory allocation. You pay: per second the container is active. Lambda: You run a function. AWS manages everything. You manage: your code and its trigger. You pay: per millisecond of actual execution.The gradient goes from maximum control (EC2) to maximum abstraction (Lambda). Neither extreme is always correct.
EC2 wins when your workload is predictable, persistent, and stateful.
Zerodha's trading engine processes millions of orders per day across a 6-hour market window. The load pattern is known: 9:15 AM opens hard, stays high until 3:30 PM, quiet overnight. The application is stateful — in-memory order books that cannot be rebuilt on every cold start. Lambda's 15-minute limit and cold start penalty are disqualifying factors. EC2 Reserved Instances bought for the trading window cost 40-72% less than On-Demand.
EC2 is correct when:
The mistake engineers make is defaulting to EC2 out of familiarity. If your EC2 instance sits at 3% CPU for 18 hours a day, you are paying for compute you are not using. That is where the other two options become relevant.
Lambda wins when work arrives in bursts, runs for seconds, and disappears.
At Hotstar, when a match ends, 50 million users simultaneously trigger a cascade of events — push notifications, watch history updates, recommendation model triggers, analytics writes. Each event takes 200-500 milliseconds. Lambda handles 50,000 of them in parallel without any capacity planning. Five minutes after the match, load drops to near zero. Lambda scales to zero automatically. EC2 running 24/7 for that burst workload would cost 20x more and sit idle 95% of the time.
Lambda is correct when:
The Lambda pricing reality check:
Function: 256 MB RAM, 300ms per invocationTraffic: 1 million invocations per day Lambda cost:Duration: 1M × 0.25 GB × 0.3s = 75,000 GB-seconds= 75,000 / 600,000 × $1.00 = $0.125/day = ~$3.75/month Equivalent t3.small EC2 running 24/7:$0.026/hour × 720 hours = $18.72/month Lambda is 5x cheaper for this pattern.Lambda is wrong when your function approaches the 15-minute limit, needs GPU, or runs every second without pause. At that point the abstraction costs more than the infrastructure.
Fargate sits between EC2 and Lambda. You get containers without managing servers, with no time limit and no cold start concerns — but you pay for running containers even when they are idle.
PhonePe runs its payment processing microservices on Fargate. Each service is a Docker container with specific CPU and memory requirements. The services run continuously — they need to be responsive instantly when a UPI request arrives. Lambda cold starts are unacceptable for sub-second payment confirmation. But PhonePe does not want to manage EC2 instances, patch operating systems, or size clusters manually. Fargate gives them containers-as-infrastructure with AWS handling everything underneath.
Fargate is correct when:
Fargate is wrong for extremely spiky workloads. When a Fargate task starts, it takes 20-30 seconds to be ready. For sudden traffic explosions Lambda — which scales in milliseconds — is faster.
| Dimension | EC2 | Fargate | Lambda |
|---|---|---|---|
| Startup time | Minutes (with cold AMI) | 20-30 seconds | 100ms to 10s |
| Max runtime | Unlimited | Unlimited | 15 minutes |
| Scaling speed | Minutes (ASG) | 30 seconds | Milliseconds |
| Idle cost | Full instance cost | Per second idle | Zero |
| Server management | Full — you patch | None | None |
| GPU support | Yes | Yes (limited) | No |
| VPC integration | Native | Native | Yes (with latency) |
Most production architectures at scale use all three together:
API Layer:API Gateway → Lambda (auth check, routing, simple responses) Application Layer:ECS Fargate (long-running microservices, stateful services) Batch and Events:Lambda (S3 triggers, SQS workers, scheduled jobs, notifications) Databases and Infrastructure:EC2 Reserved (Redis clusters, Kafka brokers, anything stateful and continuous)At CRED, the recommendation engine runs on EC2 Reserved Instances because it trains continuously. The notification delivery runs on Lambda because it fires in bursts when reward points are calculated. The API serving users runs on Fargate because it needs instant response without the complexity of EC2 fleet management.
Before picking, model your cost across three scenarios:
Scenario A — 10 requests per second, 500ms each:
Lambda: 10 req/s × 86,400s × 0.5s × 0.25 GB = 108,000 GB-s/day → ~$0.18/dayFargate: 0.25 vCPU × $0.04048/vCPU/hr × 24hr = ~$0.24/dayEC2 t3.small: $0.026/hr × 24hr = $0.62/dayWinner: LambdaScenario B — 100 requests per second, 500ms each:
Lambda: 100 req/s × 86,400s × 0.5s × 0.25 GB = 1,080,000 GB-s/day → ~$1.80/dayFargate: 2 vCPU × $0.04048 × 24hr = ~$1.94/dayEC2 t3.medium (Reserved 1yr): $0.015/hr × 24hr = $0.36/dayWinner: EC2 Reserved at this volumeScenario C — 1,000 requests per second in a 2-hour burst, then zero:
Lambda: scales instantly to handle burst, costs only during 2-hour windowFargate: must pre-provision for peak, pays for capacity even at zeroEC2 ASG: takes minutes to scale, over-provisionsWinner: Lambda by a wide margin for bursty patternsCold starts are Lambda's biggest liability for user-facing APIs:
Python / Node.js: 100-500ms (acceptable for most APIs)Java / .NET: 1-10 seconds (serious problem for payments, trading) Mitigations:1. Move all initialisation outside the handler function (DB connections, SDK clients, config — runs once, reused)2. Provisioned Concurrency — keep N environments always warm (paid)3. SnapStart for Java — snapshot at deploy time, restore in <1s (free)4. Choose Python or Node.js for latency-sensitive functionsFor payment APIs at Razorpay, Provisioned Concurrency with Application Auto Scaling keeps 20 warm environments during business hours and scales down overnight. Cold starts effectively eliminated. Cost increases by roughly 30% but SLA is met.
| Concern | EC2 | Fargate | Lambda |
|---|---|---|---|
| Operational burden | High — OS, patching, capacity | Low — container only | Near zero |
| Debugging | Full access | Container logs | CloudWatch only |
| Cost at low traffic | Worst — pays for idle | Medium | Best — zero at zero |
| Cost at high continuous traffic | Best with Reserved | Medium | Worst — per-request |
| Deployment speed | Slowest | Fast | Fastest |
Follow these rules before finalising your compute choice:
REMEMBER THIS**References and Further Reading** * [AWS Lambda pricing calculator](https://aws.amazon.com/lambda/pricing/) — model your exact workload cost * [AWS Fargate pricing](https://aws.amazon.com/fargate/pricing/) — per-vCPU and per-GB-memory pricing * [EC2 Savings Plans](https://aws.amazon.com/savingsplans/) — how to reduce EC2 cost for steady workloads
Lambda becomes costlier than EC2 when your function runs continuously for more than roughly 20 hours per day. At that point a Reserved EC2 instance is cheaper. Lambda wins for bursty, event-driven workloads with idle time. EC2 wins for steady 24/7 compute.
Yes. Both Lambda and Fargate can be deployed inside a VPC by specifying subnets and security groups. The trade-off is that Lambda inside a VPC loses default internet access — you need a NAT Gateway for outbound calls to public endpoints.
Discussion0