Search
CLD Tutorial

AWS Fargate: Deploy Containers in 13 Steps, 70 Min [2026]

Yusuf Demir
Yusuf DemirCloud & Software Reporter
22 min read
AWS Fargate: Deploy Containers in 13 Steps, 70 Min [2026]

AWS Fargate turns ten years old in the cloud computing timeline this year, and it still solves the same problem it was built for: running containers without anyone on the team babysitting an EC2 fleet. If you have ever patched a cluster of container hosts at 2 a.m. because a kernel CVE dropped, you already understand the appeal. The sections below cover through a complete AWS Fargate deployment in October 2026, from writing the Dockerfile to tearing the stack back down, with real pricing figures pulled straight from AWS’s published rate card.

Containers are no longer a niche choice. “Docker was used by 71.1% of all respondents, while Amazon Web Services was used by 43.3% in cloud development and infrastructure work,” according to the 2025 Stack Overflow Developer Survey. Fargate sits at the intersection of both numbers: it is Amazon’s answer to running Docker images without owning the servers underneath them. By the end of this guide you will have a working ECS service running on Fargate, fronted by a load balancer, scaled automatically, logged to CloudWatch, and billed on Fargate Spot pricing where it makes sense.

AWS launched Fargate for ECS in 2017 and extended it to EKS in 2019, and the core pitch has not changed since: describe the resources a container needs, and let AWS worry about where it physically runs. What has changed is the surrounding tooling. Capacity providers, Fargate Spot, Graviton support, and ECS Exec all arrived after the original launch and turned a bare-bones serverless container runtime into something teams can actually run production traffic on without a second compute platform bolted on for the pieces Fargate used to be missing.

Google · Preferred Sources

Don't miss new tech stories on Google

Add TrendinTech once in the Google app and our stories appear in your news suggestions.

Add Now

What AWS Fargate Is and Why It Still Matters in 2026

AWS Fargate is a serverless compute engine for containers. You describe how much vCPU and memory a task needs, hand AWS a container image, and Fargate finds the capacity, starts the task, and tears it down when it finishes. There is no EC2 instance to patch, no Auto Scaling Group to tune for the underlying hosts, and no capacity planning spreadsheet. Fargate works with both Amazon Elastic Container Service (ECS) and Amazon Elastic Kubernetes Service (EKS), so teams already standardized on Kubernetes manifests are not locked out.

The reason this still matters heading into 2026 is adoption math. The Cloud Native Computing Foundation found that “91% of organizations reported using containers in production, up from 80% in 2023,” and separately that “80% of organizations reported running Kubernetes in production in 2024, compared with 66% in 2023,” according to the CNCF 2024 Annual Survey. Containers stopped being an experiment years ago; the open question now is who operates the hosts underneath them. Fargate’s answer is: nobody on your team has to.

Fargate bills by the second for the vCPU, memory, operating system, CPU architecture, and storage a task actually consumes, rounded up to the nearest second, from the moment the container image starts downloading until the task or pod terminates. That billing model is the backbone of the cost section later And it is also why right-sizing a task definition is worth the extra ten minutes it takes.

How AWS Fargate Actually Works Under the Hood

Every Fargate task runs inside its own lightweight virtual machine built on Firecracker, the microVM technology AWS also uses for Lambda. That design choice is why Fargate can offer hard security isolation between tasks that belong to different customers, or even different tasks from the same customer, without the overhead of a full traditional virtual machine. Each microVM boots with only the kernel and resources needed for that one task, then gets discarded the moment the task stops. There is no shared kernel between your workload and a neighbor’s, which is a meaningfully stronger isolation boundary than a traditional container host running dozens of containers from different teams on one shared Linux kernel.

This also explains two things that confuse people coming from EC2-backed ECS. First, there is no SSH access to the underlying host, because there effectively is no persistent host from your perspective; AWS manages the fleet of physical machines running these microVMs behind the scenes and rotates workloads across it continuously. Second, a Fargate task’s “cold start” is really a microVM boot plus an image pull, which is why container image size and base layer choice have an outsized effect on how quickly a new task becomes healthy behind a load balancer. A 2 GB image with a bloated base layer can easily take two or three times longer to reach a running state than the 80 MB slim image built in Step 1 of this tutorial.

Prerequisites: Tools, Versions, and Account Setup

