Argo Rollouts vs Flagger: Progressive Delivery ADR for 2026
Most teams that pick between Argo Rollouts and Flagger pick on brand affinity. They run Argo CD, so they choose Argo Rollouts. They run Flux, so they choose Flagger. That heuristic is right often enough to survive, and wrong in the cases that cost you a weekend: a Deployment you cannot rewrite, a Gateway API data plane the plugin does not fully cover, a metric you need that exists in one tool’s analysis model and not the other’s.
The decision matters more in 2026 than it did three years ago. Kubernetes has largely settled on Gateway API as the standard way to express traffic weights, which means both projects now speak a common routing dialect, and the real differences have moved up a layer: who owns the workload object, how the analysis loop is expressed, and how each tool behaves when GitOps tries to fight it.
This post is written as an Architecture Decision Record. Argo Rollouts vs Flagger is compared on mechanism, not feature checklists, so you can defend the choice in a design review. By the end you will have a decision matrix, config for both tools against a Gateway API HTTPRoute, the failure modes each one hides, and a rollout plan that does not require rewriting your fleet.
What this covers: the state of both projects as of October 2026, the two ownership models, traffic shaping and Gateway API support, analysis and metric gating, GitOps interaction, a decision matrix, failure modes, and a recommended default.
Context and Background
Progressive delivery is the practice of exposing a new version to a controlled fraction of traffic, measuring it against objective criteria, and promoting or reverting automatically. Plain Kubernetes Deployments offer a rolling update, which replaces pods gradually but has no concept of traffic percentages, no metric gate, and no automatic rollback on a bad error rate. It only knows about pod readiness. A pod that is ready and returning HTTP 500 on every third request passes a rolling update without complaint.
Two CNCF-hosted projects fill that gap. Argo Rollouts is part of the Argo project and ships a Rollout custom resource that replaces the Deployment. Flagger is part of the Flux project and ships a Canary custom resource that sits beside an existing Deployment and orchestrates it. Both implement the same loop: shift traffic, query metrics, compare against thresholds, continue or abort. Both support canary and blue/green. The disagreement is almost entirely about where the control plane sits relative to your workload.
Version facts, verified against the official repositories and docs on 2026-10-01: the Argo Rollouts releases page lists v1.10.0, dated August 27, 2026, with notes mentioning improved weight-setting behavior during canary scaling, better error detection for infrastructure issues in AnalysisRun metrics, reduced controller memory use through ReplicaSet informer filtering, and plugin capabilities extended to traffic mirroring and ping-pong patterns beyond Istio. For Flagger, the GitHub releases page we fetched showed v1.44.0 as latest, while the project changelog we fetched describes a v1.45.0 from September 2026 that adds an Azure Monitor Workspace metrics provider and Linkerd port-discovery fixes. Because those two sources disagree, treat the exact Flagger patch number as something to confirm on the day you install; the capabilities discussed here are stable across both.
If you are already weighing Gateway API against ingress, our Kubernetes Gateway API vs Ingress comparison covers the routing layer both tools now target. For the edge-fleet angle on Rollouts specifically, see Argo Rollouts progressive delivery for edge fleets. The upstream docs are at the Argo Rollouts documentation and the Flagger documentation.
Why the question is harder than it looks
Both tools can run a ten percent canary, wait five minutes, check a Prometheus query, and go to fifty percent. If that were the whole job, you would flip a coin. The job is actually larger. It includes what happens when the cluster autoscaler is mid-scale, when a ConfigMap changes but the image does not, when two Git commits land during one analysis, when the metric backend is down, and when your GitOps controller sees the traffic weights the progressive tool wrote and decides they are drift.
Those are the scenarios where the two designs diverge, and they are the scenarios an ADR should record. The rest of this post works through them in order.
Two Ownership Models: Replace the Deployment or Wrap It
The shortest accurate summary: Argo Rollouts replaces the Deployment object with its own workload resource, and Flagger leaves the Deployment alone and builds a second copy beside it. Every other difference flows from that choice.

