Skip to content
ExponaBLOG
AWS FOR DEVELOPERS · DAY 025 / 100

ECS vs EKS: a practical AWS guide for working engineers

Pick by team skills, not hype.

Expona Admin6 min read

ECS vs EKS

After five years of running workloads on AWS, I've watched teams spend weeks debating container orchestration when they should be shipping features. The choice between ECS and EKS isn't technical—it's organizational. Let me walk you through how to pick the right tool for your team, not the one everyone's hyping at conferences.

The Core Difference

ECS (Elastic Container Service) is AWS's native container orchestrator. EKS (Elastic Kubernetes Service) is AWS's managed Kubernetes. That sounds simple, but it cascades into everything: learning curves, operational overhead, ecosystem access, and how fast your team can iterate.

I've shipped production systems on both. ECS got us to market faster in 2021 when we had six engineers. EKS became the right call later when we needed to migrate across cloud providers and hire people already fluent in Kubernetes syntax.

ECS: Simpler and Deeply AWS-Integrated

ECS is built for teams that want to run containers without learning a new abstraction layer. You define task definitions (blueprints for your containers), services (how many tasks to run), and let ECS handle placement and scaling.

Here's a real example from a ride-hailing platform I worked on. We had a driver-matching service handling 10,000 concurrent requests. The task definition looked like this:

bash
{
  "family": "driver-matcher",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "512",
  "memory": "1024",
  "containerDefinitions": [
    {
      "name": "app",
      "image": "123456789.dkr.ecr.us-east-1.amazonaws.com/driver-matcher:latest",
      "portMappings": [
        {
          "containerPort": 3000,
          "protocol": "tcp"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/driver-matcher",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "ecs"
        }
      }
    }
  ]
}

We created an ECS service referencing this definition, set desired count to 20, and ECS distributed those 20 tasks across our Fargate cluster. When load spiked, we configured target tracking on CPU or request count, and ECS scaled horizontally. CloudWatch dashboards lit up, auto-scaling policies fired, and we didn't touch a single Kubernetes YAML file.

ECS integrates natively with:

  • CloudWatch Logs — container stdout/stderr pipes directly without sidecars
  • IAM roles — task-level permissions without RBAC complexity
  • Application Load Balancer — health checks and traffic routing baked in
  • Parameter Store and Secrets Manager — environment variable injection without a secret controller
  • VPC networking — awsvpc mode means each task gets its own ENI

For a small to mid-sized team, this reduces your operational surface. You're not managing a separate control plane, ETCD backups, or certificate rotation. AWS handles it.

EKS: Kubernetes Ecosystem and Portability

Kubernetes is the industry standard. If you hire a platform engineer or SRE, they've probably used Kubernetes. EKS gives you the full ecosystem: Helm, service meshes (Istio), observability tools (Prometheus, Grafana), and GitOps (ArgoCD). You also get portability—run the same manifests on GCP, Azure, or on-premises.

I adopted EKS for a SaaS platform where customers demanded multi-region failover and the ability to spin up isolated environments per customer. Here's how a deployment looked:

bash
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-server
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api-server
  template:
    metadata:
      labels:
        app: api-server
    spec:
      containers:
      - name: app
        image: 123456789.dkr.ecr.us-east-1.amazonaws.com/api-server:v2.1.0
        ports:
        - containerPort: 8080
        resources:
          requests:
            cpu: 500m
            memory: 512Mi
          limits:
            cpu: 1000m
            memory: 1Gi
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        env:
        - name: LOG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: log-level
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - api-server
            topologyKey: kubernetes.io/hostname

With EKS, we installed Prometheus and Grafana via Helm, plugged in ArgoCD for GitOps deployments, and configured a service mesh to handle traffic splitting for canary releases. This would have been possible on ECS, but it would have required manual integration and custom tooling.

EKS shines when you need:

  • Multi-cloud or hybrid deployments
  • Complex workload scheduling (pod affinity, node selectors, taints/tolerations)
  • Istio or other service meshes
  • Helm charts from the community
  • Engineers already fluent in kubectl and YAML manifests