Before touching the AWS console, get the local tooling right. Version mismatches are the single most common reason a Fargate deployment fails on the first attempt, so confirm every item below.

  • An AWS account with administrator access or, at minimum, permissions for ECS, ECR, IAM, VPC, CloudWatch, and Application Load Balancer.
  • AWS CLI version 2.17 or later. Run aws --version to confirm; Fargate-related commands assume CLI v2 syntax.
  • Docker Desktop or Docker Engine 25.0 or later, so you can build and test the container image locally before pushing it.
  • A terminal with jq installed; several commands Parse JSON output and it makes the examples far more readable.
  • A domain or at least a willingness to use the Application Load Balancer’s default DNS name for testing.
  • Roughly 70 minutes of uninterrupted time. Most of it is waiting on AWS resources to reach a steady state, not typing commands.

You do not need to install anything related to ECS agents, container runtimes, or host operating systems. That is the entire point of Fargate: AWS owns the box, you own the task definition.

Step 1 to 3: Build, Tag, and Push Your Container Image to Amazon ECR

Fargate needs an image sitting somewhere it can pull from. Amazon Elastic Container Registry (ECR) is the obvious choice because it is already wired into IAM permissions and sits in the same region as your ECS cluster, which keeps pull latency low.

Step 1: Write a minimal Dockerfile

Keep the base image small. A slim Node.js or Python image pulls faster, and pull time is part of what you pay for on Fargate.

FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

Step 2: Build and test the image locally

Build for linux/amd64 explicitly if you are developing on an Apple Silicon Mac, since Fargate’s default Linux/X86 task family expects that architecture unless you specifically opt into Graviton, which the sections below cover in the advanced tips section.

docker build --platform linux/amd64 -t fargate-demo-app:latest .
docker run -p 3000:3000 fargate-demo-app:latest
curl http://localhost:3000/health

Step 3: Create an ECR repository and push the image

Create the repository, authenticate Docker against it, then tag and push.

aws ecr create-repository --repository-name fargate-demo-app --region us-east-1

aws ecr get-login-password --region us-east-1 | \
  docker login --username AWS --password-stdin \
  123456789012.dkr.ecr.us-east-1.amazonaws.com

docker tag fargate-demo-app:latest \
  123456789012.dkr.ecr.us-east-1.amazonaws.com/fargate-demo-app:latest

docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/fargate-demo-app:latest

Replace the account ID with your own throughout this tutorial. The pattern is identical for Python, Go, or Java images; only the Dockerfile changes.

Step 4: Create a Fargate-Ready ECS Cluster

An ECS cluster on Fargate is mostly a logical namespace. There are no EC2 instances to register, which is the fastest way to tell a Fargate cluster apart from an EC2-backed one at a glance.

aws ecs create-cluster \
  --cluster-name fargate-demo-cluster \
  --capacity-providers FARGATE FARGATE_SPOT \
  --default-capacity-provider-strategy capacityProvider=FARGATE,weight=1

Registering both FARGATE and FARGATE_SPOT as capacity providers now means you can shift workload between them later with a single service update, instead of recreating the cluster.

Step 5: Write the Fargate Task Definition

The task definition is where Fargate differs most sharply from EC2-backed ECS. CPU and memory have to be declared at the task level, and only specific combinations are valid. AWS’s documentation lays out the exact matrix for Linux tasks:

Task vCPUValid memory rangeMemory incrementMinimum platform version
0.25 vCPU512 MB to 2 GB512 MB / 1 GB steps1.0.0
0.5 vCPU1 GB to 4 GB1 GB1.0.0
1 vCPU2 GB to 8 GB1 GB1.0.0
2 vCPU4 GB to 16 GB1 GB1.0.0
4 vCPU8 GB to 30 GB1 GB1.0.0
8 vCPU16 GB to 60 GB4 GB1.4.0 (Linux)
16 vCPU32 GB to 120 GB8 GB1.4.0 (Linux)

Pick the smallest combination that comfortably runs your application under real load, then add headroom for traffic spikes rather than guessing high from the start. A task definition in JSON form looks like this:

{
  "family": "fargate-demo-task",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "512",
  "memory": "1024",
  "executionRoleArn": "arn:aws:iam::123456789012:role/fargateExecutionRole",
  "taskRoleArn": "arn:aws:iam::123456789012:role/fargateTaskRole",
  "containerDefinitions": [
    {
      "name": "fargate-demo-app",
      "image": "123456789012.dkr.ecr.us-east-1.amazonaws.com/fargate-demo-app:latest",
      "portMappings": [{ "containerPort": 3000, "protocol": "tcp" }],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/fargate-demo-task",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "ecs"
        }
      }
    }
  ]
}