Figure 1: Both controllers run the same loop of shift traffic, query metrics, then promote or abort. They differ in what object they manage during the shift.
The diagram shows the shared shape. A new image tag lands in Git, the controller reacts, traffic weights change through a router, a metrics provider answers a query, and a decision gate promotes or aborts. In Argo Rollouts, the controller manages two ReplicaSets directly. In Flagger, it clones your Deployment into a primary and a canary and manages those.
Argo Rollouts: the Rollout object replaces the Deployment
A Rollout is a drop-in analog of a Deployment with a different apiVersion (argoproj.io/v1alpha1), a different kind, and a strategy block that is either canary or blueGreen. The official migration guide describes the conversion as exactly those three edits. The controller then owns the ReplicaSets itself, scaling a stable set and a canary set according to a steps list.
Because the controller owns the ReplicaSets, it has fine control over pod counts. It can run a canary at a ten percent traffic weight with a configurable number of canary pods, using a traffic router to decouple weight from replica ratio. Without a traffic router, Argo Rollouts approximates weights through pod counts, which is coarser but works on any cluster.
The cost is that your workload is no longer a Deployment. Anything that watches Deployments, such as certain autoscalers, cost tools, admission policies, dashboards and kubectl rollout muscle memory, has to learn about Rollouts. Argo Rollouts addresses this with workloadRef: the Rollout references an existing Deployment’s pod template instead of embedding its own, and a scaleDown field controls whether the Deployment stays (never), scales to zero after the Rollout stabilizes (onsuccess), or scales down as the Rollout scales up (progressively). The docs recommend running the Rollout next to the Deployment before deleting the Deployment when migrating live traffic, and note the temporary cost of duplicate pods.
Flagger: the Canary object wraps the Deployment
Flagger takes the opposite position. You keep your Deployment and add a Canary resource whose targetRef points at it. On first reconcile, Flagger creates a <name>-primary Deployment (a managed copy that serves production traffic), scales your original Deployment down to zero, and creates Services named <name>, <name>-primary and <name>-canary. When you change the original Deployment’s pod spec, that change becomes the canary, and Flagger runs analysis against it before copying it over to the primary.
The documented triggers for an analysis are a change to the Deployment PodSpec, or to ConfigMaps and Secrets mounted as volumes or mapped to environment variables. That last clause is a quiet advantage: a config-only change is treated as a release, with the same gating as an image change. In Argo Rollouts a ConfigMap change does not alter the pod template hash unless you version the ConfigMap name, so it can bypass the steps entirely.
The cost of wrapping is indirection. Your Deployment is a template that sits at zero replicas, the live pods belong to a Deployment called -primary that Flagger wrote, and anyone debugging at 3 a.m. has to know that. Replica changes need care too: Flagger’s FAQ says that without a HorizontalPodAutoscaler you update replicas on the canary Deployment and trigger an analysis by annotating the template.