Small Teams Usually Move Faster with ECS

I've seen it repeatedly: a team of eight engineers picks EKS because "that's what Netflix uses" and burns three weeks learning Kubernetes before shipping their first service. ECS isn't less powerful—it's less abstract. You spend less time learning the orchestrator and more time building features.

At the ride-hailing company, our team went ECS-first. We had task definitions, services, and auto-scaling working in two days. The driver-matching logic, Redis caching, and PostgreSQL queries took the real engineering effort. If we'd chosen EKS, we'd still be debugging networking issues.

ECS requires less operational overhead: no cluster upgrades, no node patching schedules, no ETCD maintenance. When something breaks, AWS is responsible for the control plane. On EKS, you own the control plane—AWS manages the API server and etcd, but you're responsible for CNI plugins, ingress controllers, and add-ons.

That said, if your team is already Kubernetes-native or you have 30+ engineers, EKS's flexibility pays dividends. The cost of learning and operating Kubernetes distributes across more people.

Both Run on Fargate or EC2

A common misconception: ECS runs on EC2 and EKS uses Fargate, or vice versa. False. Both can run on either.

Fargate is serverless compute. You specify CPU and memory, AWS handles the underlying instances, patching, and capacity planning. No cluster management. Pricing is per-task or per-pod-hour. Best for predictable workloads and teams without infrastructure expertise.

EC2 lets you manage the cluster explicitly. You launch instances, join them to a cluster, and handle patching. You pay for instances whether or not your containers use them. Best for cost optimization at scale, GPU workloads, or when you need fine-grained control.

I've run ECS on Fargate for microservices (low management overhead, predictable costs up to ~20 concurrent tasks) and ECS on EC2 for batch processing (cheaper per compute unit, justified the management overhead).

For EKS, I preferred Fargate during early stages—it reduced operational burden—and moved to EC2 once we had an SRE team and knew our steady-state traffic patterns. Fargate pod pricing is steep if you're running 100+ pods consistently.

Common Mistakes

  • Choosing Kubernetes to future-proof — You don't future-proof software by picking complex infrastructure. You future-proof by writing good code and observability. If you need Kubernetes later, migrating a well-designed service is straightforward.
  • Treating ECS as second-class — ECS is production-grade. LinkedIn, Airbnb, and Slack run massive ECS clusters. The "Kubernetes is the real orchestrator" narrative comes from cloud-agnostic organizations, not from teams shipping fast.
  • Ignoring networking overhead — EKS with a CNI (like Calico or AWS VPC CNI) adds latency compared to ECS awsvpc mode. Measure it for your workload. Inter-pod communication is slower than ECS task-to-task communication.
  • Picking based on vendor lock-in fears — If portability matters (truly matters—most teams overestimate this), choose Kubernetes. If it doesn't, ECS is faster and cheaper on AWS.
  • Underestimating operational costs — EKS requires more tooling, more monitoring, and more oncall rotations. Budget for that. ECS on Fargate is the simplest model: define, deploy, scale.

Key Takeaways

  • ECS is AWS-native, simpler to operate, and faster for small teams to ship on.
  • EKS gives you Kubernetes ecosystem, portability, and complex scheduling—at the cost of operational overhead.
  • Both support Fargate (serverless, simpler) and EC2 (cost-optimized, more control).
  • Small teams (≤15 engineers) move faster with ECS unless they already know Kubernetes.
  • Pick by team skills, not hype. A well-run ECS cluster beats a poorly-managed EKS cluster every time.
  • Migration between them is possible but not trivial—spend a week on architecture, not weeks regretting the choice.
ShareXLinkedInReddit

Found this useful? Support the writing.

Buy me a coffee
Written by
Expona Admin
Site administrator

Comments

Loading comments…

Leave a comment

Comments are reviewed before they appear. Be kind and stay on topic.

Related articles