Save this as task-definition.json. The 512 CPU units and 1024 MiB memory shown here map to the 0.5-vCPU row in the table above, a reasonable starting point for a small API service.

Adding a sidecar container for log forwarding

A single task definition can run more than one container, sharing the same network namespace and, optionally, mounted volumes. The most common reason to do this on Fargate is a sidecar: a second small container running alongside the main application to forward logs to a third-party aggregator, handle TLS termination, or run a service mesh proxy. Because the sidecar shares the task’s vCPU and memory pool, it has to be accounted for in the sizing decision from the earlier table, not treated as free.

{
  "containerDefinitions": [
    {
      "name": "fargate-demo-app",
      "image": "123456789012.dkr.ecr.us-east-1.amazonaws.com/fargate-demo-app:latest",
      "portMappings": [{ "containerPort": 3000, "protocol": "tcp" }],
      "dependsOn": [{ "containerName": "log-router", "condition": "START" }]
    },
    {
      "name": "log-router",
      "image": "amazon/aws-for-fluent-bit:latest",
      "firelensConfiguration": { "type": "fluentbit" },
      "memoryReservation": 50
    }
  ]
}

The dependsOn condition ensures the log router container reaches a running state before the application container starts, which avoids a short window where early application logs have nowhere to go. Keep sidecars as small as realistically possible; a 50 MiB memory reservation for a log router is typical, and padding it unnecessarily just eats into the budget available for the actual application.

Step 6: Configure IAM Roles for Fargate

Fargate tasks need two distinct IAM roles, and conflating them is a common source of confusing permission errors.

  • The execution role lets ECS pull the image from ECR and write logs to CloudWatch on your behalf, before your application code even runs.
  • The task role is assumed by your application at runtime, for example to read from an S3 bucket or write to a DynamoDB table.
aws iam create-role \
  --role-name fargateExecutionRole \
  --assume-role-policy-document file://ecs-trust-policy.json

aws iam attach-role-policy \
  --role-name fargateExecutionRole \
  --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy

aws iam create-role \
  --role-name fargateTaskRole \
  --assume-role-policy-document file://ecs-trust-policy.json

The trust policy file needs ecs-tasks.amazonaws.com listed as the trusted principal. Attach only the permissions your application actually needs to the task role; the execution role should stay limited to ECR and CloudWatch Logs.

Step 7: Set Up VPC Networking and Security Groups

Fargate tasks always run in awsvpc network mode, which means every task gets its own elastic network interface and private IP address inside your VPC, the same way an EC2 instance would. You need at least two subnets across different availability zones for a production-grade setup, plus a security group that allows inbound traffic on your container port only from the load balancer’s security group, not from the open internet.

aws ec2 create-security-group \
  --group-name fargate-task-sg \
  --description "Fargate task security group" \
  --vpc-id vpc-0123456789abcdef0

aws ec2 authorize-security-group-ingress \
  --group-id sg-0123456789abcdef0 \
  --protocol tcp --port 3000 \
  --source-group sg-0fedcba9876543210

If your tasks need outbound internet access to pull images or call external APIs and you placed them in private subnets, add a NAT gateway. Running tasks in public subnets with public IPs assigned works for a quick test but is not the pattern to carry into production.

Step 8 and 9: Register the Task and Launch a Load-Balanced Service

With the role ARNs and networking in place, register the task definition and create the Application Load Balancer target group the service will attach to.

aws ecs register-task-definition --cli-input-json file://task-definition.json

aws elbv2 create-target-group \
  --name fargate-demo-tg \
  --protocol HTTP --port 3000 \
  --vpc-id vpc-0123456789abcdef0 \
  --target-type ip \
  --health-check-path /health

aws ecs create-service \
  --cluster fargate-demo-cluster \
  --service-name fargate-demo-service \
  --task-definition fargate-demo-task \
  --desired-count 2 \
  --launch-type FARGATE \
  --network-configuration "awsvpcConfiguration={subnets=[subnet-aaa,subnet-bbb],securityGroups=[sg-0123456789abcdef0],assignPublicIp=DISABLED}" \
  --load-balancers "targetGroupArn=arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/fargate-demo-tg/abc123,containerName=fargate-demo-app,containerPort=3000"