Figure 2: Argo Rollouts swaps the workload kind and scripts the rollout as an ordered steps list. Flagger keeps the Deployment and runs a fixed interval loop.
Steps list versus interval loop
The second structural difference is how the rollout schedule is expressed. Argo Rollouts uses an explicit, ordered steps array: setWeight: 10, pause: {duration: 5m}, analysis: ..., setWeight: 50, and so on. You can mix a manual pause: {} (wait for a human promote command) with automated steps in a single rollout, which is the cleanest way to express “automate the first 20 percent, then require approval.”
Flagger uses a loop defined by interval, threshold, stepWeight and maxWeight. The docs give the promotion time as interval multiplied by maxWeight divided by stepWeight. With a 60-second interval (the documented default), stepWeight: 10 and maxWeight: 50, that is five steps and about five minutes before the final promotion. The loop is simple to reason about and hard to make irregular. Irregular schedules, such as a slow start and a fast finish, are possible with stepWeights lists and confirmation webhooks, but they take more assembly.
The steps array is more expressive; the loop is more predictable. Neither is wrong. If your release policy is “same shape for every service,” the loop is easier to template. If services need bespoke choreography, steps win.
Traffic Shaping and Gateway API Support
Traffic shaping is where the two tools used to differ most, because each grew its own list of integrations. In 2026 the useful question is no longer “which router do you support” but “how do you drive a Gateway API HTTPRoute,” because that is the interface most new clusters standardize on.
The upstream integration lists, from the official docs, look like this. Argo Rollouts lists native integrations for the AWS ALB Ingress Controller, Ambassador Edge Stack, Apache APISIX, Google Cloud, Istio, Kong Ingress, NGINX Ingress Controller, Service Mesh Interface and Traefik Proxy, and states that Gateway API is available through a plugin. Flagger’s deployment strategies page lists canary support for Istio, Linkerd, App Mesh, NGINX, Skipper, Contour, Gloo Edge, Traefik, Open Service Mesh, Kuma, Gateway API and Apache APISIX.
How each tool drives Gateway API
Flagger treats Gateway API as a first-class provider. Its tutorial states the requirement as Kubernetes v1.19 or newer and any mesh or ingress implementing the v1beta1 version of Gateway API, and notes that v1alpha2 still works but is deprecated and will be dropped in a future release. The changelog we fetched describes the route API progressing from v1alpha2 through v1beta1 to v1 support. When you create a Canary, Flagger generates the HTTPRoute that attaches to the Gateway you name in gatewayRefs, plus the canary and primary Deployments, Services and HorizontalPodAutoscalers. Flagger owns the HTTPRoute it creates, so your Git repo should not also define it.
Argo Rollouts does the opposite: you author the HTTPRoute, and the controller edits the backend weights in it. The rollouts-plugin-trafficrouter-gatewayapi plugin, registered in the Argo Rollouts ConfigMap, patches weights on the route rules that reference your stable and canary Services. Its documentation lists HTTPRoute, GRPCRoute, TCPRoute and TLSRoute among supported route types, and describes the pattern as working with any traffic provider that implements Gateway API. That route-type breadth is worth checking against your data plane: TCPRoute and TLSRoute live in the experimental channel of Gateway API, so your implementation may not serve them even though the plugin can write them. Our Gateway API 1.6 TCPRoute and UDPRoute analysis covers that channel boundary.
This is a genuine ownership difference. With Flagger, the route is output. With Argo Rollouts, the route is input that the controller mutates. The second model is friendlier to platform teams that already template routes with policies, header matches and filters; the first is less YAML to write.
Here is the Argo Rollouts side for an HTTP service:
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: checkout
spec:
replicas: 6
selector:
matchLabels:
app: checkout
template:
metadata:
labels:
app: checkout
spec:
containers:
- name: checkout
image: registry.example.com/checkout:2.4.1
strategy:
canary:
stableService: checkout-stable
canaryService: checkout-canary
trafficRouting:
plugins:
argoproj-labs/gatewayAPI:
httpRoute: checkout-route
namespace: shop
steps:
- setWeight: 10
- pause: {duration: 5m}
- analysis:
templates:
- templateName: success-rate
- setWeight: 50
- pause: {duration: 10m}
And the Flagger side, same intent:
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: checkout
namespace: shop
spec:
provider: gatewayapi:v1
targetRef:
apiVersion: apps/v1
kind: Deployment
name: checkout
service:
port: 80
hosts:
- checkout.example.com
gatewayRefs:
- name: public-gateway
namespace: gateway-system
analysis:
interval: 1m
threshold: 3
maxWeight: 50
stepWeight: 10
metrics:
- name: request-success-rate
thresholdRange:
min: 99
interval: 1m
Both snippets are illustrative and condensed; check field names against the current docs for your installed version before applying, since provider strings and plugin names have changed across releases. In particular, Flagger’s provider value for Gateway API has carried version suffixes, so confirm the exact string for your release.
Blue/green versus canary, and where mirroring fits
The blue green vs canary question is a traffic question, not a tool question. Blue/green keeps a full parallel copy and flips all traffic at once after verification. It costs double the pods for the duration but gives instant, complete rollback and a clean pre-promotion test window. Canary shifts incrementally, costs less capacity, and exposes real users to the new version progressively, which is what lets metric analysis catch problems at 10 percent instead of 100.
Flagger’s documentation shows blue/green on a wide set of providers, including plain Kubernetes with CNI-level switching, but blue/green mirroring (shadow traffic) is documented as Istio-only, as is canary with cookie-based session affinity. A/B testing on HTTP headers and cookies is documented for Istio, App Mesh, NGINX, Contour, Gloo Edge and Gateway API. Argo Rollouts covers the header-based routing case through setHeaderRoute and mirror steps for supported routers, and its v1.10.0 notes mention plugin support for mirroring beyond Istio. If shadow traffic is a hard requirement, verify the exact router combination in a test cluster before committing, because this is the area where documentation and implementation lag each other most.
Analysis and Metric Gating
A canary without analysis is a slow rolling update with extra steps. The analysis model determines whether the tool can express your actual definition of “healthy,” so it deserves the most scrutiny in the ADR.
Argo Rollouts: AnalysisTemplate and AnalysisRun
Argo Rollouts models analysis as separate resources. An AnalysisTemplate defines metrics, how often to measure, and success and failure conditions. A ClusterAnalysisTemplate is the cluster-scoped version for reuse across namespaces. An AnalysisRun is an instance created during a rollout that ends as Successful, Failed or Inconclusive, and that status directly drives progression.
Two execution models matter. Inline analysis is a step in the list that blocks progress until it finishes. Background analysis starts at a given step and runs continuously while the canary progresses, so a failure at minute eight aborts a rollout that is already at 50 percent. Background analysis is the more important feature in practice: it means a metric regression that appears late is still caught.
The documented knobs include interval, count, failureLimit, consecutiveSuccessLimit, and successCondition and failureCondition expressions. Supported providers in the docs are Prometheus, Datadog, NewRelic, Wavefront, CloudWatch, Graphite, InfluxDB and Apache SkyWalking, plus web and job-based analysis. The docs also state that no new metric integrations are accepted into the core controller; new providers must be plugins. That is a signal about maintenance posture: the provider list is effectively frozen in core, and growth happens in the plugin ecosystem.
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
spec:
args:
- name: service
metrics:
- name: success-rate
interval: 1m
count: 5
failureLimit: 1
successCondition: result[0] >= 0.99
provider:
prometheus:
address: http://prometheus.monitoring:9090
query: |
sum(rate(http_requests_total{service="{{args.service}}",code!~"5.."}[2m]))
/
sum(rate(http_requests_total{service="{{args.service}}"}[2m]))
Flagger: MetricTemplate, built-ins, and webhooks
Flagger’s analysis lives inside the Canary spec. It ships built-in checks such as request success rate and request duration for the mesh or ingress in use, which means a basic canary needs no query authoring at all. For custom signals you define a MetricTemplate resource with a provider and a query, and reference it from the Canary’s metrics list with a thresholdRange. The changelog we fetched lists Prometheus, Datadog, Splunk, Dynatrace, InfluxDB and Google Cloud Monitoring among providers, with Azure Monitor Workspace described as new in the September 2026 entry.
Flagger’s gating beyond metrics is webhook-based. Documented hook types include pre-rollout, rollout, confirm-rollout, confirm-promotion, post-rollout and rollback hooks, and load-test hooks that generate traffic so a quiet staging canary has something to measure. The confirmation hooks are how you insert a human or an external system, such as a change-management ticket, at specific gates.
The threshold semantics differ subtly. Flagger’s threshold is the number of failed metric checks tolerated before rollback across the analysis. Argo’s failureLimit is per-metric inside an AnalysisRun, and Inconclusive is a distinct third result that pauses the rollout for a human decision. That third state is useful for ambiguous signals and has no direct Flagger equivalent.

