OpsCanary
kubernetesPractitioner

Mastering Gradual Deployments in Amazon ECS: Linear vs. Canary Strategies

5 min read AWS Containers BlogMay 8, 2026Reviewed for accuracy
Share
PractitionerHands-on experience recommended

In today's fast-paced development environment, gradual deployments are crucial for reducing the risk of introducing bugs and performance issues. By implementing strategies like linear and canary deployments in Amazon ECS, you can shift traffic incrementally and observe the new version's behavior before fully committing. This approach allows for safer rollouts and quicker rollbacks if something goes wrong.

When you configure linear or canary deployments, Amazon ECS utilizes Elastic Load Balancing weighted target groups and CloudWatch alarms to manage traffic shifting and automate rollbacks. Linear deployments shift traffic in equal increments, allowing you to set a configurable bake time at each stage. On the other hand, canary deployments route a small percentage of traffic to the new version for an extended observation period, giving you time to validate performance and stability. Key configuration parameters include minimumHealthyPercent, which controls the minimum number of healthy tasks during a rolling deployment, and maximumPercent, which dictates the maximum number of tasks that can be running.

In production, ensure you have the right prerequisites in place: an Amazon ECS cluster, a load balancer with two target groups, and the necessary IAM roles. Be cautious of the potential pitfalls, such as misconfigured alarms that could lead to undetected issues during the deployment process. The official docs don't call out specific anti-patterns here. Use your judgment based on your scale and requirements.

Key takeaways

  • Configure linear deployments to shift traffic in equal increments with a configurable bake time.
  • Utilize canary deployments to route a small percentage of traffic for extended observation.
  • Set up CloudWatch alarms to monitor 5XX errors and high latency across target groups.
  • Ensure you have the necessary IAM roles for managing load balancer target group weights.
  • Validate performance and stability before fully committing to a new version.

Why it matters

Gradual deployments significantly reduce the risk of downtime and user impact during application updates, allowing teams to deliver features faster and with greater confidence.

Code examples

Bash
1# Create alarm for 5XX errors across both target groups
2aws cloudwatch put-metric-alarm \
3  --alarm-name my-service-5xx-errors \
4  --alarm-description "Trigger on high 5XX error rate across both target groups" \
5  --metrics '[\n    {\n      "Id": "blue5xx",\n      "MetricStat": {\n        "Metric": {\n          "Namespace": "AWS/ApplicationELB",\n          "MetricName": "HTTPCode_Target_5XX_Count",\n          "Dimensions": [\n            {"Name": "TargetGroup", "Value": "targetgroup/blue/xxx"},\n            {"Name": "LoadBalancer", "Value": "app/my-load-balancer/xxx"}\n          ]\n        },\n        "Period": 60,\n        "Stat": "Sum"\n      },\n      "ReturnData": false\n    },\n    {\n      "Id": "green5xx",\n      "MetricStat": {\n        "Metric": {\n          "Namespace": "AWS/ApplicationELB",\n          "MetricName": "HTTPCode_Target_5XX_Count",\n          "Dimensions": [\n            {"Name": "TargetGroup", "Value": "targetgroup/green/xxx"},\n            {"Name": "LoadBalancer", "Value": "app/my-load-balancer/xxx"}\n          ]\n        },\n        "Period": 60,\n        "Stat": "Sum"\n      },\n      "ReturnData": false\n    },\n    {\n      "Id": "total5xx",\n      "Expression": "SUM([blue5xx, green5xx])",\n      "Label": "Total 5XX Errors",\n      "ReturnData": true\n    }\n  ]' \
6  --evaluation-periods 2 \
7  --threshold 10 \
8  --comparison-operator GreaterThanThreshold
Bash
# Create alarm for high latency across both target groups
aws cloudwatch put-metric-alarm \
  --alarm-name my-service-high-latency \
  --alarm-description "Trigger on high response time across both target groups" \
  --metrics '[\n    {\n      "Id": "blueLatency",\n      "MetricStat": {\n        "Metric": {\n          "Namespace": "AWS/ApplicationELB",\n          "MetricName": "TargetResponseTime",\n          "Dimensions": [\n            {"Name": "TargetGroup", "Value": "targetgroup/blue/xxx"},\n            {"Name": "LoadBalancer", "Value": "app/my-load-balancer/xxx"}\n          ]\n        },\n        "Period": 60,\n        "Stat": "Average"\n      },\n      "ReturnData": false\n    },\n    {\n      "Id": "greenLatency",\n      "MetricStat": {\n        "Metric": {\n          "Namespace": "AWS/ApplicationELB",\n          "MetricName": "TargetResponseTime",\n          "Dimensions": [\n

When NOT to use this

The official docs don't call out specific anti-patterns here. Use your judgment based on your scale and requirements.

Want the complete reference?

Read official docs

Test what you just learned

Quiz questions written from this article

Take the quiz →
Better StackSponsor

Unified observability — logs, uptime monitoring, and on-call in one place. Used by 50,000+ engineering teams to ship faster and sleep better.

Try Better Stack free →

Get the daily digest

One email. 5 articles. Every morning.

No spam. Unsubscribe anytime.