Skip to main content
Argo CD provides flexible synchronization strategies to control when and how applications are deployed to your clusters.

Manual Sync

By default, applications require manual synchronization. When changes are detected in Git, you must explicitly trigger a sync operation.
# Sync application
argocd app sync myapp

# Sync with pruning
argocd app sync myapp --prune

# Force sync (recreate resources)
argocd app sync myapp --force

Automated Sync Policy

Argo CD can automatically sync applications when it detects differences between the desired manifests in Git and the live state in the cluster.

Enabling Auto-Sync

spec:
  syncPolicy:
    automated: {}

Auto-Sync with Enabled Flag

You can explicitly control automated sync using the enabled field:
spec:
  syncPolicy:
    automated:
      enabled: true  # or false to disable
Setting spec.syncPolicy.automated.enabled to null is treated as enabled. When set to false, the controller will skip automated sync even if prune, selfHeal, and allowEmpty are configured.

Automatic Pruning

By default, automated sync will not delete resources when they are removed from Git. Enable automatic pruning to delete resources:
spec:
  syncPolicy:
    automated:
      prune: true
Automatic pruning will delete resources from your cluster when they’re removed from Git. Use with caution.

Allow Empty Resources

Prevents errors when there are no target resources:
spec:
  syncPolicy:
    automated:
      prune: true
      allowEmpty: true

Automatic Self-Healing

When enabled, Argo CD will automatically revert manual changes made to the live cluster:
spec:
  syncPolicy:
    automated:
      selfHeal: true
By default, changes made to the live cluster will not trigger automated sync. Self-heal ensures your cluster state always matches Git.
Disabling self-heal does not guarantee that live cluster changes will persist in multi-source applications. Changes in one source can trigger autosync even if another remains unchanged.

Sync Options

Fine-tune sync behavior with sync options:
spec:
  syncPolicy:
    syncOptions:
      # Disable kubectl validation
      - Validate=false
      
      # Create namespace if it doesn't exist
      - CreateNamespace=true
      
      # Set prune propagation policy
      - PrunePropagationPolicy=foreground  # or background, orphan
      
      # Prune resources as final wave
      - PruneLast=true
      
      # Respect ignoreDifferences during sync
      - RespectIgnoreDifferences=true
      
      # Only sync out-of-sync resources
      - ApplyOutOfSyncOnly=true
      
      # Use kubectl replace instead of apply
      - Replace=true
      
      # Skip dry run on missing resources
      - SkipDryRunOnMissingResource=true

Managed Namespace Metadata

When using CreateNamespace=true, you can set metadata on the namespace:
spec:
  syncPolicy:
    syncOptions:
      - CreateNamespace=true
    managedNamespaceMetadata:
      labels:
        environment: production
        team: platform
      annotations:
        monitoring: enabled

Sync Waves

Sync waves allow you to control the order in which resources are applied using the argocd.argoproj.io/sync-wave annotation.

How Waves Work

1

Resources are ordered

All resources are ordered by their wave number (lowest to highest)
2

Sequential application

Resources in each wave are applied sequentially
3

Health check

Argo CD waits for all resources in a wave to be healthy before proceeding

Wave Examples

Wave -1: Database Migration
apiVersion: batch/v1
kind: Job
metadata:
  name: db-migrate
  annotations:
    argocd.argoproj.io/sync-wave: "-1"
spec:
  template:
    spec:
      containers:
        - name: migrate
          image: flyway:latest
          # migration command
Wave 0: ConfigMaps and Secrets (default)
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  # No annotation = wave 0
data:
  config.yaml: |
    # configuration
Wave 1: Deployments
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
  annotations:
    argocd.argoproj.io/sync-wave: "1"
spec:
  # deployment spec
Wave 2: Services
apiVersion: v1
kind: Service
metadata:
  name: backend-service
  annotations:
    argocd.argoproj.io/sync-wave: "2"
spec:
  # service spec
Waves are assigned to wave 0 by default. Waves can be negative, allowing you to create resources that run before everything else.

Sync Phases (Hooks)

Hooks allow you to run resources at specific points in the sync lifecycle:
Hook TypeDescription
PreSyncExecutes before the application of manifests
SyncExecutes at the same time as manifest application
PostSyncExecutes after all resources are healthy
SyncFailExecutes when the sync operation fails
SkipSkips the resource during sync
PreDeleteExecutes before Application deletion
PostDeleteExecutes after Application resources are deleted

Hook Example

apiVersion: batch/v1
kind: Job
metadata:
  name: post-deploy-notification
  annotations:
    argocd.argoproj.io/hook: PostSync
    argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
  template:
    spec:
      containers:
        - name: notify
          image: curlimages/curl
          command:
            - curl
            - '-X'
            - POST
            - 'https://hooks.slack.com/services/...'
      restartPolicy: Never

Hook Deletion Policies

PolicyDescription
HookSucceededDelete after successful execution
HookFailedDelete after failed execution
BeforeHookCreationDelete existing hook before creating new one

Combining Waves and Hooks

You can combine sync waves with hooks for fine-grained control:
apiVersion: batch/v1
kind: Job
metadata:
  name: db-schema-update
  annotations:
    argocd.argoproj.io/hook: PreSync
    argocd.argoproj.io/sync-wave: "-1"
    argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
  # Job spec
Argo CD orders resources by:
  1. Phase (PreSync, Sync, PostSync)
  2. Wave (lowest to highest)
  3. Kind (namespaces first, then other resources)
  4. Name (alphabetically)

Retry Policy

Configure automatic retry on sync failure:
spec:
  syncPolicy:
    retry:
      limit: 5  # Number of retry attempts
      backoff:
        duration: 5s      # Initial backoff duration
        factor: 2         # Multiplier for each retry
        maxDuration: 3m   # Maximum backoff duration

Refresh on Retry

Automatically refresh application on new revisions during retries:
spec:
  syncPolicy:
    retry:
      refresh: true

Automated Sync Semantics

  • Only when the application is OutOfSync
  • Applications in Synced or error states will not auto-sync
  • One sync per unique combination of commit SHA and parameters
  • Will not retry if a previous sync failed for the same commit
  • When selfHeal: true, sync will retry after self-heal timeout (default: 5 seconds)
  • Timeout is controlled by --self-heal-timeout-seconds flag
  • Determined by timeout.reconciliation in argocd-cm ConfigMap
  • Default: 120 seconds with 60 seconds jitter (max 3 minutes)
  • Rollback cannot be performed on applications with automated sync enabled

ApplicationSet Auto-Sync Toggle

For ApplicationSet-managed applications, toggling auto-sync requires special handling. See the ApplicationSet documentation for details on controlling resource modification.