Note --target-type ip on the target group. Fargate tasks do not register with a load balancer the way EC2 instances do; they register by IP address, since there is no instance ID to point to. Forgetting this flag is one of the most common setup mistakes, covered in more detail in the pitfalls section below.

Step 10: Configure Service Auto Scaling

Fargate services scale the same way EC2-backed ECS services do, through Application Auto Scaling policies attached to the service’s desired count. Register the service as a scalable target, then attach a target-tracking policy on CPU utilization.

aws application-autoscaling register-scalable-target \
  --service-namespace ecs \
  --resource-id service/fargate-demo-cluster/fargate-demo-service \
  --scalable-dimension ecs:service:DesiredCount \
  --min-capacity 2 --max-capacity 10

aws application-autoscaling put-scaling-policy \
  --service-namespace ecs \
  --resource-id service/fargate-demo-cluster/fargate-demo-service \
  --scalable-dimension ecs:service:DesiredCount \
  --policy-name cpu-target-tracking \
  --policy-type TargetTrackingScaling \
  --target-tracking-scaling-policy-configuration \
  '{"TargetValue":60.0,"PredefinedMetricSpecification":{"PredefinedMetricType":"ECSServiceAverageCPUUtilization"}}'

A target of 60 percent CPU utilization leaves enough room for a traffic burst to be absorbed while new tasks spin up, which typically takes under a minute on Fargate since there is no EC2 instance to boot first.

Step 11: Add CloudWatch Logging and Container Insights

The awslogs driver configured in the task definition already streams container stdout and stderr to CloudWatch Logs. Create the log group before the first deployment so the task does not fail at startup looking for a destination that does not exist.

aws logs create-log-group --log-group-name /ecs/fargate-demo-task
aws logs put-retention-policy --log-group-name /ecs/fargate-demo-task --retention-in-days 30

For deeper visibility into per-task CPU, memory, network, and storage metrics without instrumenting your own code, enable Container Insights on the cluster. It costs extra because it ships custom CloudWatch metrics, so turn it on for production clusters and leave it off for throwaway test environments.

Step 12 and 13: Apply Fargate Spot for Savings, Then Tear Down

Fargate Spot runs interruption-tolerant tasks on spare AWS capacity at up to a 70 percent discount off standard Fargate pricing. It is not a fit for every workload, since AWS can reclaim the capacity with a two-minute warning, but for batch jobs, CI runners, and stateless web tiers behind a load balancer with enough replicas, it is close to free money.

aws ecs update-service \
  --cluster fargate-demo-cluster \
  --service fargate-demo-service \
  --capacity-provider-strategy \
    capacityProvider=FARGATE,weight=1,base=1 \
    capacityProvider=FARGATE_SPOT,weight=3

This strategy keeps one guaranteed on-demand task running at all times (base=1 on standard FARGATE) while routing roughly three out of every four additional tasks to FARGATE_SPOT. When you are done testing, tear everything down in reverse order so nothing keeps billing in the background:

aws ecs update-service --cluster fargate-demo-cluster --service fargate-demo-service --desired-count 0
aws ecs delete-service --cluster fargate-demo-cluster --service fargate-demo-service
aws elbv2 delete-target-group --target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/fargate-demo-tg/abc123
aws ecs delete-cluster --cluster fargate-demo-cluster
aws ecr delete-repository --repository-name fargate-demo-app --force

Scaling the service to zero before deleting it avoids orphaned tasks that keep running, and keep running up a bill, even after the service object itself is gone.

Debugging Running Tasks with ECS Exec

Because there is no host to SSH into, Fargate relies on ECS Exec for interactive debugging, which opens a secure shell session directly into a running container through the SSM Session Manager plugin rather than a traditional SSH connection. It needs to be enabled explicitly, since it is off by default for security reasons, and it requires the task role to carry the SSM messages permissions shown below.

aws ecs update-service \
  --cluster fargate-demo-cluster \
  --service fargate-demo-service \
  --enable-execute-command

aws ecs execute-command \
  --cluster fargate-demo-cluster \
  --task arn:aws:ecs:us-east-1:123456789012:task/fargate-demo-cluster/abcd1234 \
  --container fargate-demo-app \
  --command "/bin/sh" \
  --interactive

