# How to Implement Progressive Delivery with Argo CD: RollingSync Strategy Guide

> Implement progressive delivery with Argo CD using the RollingSync strategy. Master sequential rollouts across environments with this comprehensive guide.

- Repository: [Argo Project/argo-cd](https://github.com/argoproj/argo-cd)
- Tags: how-to-guide
- Published: 2026-07-09

---

**Enable the experimental progressive sync feature in the ApplicationSet controller, then define a RollingSync strategy with ordered steps in your ApplicationSet spec to roll out changes across environments sequentially.**

Argo CD’s **progressive delivery** capability (also referred to as progressive sync) allows you to deploy changes to Kubernetes applications in controlled waves rather than updating all environments simultaneously. This feature is implemented within the ApplicationSet controller and requires explicit activation before use. By configuring a **RollingSync** strategy, you can orchestrate multi-stage rollouts across development, staging, and production clusters while maintaining fine-grained control over the deployment lifecycle.

## Enable Progressive Sync in the Controller

Progressive delivery is an experimental feature in Argo CD. You must enable it before the ApplicationSet controller will process RollingSync strategies.

### Using Command-Line Flags

Start the ApplicationSet controller with the `--enable-progressive-syncs` flag. This option is defined in [[`cmd/argocd-applicationset-controller/commands/applicationset_controller.go`](https://github.com/argoproj/argo-cd/blob/main/cmd/argocd-applicationset-controller/commands/applicationset_controller.go)](https://github.com/argoproj/argo-cd/blob/master/cmd/argocd-applicationset-controller/commands/applicationset_controller.go#L311):

```bash
argocd-applicationset-controller --enable-progressive-syncs

```

### Using ConfigMap Parameters

Alternatively, enable the feature via the `argocd-cmd-params-cm` ConfigMap by setting the `applicationsetcontroller.enable.progressive.syncs` key:

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cmd-params-cm
data:
  applicationsetcontroller.enable.progressive.syncs: "true"

```

## Configure a RollingSync Strategy

Once enabled, define your rollout sequence in an `ApplicationSet` resource using the `strategy` field. The API types are defined in [[`pkg/apis/application/v1alpha1/applicationset_types.go`](https://github.com/argoproj/argo-cd/blob/main/pkg/apis/application/v1alpha1/applicationset_types.go)](https://github.com/argoproj/argo-cd/blob/master/pkg/apis/application/v1alpha1/applicationset_types.go#L89-L96).

The following example demonstrates a three-wave rollout across environments:

```yaml
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: progressive-sync-appset
spec:
  generators:
    - list:
        elements:
          - environment: dev
            namespace: dev-ns
          - environment: staging
            namespace: staging-ns
          - environment: prod
            namespace: prod-ns
  template:
    metadata:
      name: '{{name}}-{{environment}}'
      labels:
        environment: '{{environment}}'
    spec:
      project: default
      source:
        repoURL: https://github.com/example/repo
        targetRevision: HEAD
        path: '{{environment}}'
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{namespace}}'
  strategy:
    type: RollingSync
    rollingSync:
      steps:
        - matchExpressions:
            - key: environment
              operator: In
              values: ["dev"]
          maxUpdate: 100%
        - matchExpressions:
            - key: environment
              operator: In
              values: ["staging"]
        - matchExpressions:
            - key: environment
              operator: In
              values: ["prod"]

```

**Key configuration elements:**

- **`type: RollingSync`** – Activates the progressive delivery mode for this ApplicationSet.
- **`steps`** – Defines the order of deployment. Each step contains `matchExpressions` that select Applications based on their labels.
- **`maxUpdate`** – Optional parameter limiting how many Applications can update simultaneously within a step (e.g., `"50%"` or an integer).
- **`deletionOrder`** – Optional field set to `Reverse` to delete Applications in the opposite order of deployment when the ApplicationSet is removed.

## How the Progressive Sync Manager Works

The core logic resides in [[`applicationset/progressivesync/progressive_sync.go`](https://github.com/argoproj/argo-cd/blob/main/applicationset/progressivesync/progressive_sync.go)](https://github.com/argoproj/argo-cd/blob/master/applicationset/progressivesync/progressive_sync.go). The **progressive sync manager** orchestrates the rollout by tracking each Application through a defined state machine.

When a generated Application’s desired spec or Git revision changes, the manager transitions its status through the following phases:

1. **Waiting** – The Application is queued for the next sync wave.
2. **Pending** – The Application is eligible for sync but waiting for the current step to complete.
3. **Progressing** – The Application is actively syncing.
4. **Healthy** – The Application has synced successfully and the step is complete.

The manager determines which Applications are ready to synchronize using the `getAppsToSync` function. It builds a dependency list for each step based on the `matchExpressions` defined in your strategy, ensuring that waves proceed sequentially only after the previous step reaches `Healthy` status. The status transition logic is implemented around lines 222–390 in the progressive sync manager.

## Monitor Rollout Progress

Observe the current state of your progressive delivery by inspecting the `ApplicationSet` status field. The controller updates `ApplicationSet.status.applicationStatus` to reflect each Application’s current step and health state.

```bash
kubectl get applicationset progressive-sync-appset -o yaml | yq .status.applicationStatus

```

Expected output shows the progression through steps:

```yaml
- application: progressive-sync-appset-dev
  status: Healthy
  step: "1"
- application: progressive-sync-appset-staging
  status: Progressing
  step: "2"
- application: progressive-sync-appset-prod
  status: Waiting
  step: "3"

```

The controller updates these fields automatically as each wave completes. Applications remain in `Waiting` status until all Applications in the previous step report `Healthy`.

## Configure Reverse Deletion Order (Optional)

When deleting an ApplicationSet configured with progressive sync, you can control the deletion order using the `deletionOrder: Reverse` setting. This ensures Applications are removed in the opposite sequence of deployment (e.g., production first, then staging, then development).

The `PerformReverseDeletion` function in [[`applicationset/progressivesync/progressive_sync.go`](https://github.com/argoproj/argo-cd/blob/main/applicationset/progressivesync/progressive_sync.go)](https://github.com/argoproj/argo-cd/blob/master/applicationset/progressivesync/progressive_sync.go) handles this logic. This capability is particularly useful for ensuring that cleanup operations respect dependency chains or for maintaining safety during environment teardown.

## Summary

- **Progressive delivery** in Argo CD requires enabling the experimental `--enable-progressive-syncs` flag or corresponding ConfigMap parameter.
- Configure rollouts using the **RollingSync** strategy in your `ApplicationSet` spec, defining ordered `steps` with label `matchExpressions`.
- The progressive sync manager in [`applicationset/progressivesync/progressive_sync.go`](https://github.com/argoproj/argo-cd/blob/main/applicationset/progressivesync/progressive_sync.go) tracks Application status through `Waiting → Pending → Progressing → Healthy` states.
- Use `maxUpdate` to limit concurrency within a step and `deletionOrder: Reverse` to control teardown sequence.
- Monitor rollout health via `ApplicationSet.status.applicationStatus` to verify each wave completes before the next begins.

## Frequently Asked Questions

### Is progressive delivery with Argo CD production-ready?

No, progressive delivery is currently an **experimental feature** in Argo CD. You must explicitly enable it using the `--enable-progressive-syncs` flag or ConfigMap parameter. Review the [official documentation](https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/applicationset/Progressive-Syncs.md) for current stability status and upgrade considerations before deploying to production environments.

### How does Argo CD determine which Applications belong to which step?

The controller uses **label selectors** defined in each step’s `matchExpressions` field. When generating Applications from the template, ensure they include labels that match your criteria (such as `environment: dev`). The `getAppsToSync` function in the progressive sync manager filters generated Applications based on these expressions to build the deployment wave.

### What happens if an Application fails to sync during a progressive rollout?

If an Application fails to reach `Healthy` status, the rollout **pauses** at that step. The controller will not proceed to subsequent steps until all Applications in the current step report `Healthy`. You must resolve the underlying issue (such as a failed deployment or invalid manifest) and allow the Application to sync successfully before the progressive delivery continues.

### Can I limit the number of concurrent updates within a single step?

Yes. Use the **`maxUpdate`** field within a step definition to control concurrency. You can specify an absolute number (e.g., `maxUpdate: 2`) or a percentage (e.g., `maxUpdate: 50%`) of Applications that should sync simultaneously. This limits the blast radius during updates and helps manage resource contention in large environments.