Skip to main content
In this lesson we explain how to use Argo CD sync waves together with sync hooks to control resource synchronization order. You’ll learn why hooks alone are not enough when you need strict sequencing (for example, run schema migration → data migration → namespace creation → PostgreSQL → frontend → cleanup) and how to combine hook phases and numeric sync-wave annotations to enforce that order. The repository contains a folder waves-demo under the synchronization path. That YAML contains multiple resources in a single manifest: two migration jobs (schema and data), a Namespace, frontend and PostgreSQL deployments and services, and a cleanup job.
A dark-themed Gitea repository page showing the kk-org/gitops-argocd-capa project with the "synchronization" folder open, listing subfolders (hooks, waves, waves-demo) and recent commit messages. The left sidebar shows other repository directories like helm-chart, nginx-app, and vault-secrets.
High-level resource order in the manifest:
  • Schema migration job — currently annotated as a PreSync hook.
  • Namespace app-namespace.
  • Data migration job — also a PreSync hook.
  • Frontend deployment + frontend service.
  • PostgreSQL deployment + PostgreSQL service.
  • Cleanup job — annotated as a PostSync hook.
Baseline (trimmed) excerpt: the two jobs, the namespace, and a few deployment/service fragments. Note both migration jobs are PreSync hooks in this baseline, which causes them to run in parallel when Argo CD syncs the app.
If you deploy this baseline manifest as-is (without ordering), both PreSync jobs run concurrently. The frontend and PostgreSQL deployments are also created in parallel unless you control their order. The Argo CD UI will reflect concurrent sync activity:
A screenshot of the Argo CD web UI for the application "sync-wave-1" showing app health as "Healthy" and sync status as "Synced" with a "Syncing" last-sync indicator. The main panel shows a resource tree/graph listing services, deployments and jobs (frontend, postgresql, cleanup-job, data-migration-job) with status icons.
When strict ordering is required (for example: schema migration → data migration → create namespace → PostgreSQL → frontend → cleanup), hooks alone are insufficient because multiple resources annotated with the same hook (e.g., PreSync) will run concurrently. Sync Waves provide the missing sequencing control. Argo CD supports a numeric annotation argocd.argoproj.io/sync-wave (string value) that defines relative ordering. Argo CD processes resources by increasing wave number (lowest first). The default wave is "0". Negative values run earlier than zero (for example, "-2""-1""0"). See the Argo CD sync waves documentation for details: https://argo-cd.readthedocs.io/en/stable/user-guide/sync-waves/
A screenshot of Argo CD documentation titled "Combining Sync waves and hooks" showing a diagram with PreSync, Sync, and PostSync phases, each containing labeled "Wave" boxes and a vertical arrow for order of execution. The page also shows a left navigation menu and a right table of contents.
Sync waves and hook phases (PreSync/Sync/PostSync) are combinable: Argo CD groups resources by hook phase and wave, then processes groups in increasing wave order within each phase. Use this to implement precise, deterministic sync sequences.
Updated manifest: apply sync-wave annotations to enforce ordering. The planned sequence:
  • schema migration job: PreSync, sync-wave “-2” (first)
  • data migration job: PreSync, sync-wave “-1” (after schema)
  • Namespace: sync-wave “0” (create namespace before sync-phase resources)
  • PostgreSQL deployment & service: sync-wave “1”
  • Frontend deployment & service: sync-wave “2”
  • Cleanup job: PostSync hook (runs after the sync phase finishes)
How to deploy with Argo CD CLI Create the Argo CD application pointing at the repository and path. Example:
Important notes:
  • Commit the updated manifest (with sync-wave annotations) to Git before Argo CD can apply the new ordering.
  • If any PreSync hooks target the Namespace (i.e., run jobs in app-namespace), ensure the Namespace exists before the PreSync phase. Options:
    • Use —sync-option CreateNamespace=true when creating the Argo CD app, or
    • Make the Namespace a PreSync resource with an earlier wave value than the jobs.
Remember: multiple resources with the same hook phase and the same sync-wave value will be synced in parallel. Assign distinct sync-wave numbers to achieve strict, sequential ordering.
Summary
  • Hooks (PreSync/PostSync) control when resources run relative to the main sync phase, but resources sharing the same hook run concurrently.
  • Sync waves (argocd.argoproj.io/sync-wave) provide an ordered sequence within each hook phase and the sync phase.
  • Combine hooks and sync waves to implement complex GitOps workflows: migrations, namespace creation, database-first deployments, followed by frontend, and finishing with cleanup.
Resource ordering quick reference Links and references

Watch Video

Practice Lab