Running tasks have to be restarted after enabling execute command on an existing service, since it is baked into the task at launch time rather than toggled live. Once inside, treat it like any other production shell: it is useful for checking environment variables, inspecting a stuck process, or tailing a file that is not making it into the CloudWatch log stream, but it is not a substitute for the application actually logging what it is doing.

Tagging Tasks for Cost Allocation and FinOps Visibility

A Fargate bill with dozens of services and no tags attached is close to unreadable once a company runs more than a handful of workloads. Cost allocation tags applied to the service, and propagated down to each task, let the Cost Explorer and billing reports break spending down by team, environment, or product line instead of showing one undifferentiated ECS line item.

aws ecs tag-resource \
  --resource-arn arn:aws:ecs:us-east-1:123456789012:service/fargate-demo-cluster/fargate-demo-service \
  --tags key=team,value=platform-eng key=environment,value=production key=cost-center,value=cc-4471

Set propagateTags=SERVICE on the ECS service definition so every task launched by that service inherits the same tags automatically, rather than tagging each task by hand after the fact. Activate the tags as cost allocation tags in the AWS Billing console once, and within a day they start appearing as filterable columns in Cost Explorer. This is the same groundwork that makes a tool like Kubecost useful on the Kubernetes side, covered in the Kubecost and OpenCost tutorial, except here it is native to ECS with no extra software to install.

AWS Fargate Pricing in October 2026

Fargate’s published on-demand rates for the US East (N. Virginia) region break down by architecture and operating system. The table below converts AWS’s per-second figures into the more familiar per-hour rate.

ConfigurationvCPU rate (per hour)Memory rate (per GB, per hour)Notes
Linux / x86$0.04048$0.00445Default Fargate configuration
Linux / ARM (Graviton)$0.03238$0.00356About 20% cheaper per unit than x86
Windows / x86$0.09150$0.01000Plus a separate per-vCPU OS charge of $0.04600
Fargate Spot (any supported arch)Up to 70% off the on-demand rateUp to 70% off the on-demand rateCapacity can be reclaimed with a two-minute warning

Run the math on the 0.5-vCPU, 1-GB task used in this tutorial: at Linux/x86 on-demand rates, two tasks running continuously for a month cost roughly 0.5 x $0.04048 x 2 x 730 hours for compute, plus 1 x $0.00445 x 2 x 730 hours for memory, which lands just under $36 a month before any load balancer or data transfer charges. Switch the same workload to Graviton and the compute line drops by about a fifth. Switch it to Fargate Spot and it drops further still, assuming the workload tolerates interruption. There are no upfront costs or reserved capacity commitments required to access any of these rates; Fargate pricing is pay-as-you-go by design.

AWS Fargate vs AWS Lambda vs EC2: Choosing the Right Compute

Fargate is not the only serverless-adjacent compute option on AWS, and it is not always the right one. The decision usually comes down to request duration, state, and how much control you need over the runtime.

FactorAWS FargateAWS LambdaEC2 (self-managed)
Billing granularityPer second, by vCPU and memoryPer millisecond, by memory and invocationsPer second, by instance
Max runtime per task/requestNo hard limit on task duration15 minutes per invocationNo limit
Cold start behaviorTasks typically ready in under a minuteMilliseconds to a few seconds depending on runtimeMinutes, since an instance must boot
Best fitLong-running services, APIs, background workers packaged as containersShort, event-driven functions and glue codeSpecialized OS, kernel, or licensing requirements
Operational overheadNone at the host levelNone at any levelPatching, scaling, and capacity planning required

If you are building a steadily running API that needs a full Linux filesystem, specific binaries, or a long-lived in-memory cache, Fargate fits better than Lambda’s strict 15-minute execution ceiling. If your workload is short, bursty, and event-triggered, Lambda usually costs less because you are not paying to keep anything warm between invocations. EC2 still wins when you need GPU instances, licensed software with per-core pricing, or kernel-level customization that containers cannot provide. For a deeper breakdown of serverless function pricing specifically, see the comparison of Lambda, Azure Functions, and Cloud Run on this site.

Common Pitfalls When Deploying to Fargate