Figure 3: The same sequence works for both tools. Git delivers a revision, Argo CD or Flux applies it, and the controller alternates between setting a route weight and asking Prometheus whether the canary is healthy.
Figure 3 shows why the metric backend is the weak link. Between every weight change and every decision sits a query. If Prometheus is slow, stale, or missing a series for the canary because of a label mismatch, the controller sees either no data or a misleading ratio. Both tools handle missing data, but differently, and neither default is universally safe, which we return to in the failure-mode section.
A worked example of the timing math
Take a 60-second interval, stepWeight: 10, maxWeight: 50, threshold: 3 in Flagger. Promotion needs five consecutive healthy intervals to reach 50 percent, so a clean run takes about five minutes plus promotion time. A single bad interval does not abort; it increments a failure counter, and the third failure triggers rollback. A canary that fails intermittently, say every other interval, would hit three failures in roughly six minutes and roll back.
The Argo equivalent is the steps list above: ten percent, five-minute pause, analysis of five one-minute measurements allowing one failure, then 50 percent. Same wall-clock scale, but the failure budget is attached to the analysis run rather than the whole rollout. These numbers are arithmetic from documented parameters, not benchmarks; your real timing depends on scrape intervals and query windows. A two-minute rate() window in Prometheus means the first interval’s reading is mostly pre-canary data, so a one-minute loop reacts slower than its configuration suggests. Align your query window with your interval, or use a window shorter than the step duration.
GitOps Fit: Where Each Tool Fights Your Sync Engine
Progressive delivery controllers mutate live state: weights on a route, replica counts, Service selectors. A GitOps engine compares live state to Git and wants to revert differences. If you do not plan for that conflict, your canary gets reset to 0 percent mid-analysis, or your sync reports permanent OutOfSync.
Argo CD with Argo Rollouts
Argo CD and Argo Rollouts are sibling projects, and the integration is the smoothest in this space. Argo CD ships health assessment for the Rollout kind, so a rollout in the Progressing or Paused state shows as such in the UI instead of looking like a hung sync, and the Rollouts dashboard extension can surface promote and abort actions. For Rollouts with Gateway API, the controller edits HTTPRoute weights that Git also defines. The standard remedy is ignoreDifferences on the weight fields of the route, or a server-side apply configuration that leaves them to the controller. Our Argo CD 3 upgrade guide covers the diffing and tracking changes that interact with exactly this pattern, and is worth reading before you add ignoreDifferences rules to a v2-era configuration.
Flux with Flagger
Flagger is a Flux project and pairs naturally with Flux’s Kustomize and Helm controllers. Because Flagger owns generated objects, the primary Deployment, the Services and the generated HTTPRoute, the GitOps engine never sees them in Git and has nothing to revert, provided the engine does not prune objects it did not create. The one conflict is the original Deployment’s replica count: Flagger scales it to zero, and a naive reconciliation could scale it back. Flagger’s documentation handles this by treating the original Deployment as a template, and the common practice is to omit replicas from the Git manifest when an HPA is present.
Flagger works under Argo CD as well. It is not Flux-only; it is a standalone controller with a Flux home. Teams running Argo CD with Flagger need ignoreDifferences on the generated resources and care around Argo CD’s resource tracking. This is a real cost compared to the first-party Argo pairing, but it is a one-time configuration. For the broader Argo CD versus Flux choice that usually sits upstream of this one, see our Argo CD vs Flux decision record.
Who sees what: observability of a rollout in flight
Argo Rollouts has a kubectl plugin (kubectl argo rollouts get rollout checkout --watch) that renders the ReplicaSet tree, step index, weights and analysis runs in a terminal, and a standalone dashboard. For an on-call engineer, that single view answers “what step are we on, and why is it paused.” Flagger exposes state through the Canary resource status and conditions, emits Kubernetes events, and supports notifications to Slack, Microsoft Teams and similar systems through alert providers. It publishes its own Prometheus metrics for canary status and weights. The information is there, but you assemble the view yourself, usually in Grafana.
If your organization values a purpose-built rollout console, that is a real point in Argo’s favor. If your organization already centralizes everything in Grafana and chat-ops, Flagger’s approach is not a deficit.
Decision Matrix: Argo Rollouts vs Flagger
The matrix below summarizes the comparison. Ratings are my analytical judgment based on the documented behavior described above, not benchmark results. “Edge” means a meaningful advantage for typical use, not a guarantee.
| Criterion | Argo Rollouts | Flagger | Edge |
|---|---|---|---|
| Workload ownership | Replaces Deployment with Rollout; workloadRef allows reuse |
Wraps existing Deployment; no rewrite needed | Flagger for brownfield |
| Rollout schedule | Ordered steps with manual pauses and header routes |
Fixed interval loop with weight steps and webhooks | Argo for custom choreography |
| Gateway API | Plugin edits your HTTPRoute; HTTP, gRPC, TCP and TLS route types listed | Native provider; generates the HTTPRoute; v1beta1 or newer | Flagger for simplicity, Argo for control |
| Metric analysis | Separate AnalysisTemplate and AnalysisRun; background and inline; Inconclusive state | MetricTemplate plus built-in mesh metrics; webhooks | Argo for richness, Flagger for zero-config |
| New metric providers | Plugin only; none accepted into core | Provider list growing in core per changelog | Flagger |
| Config-change gating | ConfigMap change not a trigger unless pod template changes | ConfigMaps and Secrets referenced by the Deployment trigger analysis | Flagger |
| Blue/green | Native strategy with preview Service and promotion | Supported across many providers | Tie |
| Mirroring | Plugin-dependent beyond Istio | Documented for Istio only | Verify per router |
| GitOps with Argo CD | First-party health checks and UI | Works; needs ignoreDifferences |
Argo |
| GitOps with Flux | Works; no Flux-native integration | Native sibling project | Flagger |
| Operator debuggability | CLI plugin and dashboard show step and ReplicaSets | Status, events and Grafana | Argo |
| Multi-mesh breadth | Istio, ALB, NGINX, Kong, Traefik, SMI and more | Istio, Linkerd, Kuma, OSM, App Mesh, NGINX, Contour, Gloo and more | Flagger for Linkerd and Kuma |
| Autoscaler and tooling compatibility | Tools must understand Rollout |
Tools see ordinary Deployments | Flagger |
Read the matrix by asking which rows are hard constraints for you, not by counting edges. A single hard constraint, such as “we use Linkerd” or “we cannot change workload kinds,” decides the outcome faster than the sum of everything else.

