Definition
- EC2 – Virtual machines where you control the OS, runtime, scaling, and patching, giving maximum flexibility and maximum responsibility.
- ECS (Elastic Container Service) – AWS's native container orchestrator that runs Docker containers with deep AWS integration and less operational overhead than Kubernetes.
- EKS (Elastic Kubernetes Service) – Managed Kubernetes providing the full K8s API, Helm charts, operators, and portability across clouds and on-premises.
- Lambda – Serverless compute that runs function code in response to events with no servers to manage, automatic scaling from zero, and per-millisecond billing.
- Fargate – A serverless compute engine for containers that removes server management from both ECS and EKS.
Imagine National Bank of India needs office space for teams. EC2 is leasing an empty floor and furnishing it yourself – total control, but you buy the desks, wire the network, and clean it. ECS is a serviced office managed by AWS's own facilities team – you bring your people (containers), AWS runs the building efficiently. EKS is a serviced office run to a global standard chain's rulebook (Kubernetes) – portable to any city that follows the same rulebook, but the rulebook is thick. Lambda is a hot-desk you use only for the minutes you actually sit down.
Understanding the Concepts
What is EC2 and when do you choose it?
EC2 gives you a virtual server. You pick the instance type, the operating system, and you are responsible for everything above the hypervisor: patching the OS, installing runtimes, configuring auto scaling groups, and securing the host. Choose EC2 when you need full control, a specific OS or kernel tuning, licensed software tied to a host, or a long-running process that does not fit a container model cleanly.
import software.amazon.awssdk.services.ec2.Ec2Client;
import software.amazon.awssdk.services.ec2.model.*;
public class EC2FullControl {
public static void main(String[] args) {
Ec2Client ec2 = Ec2Client.create();
// Full VM – you control OS, runtime, everything
RunInstancesRequest req = RunInstancesRequest.builder()
.imageId("ami-0abcd1234")
.instanceType(InstanceType.C6I_XLARGE) // compute optimized for risk engine
.keyName("nbi-risk-key")
.minCount(1).maxCount(1).build();
ec2.runInstances(req);
// You must: patch OS, install Java, configure autoscaling, monitor
}
}
What is ECS and when do you choose it?
ECS runs Docker containers. You package the application as an image, define a task definition (CPU, memory, image, environment, IAM task role), and ECS schedules and keeps the desired number of tasks running. It integrates tightly with load balancers, IAM, CloudWatch, and VPC networking. Choose ECS when your team wants containers with minimal operational complexity and is happy to stay within AWS.
// Conceptual ECS task definition in Java
record TaskDefinition(String image, int cpu, int memoryMb, String taskRoleArn) {}
TaskDefinition transfer = new TaskDefinition(
"123456789012.dkr.ecr.ap-south-1.amazonaws.com/transfer-service:1.4.0",
512, 1024,
"arn:aws:iam::123456789012:role/transfer-task-role");
// ECS keeps 3 tasks running, restarts any that fail,
// integrates with ALB for health checks and traffic routing
What is EKS and when do you choose it?
EKS runs Kubernetes, managed by AWS for the control plane while you run workloads on worker nodes or Fargate. You get the full Kubernetes API, Helm charts, operators, and portability across clouds and on-premises. Choose EKS when you need Kubernetes portability, already have Kubernetes expertise and tooling, or must avoid cloud lock-in.
# Deploy a banking service on EKS
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: settlement-service
spec:
replicas: 3
selector:
matchLabels:
app: settlement
template:
metadata:
labels:
app: settlement
spec:
containers:
- name: settlement
image: 123456789012.dkr.ecr.ap-south-1.amazonaws.com/settlement:2.1.0
resources:
requests: { cpu: "500m", memory: "1Gi" }
limits: { cpu: "1", memory: "2Gi" }
ports:
- containerPort: 8080
EOF
What is Lambda and when do you choose it?
Lambda runs functions. You upload code, choose memory (which also scales CPU), and connect triggers such as API Gateway, S3 events, SQS, or EventBridge. AWS runs it only when invoked, scales from zero to thousands automatically, and bills per millisecond. Choose Lambda for short, event-driven, spiky, or infrequent work where you want zero server management and to pay nothing when idle.
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import java.util.Map;
public class StatementUploadHandler implements RequestHandler<Map<String, Object>, String> {
@Override
public String handleRequest(Map<String, Object> s3Event, Context context) {
// Triggered when a statement PDF lands in S3
// Indexes the statement, notifies the customer
String bucket = "nbi-customer-statements";
context.getLogger().log("Processing uploaded statement from " + bucket);
return "processed";
}
// Runs ONLY when invoked – costs nothing when idle
// Max runtime: 15 minutes
// Max memory: 10 GB
}
How do they compare side by side?
| Aspect | EC2 | ECS | EKS | Lambda |
|---|---|---|---|---|
| Abstraction | Virtual machine | Container task | Kubernetes pod | Function |
| You manage | OS, runtime, scaling, patching | Container image, task definition | K8s manifests, worker nodes | Code, memory setting |
| AWS manages | Hypervisor, hardware | Orchestration, scheduling | Control plane | Everything |
| Scaling | ASG (manual config) | Service auto scaling | HPA / Karpenter | Automatic from zero |
| Billing | Per second (instance runs) | Per task (Fargate) or EC2 | Per pod (Fargate) or EC2 | Per millisecond of execution |
| Max runtime | Unlimited | Unlimited | Unlimited | 15 minutes |
| Startup | Minutes | Seconds | Seconds | Milliseconds to seconds |
| Portability | AWS only | AWS only | Multi-cloud, on-prem | AWS only |
| Best for | Full control, licensed software | Simple AWS-native containers | K8s portability, large ecosystem | Short event-driven work |
public class ComputeSpectrum {
// Most control, most work:
// EC2 → ECS → EKS → Lambda
// Least control, least work
// Pick the least-operational option that fits the workload shape
}
What is Fargate and how does it change the picture?
Fargate is a serverless compute engine for containers. It removes the need to provision and manage EC2 instances for your ECS tasks or EKS pods. You define CPU and memory per task, and Fargate runs it on managed infrastructure. This means ECS on Fargate and EKS on Fargate both become server-less container platforms, and the only difference between them is the orchestration API (ECS API vs Kubernetes API).
# Fargate removes the server management layer
ECS on EC2: You manage EC2 instances + ECS orchestrates containers on them
ECS on Fargate: AWS manages infrastructure + ECS orchestrates containers
EKS on EC2: You manage EC2 worker nodes + Kubernetes orchestrates pods on them
EKS on Fargate: AWS manages infrastructure + Kubernetes orchestrates pods
What are common mistakes?
The first mistake is using EC2 for everything out of habit. If the workload fits containers or Lambda, you take on unnecessary operational burden.
The second mistake is choosing EKS just because Kubernetes is popular. If the team does not have Kubernetes expertise and portability is not needed, ECS is simpler and cheaper to operate.
The third mistake is ignoring Lambda's constraints. A 15-minute max runtime, cold starts, and a 10 GB memory limit mean it does not fit long-running batch jobs or latency-sensitive services.
public class ComputeMistakes {
// WRONG: EC2 for a file-processing trigger that runs 10 seconds
// → Use Lambda: zero cost when idle, scales automatically
// WRONG: EKS for a small team with no K8s experience
// → Use ECS: simpler, less operational overhead
// WRONG: Lambda for a 30-minute batch job
// → Use ECS/Fargate: no runtime limit
}
What should a senior engineer know?
A senior engineer picks the least-operational compute that fits each workload's shape. They know that a bank often runs several models simultaneously: the always-running transfer service on ECS with Fargate, the file-processing trigger on Lambda, the legacy risk engine on EC2, and the portable platform workloads on EKS. There is no single right answer.
They also know about Lambda Provisioned Concurrency to eliminate cold starts for latency-sensitive endpoints, ECS Service Connect for service mesh without a sidecar proxy, and EKS managed node groups with Karpenter for efficient auto-scaling.
National Bank of India compute choices: ┌──────────────────────────┬────────────────┐ │ Workload │ Compute Choice │ ├──────────────────────────┼────────────────┤ │ Transfer service (24/7) │ ECS + Fargate │ │ Statement PDF processing │ Lambda (S3 trigger) │ │ Risk engine (kernel tuning)│ EC2 │ │ Platform team (portable) │ EKS │ │ Month-end batch reports │ ECS Fargate task │ └──────────────────────────┴────────────────┘
Visual Overview
┌──────── Compute Spectrum: Control vs Management ────────┐ │ │ │ Most Control Least Control │ │ Most Operational Work Least Work │ │ ◄──────────────────────────────────────────────────► │ │ │ │ EC2 ECS EKS Lambda │ │ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │ │ │ VM │ │Task│ │ Pod│ │Func│ │ │ │ │ │ │ │ │ │ │ │ │ │ OS │ │Img │ │Img │ │Code│ │ │ │ RT │ │CPU │ │CPU │ │ Mem│ │ │ │ ASG│ │Mem │ │Mem │ │ │ │ │ └────┘ └────┘ └────┘ └────┘ │ │ Manage: Manage: Manage: Manage: │ │ Everything Image+Task Manifests+ Code+Memory │ │ definition worker nodes │ │ │ │ Fargate removes server management from ECS and EKS: │ │ ECS+Fargate: define task, AWS runs it │ │ EKS+Fargate: define pod, AWS runs it │ │ │ │ Lambda: define function, AWS runs it on events │ │ No servers at any level │ └──────────────────────────────────────────────────────────┘
Key Takeaway
EC2, ECS, EKS, and Lambda sit on a spectrum from most control and most operational work to least control and least work, and I choose by matching the workload's shape to the least-operational option that still fits. EC2 is a virtual machine where I control the operating system, the runtime, scaling, and patching, which I pick when I need a specific OS or kernel tuning, licensed software tied to a host, or a long-running process that does not fit a container cleanly – the price is that I own all the operational burden.
ECS is AWS's native container orchestrator. I package the app as a Docker image, define a task with CPU, memory, and an IAM task role, and ECS keeps the desired number of tasks running with deep integration into load balancers, IAM, and CloudWatch. It has a gentle learning curve and little control-plane overhead, so I choose it when my team wants containers with minimal complexity and is comfortable staying within AWS. EKS is managed Kubernetes: AWS runs the control plane and I get the full Kubernetes API, Helm, operators, and portability across clouds and on-premises, at the cost of real complexity and needing Kubernetes expertise, so I choose it specifically when portability or an existing Kubernetes investment justifies that complexity.
Lambda is serverless functions. I upload code, pick memory, and wire triggers like API Gateway, S3, SQS, or EventBridge, and AWS runs it only when invoked, scales it from zero to thousands automatically, and bills per millisecond. I choose it for short, event-driven, spiky, or infrequent work where I want zero server management and to pay nothing when idle, while respecting its constraints like the fifteen-minute maximum runtime and cold starts.
At National Bank of India I deliberately used all four. The constantly running transfer service went on ECS with Fargate for simple, AWS-native containers. The statement-PDF processor, which runs only when files land in S3, went on Lambda so it costs nothing between runs. A legacy risk engine that needed specific kernel tuning stayed on EC2 because only a full virtual machine gave that control. And the platform team's portable workloads went on EKS because they needed Kubernetes to stay portable across environments.
Remember one sentence: Pick the least-operational compute that fits the workload shape – EC2 for full control, ECS for simple AWS containers, EKS for Kubernetes portability, Lambda for short event-driven work.
---