Most first Fargate deployments fail for a small, repeatable set of reasons. Check these before filing a support ticket.

  • Using instance target type instead of IP target type. Fargate tasks have no EC2 instance ID to register with a load balancer. The target group must use --target-type ip, or the service will never pass health checks.
  • Forgetting assignPublicIp=ENABLED in public subnets without a NAT gateway. Without a public IP or a NAT path, a task in a public subnet cannot reach ECR to pull its own image and fails before the container even starts.
  • Mixing up the execution role and the task role. Attaching S3 or DynamoDB permissions to the execution role instead of the task role means the application code never actually gets those permissions at runtime.
  • Requesting an invalid CPU and memory combination. Fargate rejects task definitions that do not match the official matrix, for example 1 vCPU paired with 10 GB of memory, which is outside the valid 2 to 8 GB range for that CPU size.
  • Skipping the health check path. If the container’s health check endpoint does not match what the target group expects, ECS will cycle tasks indefinitely, each one looking “unhealthy” seconds after starting.
  • Running 8-vCPU or larger tasks on an old platform version. Those sizes require Linux platform version 1.4.0 or later; pinning an old platform version silently blocks the larger task sizes.
  • Not setting a log group before first deploy. If the CloudWatch Logs group referenced in the task definition does not already exist and the execution role lacks permission to create it, the task fails immediately on startup.

Troubleshooting AWS Fargate Deployments

When something breaks, the ECS console’s “Stopped reason” field and the task’s CloudWatch log stream are the first two places to look, in that order, since the stopped reason often names the exact failure category before you even open a log. Run aws ecs describe-tasks --cluster fargate-demo-cluster --tasks TASK_ID from the CLI if you prefer scripting the check instead of clicking through the console. These are the issues that come up most often.

  • Task stops immediately with “CannotPullContainerError.” Usually a networking issue: the task cannot reach ECR. Check that the subnet has a route to a NAT gateway or that the task has a public IP, and confirm the security group allows outbound HTTPS.
  • “ResourceInitializationError: unable to pull secrets.” The execution role is missing secretsmanager:GetSecretValue or ssm:GetParameters permissions for any secrets referenced in the task definition.
  • Service stuck at “PROVISIONING” for several minutes. Often capacity related; check that the chosen AWS Region and availability zone actually have Fargate capacity for the requested vCPU and memory combination, especially for larger task sizes.
  • Load balancer shows targets as “unhealthy” even though the container is running. Confirm the health check path returns a 200 status code and that the target group’s port matches the container port, not the host port, since there is no host port mapping on Fargate.
  • Tasks keep getting killed with exit code 137. That is an out-of-memory kill. Increase the task’s memory allocation or investigate a memory leak in the application itself.
  • Auto scaling never triggers. Confirm the scalable target was registered with the exact resource ID format service/cluster-name/service-name, and that CloudWatch is actually receiving the ECSServiceAverageCPUUtilization metric for that service.
  • Fargate Spot tasks disappear without warning in logs. AWS sends a two-minute SIGTERM warning before reclaiming Spot capacity; applications need a signal handler for graceful shutdown, or in-flight requests will simply drop.
  • Deployment rolls back with “service was unable to place a task.” Usually means the chosen subnets have run out of available IP addresses, since every task consumes one in awsvpc mode. Use a larger subnet CIDR block or add additional subnets.
  • Logs never show up in CloudWatch. Double check the awslogs-group name matches exactly what was created with aws logs create-log-group, including case sensitivity.

Advanced Tips for Production Fargate Workloads

Once the basic service is running reliably, a handful of changes separate a demo from a production-grade deployment.

Move to Graviton where the application supports ARM64. Rebuilding the container for linux/arm64 and switching the task definition’s runtime platform to ARM64 cuts the vCPU and memory rate by roughly 20 percent with no code changes required for most interpreted languages and many compiled ones, provided your base image and dependencies ship ARM64 builds.

Consider Bottlerocket for the underlying platform where available. AWS also offers Fargate platform options tuned around Bottlerocket, a minimal, security-focused container operating system, which reduces the attack surface compared to a general-purpose Linux platform.

Use EKS Fargate profiles if the team is Kubernetes-native. Instead of managing ECS task definitions, a Fargate profile lets specific Kubernetes namespaces schedule pods onto Fargate automatically, no kubectl get nodes required, which fits teams that already standardized on Helm charts and Kubernetes manifests elsewhere in the organization. This is a natural complement to Terraform-managed Kubernetes clusters that need a no-ops compute lane for a subset of workloads.

Right-size with real utilization data, not guesses. Container Insights or a third-party cost tool can show the actual CPU and memory utilization of running tasks over a week of production traffic. If a 1-vCPU task consistently uses 15 percent CPU, moving to a 0.5-vCPU allocation is nearly free money every month. This is the same discipline covered in the Kubecost and OpenCost monitoring tutorial, applied to ECS tasks instead of Kubernetes pods.

