Controlling Resource Apply Order in Argo CD Using Sync Wave
Learn how to use Argo CD’s sync-wave annotation to enforce deterministic apply order for Kubernetes manifests, with step‑by‑step instructions, verification steps, and recovery guidance.
17 Aug 2026, 00:17 UTC

Desired outcome
\nYou want Argo CD to apply Kubernetes manifests in a deterministic order so that dependencies (for example, a CustomResourceDefinition before the custom resources that use it) are always created first during a sync.
\nPrerequisites
\n- \n
- A running Argo CD cluster (version 2.x or newer). \n
kubectlconfigured to manage the Argo CD namespace (typicallyargocd) with sufficient permissions to read and edit Application resources. \n- An existing Argo CD Application whose source repository you can edit (e.g., a Git repo containing the manifests you wish to order). \n
- Basic familiarity with Kubernetes YAML manifests and Git workflow. \n
Procedure
\n- \n
- Identify the manifests that need ordering. For each manifest, decide a relative integer weight: lower numbers are applied first. A common pattern is to assign negative numbers to CRDs, zero to core resources, and positive numbers to dependent workloads. \n
- Add or modify the annotation
argocd.argoproj.io/sync-waveon each manifest. Example:\n
\n# crd.yaml (applied first)\napiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n name: myresources.example.com\n annotations:\n argocd.argoproj.io/sync-wave: \"-10\"\nspec:\n group: example.com\n versions:\n - name: v1\n served: true\n storage: true\n schema:\n openAPIV3Schema:\n type: object\n scope: Namespaced\n names:\n plural: myresources\n kind: MyResource\n
\n# myresource.yaml (applied after the CRD)\napiVersion: example.com/v1\nkind: MyResource\nmetadata:\n name: myresource-sample\n annotations:\n argocd.argoproj.io/sync-wave: \"0\"\nspec:\n # …\n
\n# deployment.yaml (applied last)\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: myapp\n annotations:\n argocd.argoproj.io/sync-wave: \"20\"\nspec:\n replicas: 1\n selector:\n matchLabels:\n app: myapp\n template:\n metadata:\n labels:\n app: myapp\n spec:\n containers:\n - name: app\n image: myapp:latest\n\n - Commit the updated manifests to the Git repository that the Application points to. \n
- Argo CD will automatically detect the change and start a sync. You can also trigger a sync manually from the UI or CLI:\n
\n# Run from your workstation where kubectl is configured\nkubectl -n argocd sync application my-app\n\n
Expected checks
\n- \n
- After the sync completes, verify the Application status shows
Synced:\n
\nkubectl get application my-app -n argocd -o yaml | grep sync.status\n\n - Inspect the ordered list of resources in the Argo CD UI: open the Application → Resources tab. Resources with lower sync‑wave numbers appear higher in the list. \n
- For a specific resource, confirm the annotation is present and that no
Failedevents followed the sync:\n
\nLook for the linekubectl describe customresourcedefinition myresources.example.com -n \nAnnotations: argocd.argoproj.io/sync-wave: -10and ensure the Events section ends with aNormalAppliedevent.\n \n
Recovery options (if sync fails)
\nIf an incorrect sync‑wave value causes a resource to be created before its dependency (e.g., a custom resource before its CRD), Argo CD will report a sync error.
\n- \n
- Revert the problematic annotation to a safer value (often moving the resource to a higher wave number). Edit the manifest in Git, commit, and push. \n
- Trigger a re-sync:\n
\nkubectl -n argocd sync application my-app\n - If the stuck resource cannot be deleted by Argo CD due to a dependency loop, you may need to manually remove it (with
kubectl delete) and let Argo CD recreate it after the annotation is corrected. Exercise caution: manual deletion bypasses Argo CD’s reconciliation loop and should be followed by a immediate re‑sync.\n \n
Limitations and verification
\n- \n
- Sync Wave only influences ordering within a single Application. It does not affect the order between separate Applications or resources managed by external controllers (e.g., Operators). \n
- Use small integer values (typically -100 to 100). Extremely large or non‑integer values can be ignored or cause unexpected behavior. \n
- Avoid circular dependencies; if two resources reference each other, setting sync-wave will not resolve the deadlock and may cause the sync to hang. \n
- Practical verification: after each sync, run\n
\nkubectl get application my-app -n argocd -o yaml -o jsonpath='{.status.sync.status}'\nand confirm it returns
Synced. Additionally, you can query the resource events as shown above to ensure noFailedevents appear after the sync.\n \n
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.