Figure 4: A decision path that starts with your GitOps engine and workload constraints rather than feature counts.
The thesis: choose by who must change, not by features
The original claim of this ADR is that the dominant factor is organizational, not technical. Argo Rollouts asks your workloads to change: every service you want gated needs a Rollout, or a Rollout with workloadRef, and every tool that touches Deployments needs to learn the new kind. Flagger asks your platform to change: you install a controller, add a Canary per service, and adopt its generated-object conventions, but application manifests stay as they are.
So if a platform team owns delivery and application teams own Deployments, Flagger imposes less coordination. If application teams already own their Argo CD Applications and want a self-service rollout console, Argo Rollouts fits the existing ownership. Technical capability is close enough that this ownership question usually settles it.
Trade-offs, Gotchas, and What Goes Wrong
Every progressive delivery system fails in a handful of repeatable ways. Knowing them in advance is the point of writing the ADR down.
Missing metrics read as success or as failure, depending on defaults. If the canary’s metric series does not exist yet, because no traffic has reached it or a label is wrong, the query returns empty. Argo Rollouts treats a non-matching result according to your successCondition and can mark the run Inconclusive or Failed; Flagger counts a failed check against threshold. Test your queries against a deliberately broken canary before trusting them. A query that always returns a healthy-looking number is worse than no query.
Low traffic makes percentages meaningless. A 10 percent canary of a service handling two requests per minute sends one request every five minutes. A 99 percent success threshold computed over that is noise. Use load-test hooks in Flagger or a synthetic traffic job, and consider count-based gating in Argo analysis, or accept that low-traffic services should use blue/green with a smoke test.
Weight drift under autoscaling. When a traffic router is not used, both tools approximate weights through replica ratios, and an HPA that scales the stable set mid-rollout changes the effective split. Use a real traffic router or Gateway API for anything where the percentage matters.
Stuck rollouts and orphaned canaries. A controller crash or a deleted metric backend can leave a rollout paused indefinitely at 50 percent, with half your traffic on a version nobody is watching. Set progress deadlines, alert on rollouts older than your expected duration, and make the abort path a tested runbook, not a theory.
Two commits during one analysis. Both tools restart or supersede the analysis when the spec changes again. That is the right behavior, but it means a busy trunk-based team can starve itself, never completing a rollout because commits arrive faster than analysis finishes. Batch merges or gate merges on rollout completion for the highest-traffic services.
Mesh lock-in through features. Mirroring and session affinity are documented for Istio in Flagger. Choosing those features is quietly choosing the mesh. Record that coupling in the ADR so a later mesh migration does not surprise anyone. Our comparison of Istio Ambient and Linkerd is relevant context if that migration is on your roadmap.
Rollback is not data rollback. Neither tool reverts database migrations, queue schema changes or cache formats. A canary that writes a new record shape and then aborts leaves those records behind. Progressive delivery protects the request path, not stateful side effects, so pair it with expand-then-contract migrations.
Practical Recommendations
For most teams in 2026, the recommended default is determined by the GitOps engine already in place, with two exceptions that override it.
If you run Argo CD and can accept a workload kind change, choose Argo Rollouts. You get first-party health assessment, a purpose-built CLI and dashboard, background analysis with an Inconclusive state, and the Gateway API plugin. Start with workloadRef so existing Deployments remain valid, and set scaleDown: progressively or onsuccess once confidence builds.
If you run Flux, or you cannot change workload kinds, choose Flagger. You keep ordinary Deployments, get config-change gating, and gain broad mesh coverage including Linkerd and Kuma. Use the Gateway API provider if your data plane implements it, and keep the route out of Git because Flagger generates it.
The overrides: if you need Linkerd or Kuma support, Flagger is the practical choice regardless of GitOps engine, because Argo Rollouts’ native list does not include them. If you need custom, multi-stage choreography with manual approval gates mixed with automation, Argo’s steps model is a better fit.
A short checklist before you commit:
- Write down your hard constraints: mesh, Gateway API implementation, workload kinds you cannot change.
- Pilot on one low-risk, moderate-traffic service for two weeks, with a deliberately broken release to exercise abort.
- Validate that your metric queries return data for the canary within the first interval.
- Configure
ignoreDifferencesor equivalent before the first production rollout, not after. - Alert on rollouts that exceed their expected duration.
- Document the abort and manual promote commands in the on-call runbook.
- Confirm exact versions on install day, since release pages and changelogs can disagree.
Frequently Asked Questions
Is Argo Rollouts better than Flagger?
Neither is universally better. Argo Rollouts has richer analysis semantics, a step-based schedule and tighter Argo CD integration, but requires replacing or referencing Deployments with a Rollout resource. Flagger leaves Deployments untouched, gates on ConfigMap and Secret changes, and supports a wider mesh list including Linkerd and Kuma. The deciding factors are usually your GitOps engine, your mesh, and whether you can change workload kinds, not raw capability.
Does Argo Rollouts support Gateway API?
Yes, through the Gateway API plugin rather than a built-in integration. You register the plugin in the Argo Rollouts ConfigMap, author your own HTTPRoute, and the controller adjusts backend weights between the stable and canary Services. The plugin documentation lists HTTPRoute, GRPCRoute, TCPRoute and TLSRoute, though your Gateway implementation must serve the route types you use, and some are in Gateway API’s experimental channel.
Can Flagger be used with Argo CD?
Yes. Flagger is a standalone controller and does not require Flux, although it belongs to the Flux project. Under Argo CD you typically add ignoreDifferences for generated resources and for the scaled-to-zero original Deployment, and ensure pruning does not remove Flagger-created objects. The integration is less turnkey than Argo Rollouts under Argo CD, but it is well-trodden and a one-time configuration cost.
What is the difference between blue/green and canary deployment in Kubernetes?
Blue/green runs a complete second copy of the application, verifies it, then switches all traffic at once, giving instant rollback at the cost of double capacity during the release. Canary shifts a growing percentage of traffic to the new version while analyzing metrics, using less capacity and catching regressions on a small blast radius. Both Argo Rollouts and Flagger support both strategies, with different provider coverage.
Do I need a service mesh for progressive delivery?
No. Both tools can shift traffic through ingress controllers or Gateway API implementations without a mesh, and Argo Rollouts can approximate weights through replica ratios when no router is available. A mesh adds capabilities such as shadow traffic, session affinity and east-west canaries. For north-south traffic on a modern cluster, Gateway API alone is usually sufficient, as long as your implementation supports weighted backends.
How do I roll back automatically with these tools?
Both abort when metric checks exceed their failure budget. Argo Rollouts marks the AnalysisRun Failed, aborts the rollout and returns traffic to the stable ReplicaSet. Flagger increments a failure counter against threshold and, once exceeded, routes all traffic to the primary and scales the canary down. Test the abort path with a deliberately broken release, and remember neither tool reverts database or other stateful changes.
Further Reading
- Argo Rollouts progressive delivery for edge fleets for Rollouts applied to constrained, distributed clusters.
- Kubernetes Gateway API vs Ingress for the routing layer both controllers now target.
- Istio Ambient multicluster, Gateway API and the Inference Extension for a mesh plus Gateway API deployment pattern.
- Argo CD 3 upgrade guide for the GitOps engine most Rollouts users run.
- Argo Rollouts documentation and Flagger documentation as the primary references.
By Riju — about