Set ephemeral storage deliberately. Fargate tasks on platform version 1.4.0 and later support configurable ephemeral storage beyond the default allotment, which matters for workloads that write large temp files, build artifacts, or process media during a request.

Pin a specific platform version once the service is stable. Leaving a production task definition on LATEST means a future AWS platform rollout could change behavior under your service without warning. Pinning to a known platform version, for example 1.4.0 explicitly instead of LATEST, keeps upgrades deliberate rather than automatic.

The Complete Working Project, End to End

Strip away the explanations and the full project is five files and a short sequence of commands: a Dockerfile, a task-definition.json, an ecs-trust-policy.json for IAM, and the CLI commands shown in Steps 1 through 13 above, run in order. The sequence is: build and push the image to ECR, create the cluster with both capacity providers registered, create the IAM roles, register the task definition, create the target group and service with IP-based load balancer registration, attach auto scaling, create the log group, and finally shift a portion of capacity to Fargate Spot. Running every command block Top to bottom, with your own account ID, VPC ID, and subnet IDs substituted in, produces a working, load-balanced, auto-scaling, cost-optimized container service with nothing left running on a server you have to patch.

From here, the natural next step for most teams is wiring this same task definition into a CI/CD pipeline that calls aws ecs update-service --force-new-deployment after every successful build, so new container images roll out automatically without anyone running these commands by hand again. Teams weighing AWS against other clouds for this kind of workload can compare notes with the AWS vs Azure vs GCP cost breakdown published separately, and anyone still deciding between ECS and EKS as the control plane for Fargate should read the ECS vs EKS cost comparison first.

Frequently Asked Questions

Is AWS Fargate more expensive than running ECS on EC2?
Per-vCPU, Fargate typically costs more than an equivalent EC2 instance on-demand, since you are paying for the convenience of not managing the host. The trade-off is operational: Fargate removes patching, scaling the underlying hosts, and capacity planning entirely, which for most teams is worth the premium on anything other than very large, steady-state workloads where a reserved or Savings Plan-backed EC2 fleet can undercut it on pure compute cost.

Can AWS Fargate run Windows containers?
Yes. Fargate supports Windows Server 2019 Full and Core edition platforms, billed at a higher per-vCPU and per-GB rate than Linux, plus a separate per-vCPU Windows OS charge. Expect slower task startup times on Windows compared with Linux, since the Windows base images involved are substantially larger.

What is the maximum task size on Fargate?
The documented matrix tops out at 16 vCPU with up to 120 GB of memory on Linux platform version 1.4.0 or later. Smaller combinations down to 0.25 vCPU with 512 MB of memory are available for lightweight services.

Does Fargate support GPU workloads?
No. Fargate does not currently offer GPU-backed task types. GPU-dependent workloads, such as model inference or training, need EC2-backed ECS or EKS with GPU instance types instead.

How is Fargate different from Fargate Spot?
Fargate Spot runs the exact same task definitions on spare AWS capacity at up to a 70 percent discount, with the tradeoff that AWS can reclaim that capacity with a two-minute warning. It is a capacity provider choice at the service level, not a separate product.

Can I use Fargate with Amazon EKS instead of ECS?
Yes. EKS Fargate profiles let specific Kubernetes namespaces run pods on Fargate without provisioning or managing any EC2 worker nodes, selected by namespace and label matching rules.

Why does my Fargate task fail with a networking error even though the security group looks correct?
Check the subnet route table first. A private subnet without a route to a NAT gateway cannot reach ECR or the internet at all, regardless of how the security group is configured.

Is there a free tier for AWS Fargate?
AWS has offered limited Fargate free tier allowances for new accounts in the past, covering a small amount of vCPU and memory hours per month. Check the current AWS Free Tier page for the exact allowance active on your account type, since free tier offers change over time.

Related Coverage

Yusuf Demir

Yusuf Demir

Cloud & Software Reporter

Yusuf Demir is the Cloud & Software Reporter at TrendinTech, where he covers cloud infrastructure, enterprise platforms, developer tools and the digital transformation of businesses in the UK and the United States. He is most interested in the gap between vendor roadmaps and the systems engineers actually run, and in what the cloud bill looks like once the free credits expire.

All stories by Yusuf Demir (348)

Related Articles