Application Dependencies with Argo CD
Jesse Suen
By Christian Hernandez and Jesse Suen. Originally published March 2024.
Updated August 2026 for Argo CD v3.5: Progressive Syncs is now Beta, native dependency ordering is under active proposal, and Kargo joins as a fourth pattern.
Since the term GitOps was coined almost a decade ago in 2017, adoption has spread and Argo CD deployments have grown more complex. Organizations that started with a handful of Applications are now running many more: in the 2026 Argo CD user survey, 42% of respondents reported managing more than 500 Applications, and scaling and performance is now the most-cited Argo CD challenge, reaching 50% among organizations running more than 2,000 Applications.
This post tackles a problem that shows up at that scale: how to make one Application wait on another. The same survey names dependency management among the top five missing features, with respondents reporting that sync waves alone are not enough to order deployments across Applications.
This application dependency problem surfaces during bootstrap or disaster-recovery rebuilds, not steady-state operation: a cluster comes up fine in staging, then fails in a fresh environment because something depended on an Application that wasn't there yet. The usual suspects:
A mutating webhook that needs to exist before dependent pods start
A CRD that needs to be established before its custom resources apply
A database that should be healthy before the service in front of it starts taking traffic
Four patterns have developed to handle this, each with different trade-offs depending on the number of Applications involved and whether a promotion pipeline is already part of the setup. This post walks through each pattern, its prerequisites, and where Argo CD's own native answer to this problem stands today.
What Argo CD Sync Waves Can and Cannot Order
Before jumping into the four patterns, it's worth covering how Argo CD thinks about Applications and where sync waves reach their limits.
An Argo CD Application is a collection of Kubernetes resources, such as Deployments, Services, and Ingress objects, treated as a single unit. It is the atomic unit of work in Argo CD.
By default, Argo CD applies the manifests inside an Application as-is, with no ordering guarantees. That becomes a problem when order matters, such as a CustomResourceDefinition needing to exist before its corresponding CustomResource. Sync waves and sync phases solve this within an Application: waves control the order resources apply in, phases control pre-sync and post-sync hooks. A Namespace annotated with sync-wave: "1" applies before a Pod annotated with sync-wave: "2".
Full details on sync waves and phases are in the Argo CD documentation.
Argo CD Applications are isolated by design. Application independence is what lets Argo CD manage thousands of Applications without one Application's problems blocking every other sync. A controller that had to track cross-Application relationships natively would be slower and harder to reason about at exactly the scale where it matters most. The trade-off is that dependency ordering has to be built on top of the Application spec rather than declared inside it.
Scope matters here: a sync-wave annotation on an api Application stays scoped to that Application. It does not carry over to when a separate database Application syncs. Ordering across Applications is not something the Application spec currently supports but it's achievable via sync waves on child Applications in an app-of-apps pattern, or via ApplicationSet RollingSync for Applications generated by a single ApplicationSet. Requests for finer-grained ordering go back to 2020. The four patterns below exist specifically to close that gap.
Prerequisites: Configuring Health Checks Before Ordering Applications
Before choosing a pattern, configure three things so that Argo CD reports Application health accurately:
Readiness and liveness probes
Custom Argo CD health checks
Application-level health
Without all three, Argo CD can mark a dependency "Healthy" before the workload behind it can serve traffic, which breaks the ordering guarantee every pattern below relies on.
Kubernetes Readiness and Liveness Probes
Argo CD determines Application health from the collective health of the resources inside it. Liveness probes confirm a resource is running; readiness probes confirm it can accept traffic. Without both configured, Argo CD can mark a resource "Healthy" and "Synced" while it is still initializing.
Consider a MySQL StatefulSet deployed without probes: Argo CD marks it healthy as soon as the pod starts, regardless of whether MySQL has finished its setup process or can accept connections yet. Adding probes fixes this:
With these in place, Kubernetes considers the StatefulSet alive once the port accepts connections, and ready once a query succeeds. More detail is available in the Kubernetes probe documentation.
Custom Argo CD Health Checks with Lua
Beyond default Kubernetes health, Argo CD ships built-in health checks for the resource types listed in the resource_customizations directory, written in Lua and visible in the Argo CD GitHub repository. Custom resources, particularly ones from Kubernetes Operators, often need a custom health check added through the resource.customizations field in the argocd-cm ConfigMap:
Full documentation on writing custom health checks is available Argo CD health check documentation.
Enabling the Application Health Check in argocd-cm
The health check for the Application CRD itself (argoproj.io/Application) was removed from Argo CD's defaults in version 1.8 (see issue #3781) and has not been restored as a default since. Each pattern below that depends on one Application waiting for another to become healthy, App-of-Apps in particular, requires this health check to be added back manually:
With probes, resource health checks, and Application health checks all in place, the four patterns below become viable.
Pattern 1: Eventual Consistency with Argo CD Sync Retries
The simplest pattern uses no explicit dependency management at all. It relies on Argo CD retrying until dependent resources succeed, using sync options and a retry policy set directly on the Application manifest:
Validate=false disables resource validation, equivalent to kubectl apply --validate=false. Combined with the retry block, Argo CD keeps attempting the sync until it succeeds or the retry limit is exhausted. This effectively handles dependencies by not handling them explicitly, and simply trying again until the dependent resource exists.
The drawback: this only works for dependencies that resolve given enough time, not ones with a hard ordering requirement. An invalid manifest applied repeatedly stays invalid regardless of retry count. Installing Istio and confirming its sidecar injector is running before an application starts is that kind of hard requirement, not something retries can paper over.
Pattern 2: Ordering Applications with App-of-Apps and Sync Waves
App-of-Apps originated as a method for bootstrapping Argo CD itself: a "parent" Application that consists of other Applications, since an Application is, at its core, a Kubernetes CRD. Once the prerequisites above are in place, particularly the Application-level health check, App-of-Apps becomes a direct way to order deployment across multiple Applications using sync waves.
Consider a three-tier application: a database, a backend, and a frontend, deployed in that order. Each child Application gets a sync-wave annotation, with lower numbers taking priority:
The parent Application is an ordinary Argo CD Application, distinguished only by the fact that its resources happen to be other Applications:
A full working example is available in this repository. Once the parent Application applies, Argo CD deploys the database first, waits for it to report synced and healthy, deploys the backend, waits again, then deploys the frontend. All three ordering guarantees hold only because the Application health check from the prerequisites section is in place; without it, Argo CD has no way to know a child Application is done deploying and will apply all three waves without waiting.
App-of-Apps remains the most direct and predictable way to order Applications relative to each other, and it is still the most-used pattern in the community: roughly 82% of respondents to the 2026 Argo CD user survey report using it in production.
Pattern 3: Health-Gated Rollouts with ApplicationSet Progressive Syncs
App-of-Apps solves ordering, but it doesn't scale gracefully: hand-writing a child Application manifest for every service works fine for three services and turns into real toil past a dozen. ApplicationSets fix the toil, not the ordering. An ApplicationSet is an Application factory, generating many Applications from one manifest through a generator, but ordering those generated Applications was never part of the original design. That gap is exactly what ProgressiveSyncs closes.
ProgressiveSyncs rolls out an ApplicationSet's generated Applications in defined steps, advancing to the next step only once every Application in the current step reports healthy:
The result mirrors App-of-Apps: database, then backend, then frontend, each waiting on the previous one's health. The difference is a single manifest generates and orders all three, rather than three separate Application definitions maintained by hand.
Status as of Argo CD v3.5: ProgressiveSyncs moved from Alpha to Beta in Argo CD v3.3 and is documented as generally stable. It still requires explicit enablement (--enable-progressive-syncs on the ApplicationSet controller) and still carries real edge cases worth knowing about before relying on it in production.
RollingSync forces autosync off on every generated Application, so syncPolicy.automated set inside the template gets overridden with a controller warning rather than an error. More significantly, RollingSync currently does not trigger a rollout for changes to .spec.sources.valuesObject (inline Helm values), which means an inline values change can bypass the staged rollout and sync every Application at once rather than proceeding step by step. There's also an open request to scope RollingSync to specific classes of change, such as triggering only on Helm chart version bumps and not on ordinary value updates, which is not yet supported.
For teams managing dozens or hundreds of generated Applications across clusters or regions, ProgressiveSyncs remains the most direct way to get staged, health-gated rollout without hand-writing every Application. Teams relying on it in production should account for the valuesObject gap directly, either by avoiding inline values in favor of value files or by testing the rollout behavior for their specific change patterns.
Pattern 4: Dependency-Aware Promotion with Kargo
Kargo, created by Jesse Suen, Alexander Matyushentsev, and Hong Wang, the original creators of Argo CD, offers a fourth pattern, one that folds dependency ordering into a broader promotion pipeline rather than treating ordering as a standalone concern.
Kargo introduces a set of concepts: a Warehouse watches sources such as image registries or Git repositories for new artifacts. Freight is a versioned bundle of those artifacts, a new image tag or commit that becomes eligible for promotion. A Stage represents an environment, with a promotion template defining what happens when new Freight arrives.
The dependency-relevant piece is stage ordering. A Stage can declare requestedFreight.sources.stages, requiring Freight to have already passed through an upstream Stage before it becomes eligible for promotion to this one. In practice, this means a backend Stage can require Freight to have already promoted successfully through a database Stage, which is the same ordering guarantee App-of-Apps provides through sync waves and Application health, expressed instead as a promotion pipeline with a UI showing Freight flowing between Warehouses and Stages.
Kargo is the heaviest pattern of the four to adopt. It is a separate system to install and operate, and it is best suited to teams that need a full promotion pipeline (moving changes across dev, staging, and production with image watching and stage gating) rather than teams that only need one Application to wait on another. For more detail on continuous promotion and Kargo's promotion mechanics specifically, see Continuous Promotion with Kargo.
Native Dependencies: The dependsOn Effort
Issue #7437, opened in October 2021, asked for a native way to block one Application's sync until another Application is deployed. It sat largely dormant until PR #25282, open since November 2025, introduced sync-groups: resources declare a sync-wave-group and sync-wave-group-dependencies, letting Argo CD build a DAG of dependencies instead of relying on linear wave numbers alone.
A resource in wave-group 2 waits until every resource in wave-groups 0 and 1 finishes syncing. The scope is still within a single Application, not across separate Applications, but it lays the groundwork for a cross-Application version.
The PR remains alpha, with no merge date, though the author confirmed in mid-2026 that its direction was discussed at an Argo community meeting. Worth tracking, not worth waiting on: the four patterns above remain the way to handle dependency ordering today.
How to Choose Between the Four Argo CD Dependency Patterns
The dependency is soft, a resource that will eventually succeed given retries rather than one with a hard ordering requirement: start with Eventual Consistency. It requires no new tooling and no prerequisites beyond what Argo CD already provides, but it cannot express "this must not deploy before that."
A small, fixed number of Applications need explicit ordering: use App-of-Apps. It is the most predictable of the four patterns and the easiest to reason about, provided the Application health check prerequisite is in place. It does not scale well to dozens of Applications managed by hand.
The same ordering problem exists at scale, across many generated Applications, clusters, or regions: move to ApplicationSets ProgressiveSyncs. Beta status means it is broadly production-viable, but the valuesObject rollout gap is worth testing against directly before relying on it for every kind of change.
Dependency ordering is really one piece of a larger promotion need, image watching, multi-environment gating, and a pipeline view of how changes move from dev to production: adopt Kargo. It is the most capable option and the most infrastructure to run.
Situation | Pattern | Prerequisite | Cost |
|---|---|---|---|
The dependency is soft and will resolve given retries | Eventual Consistency | None beyond stock Argo CD | Cannot express "this must not deploy before that" |
A small, fixed number of Applications need explicit ordering | App-of-Apps | Application health check in argocd-cm | Does not scale past roughly a dozen hand-written manifests |
The same ordering problem at scale, across generated Applications or clusters | ApplicationSet Progressive Syncs | Beta feature gate enabled on the ApplicationSet controller | valuesObject rollout gap; test against your change patterns first |
Ordering is one piece of a larger promotion need | Kargo | A separate system to install and operate | Most capable option and the most infrastructure to run |
Curious about native support landing in Argo CD itself: track, but do not wait on, PR #25282. It shows real movement on a long-standing gap, but it is alpha, scoped to within a single Application so far, and without a release commitment.
Argo CD Application Dependencies in 2026: Where Things Stand
Argo CD still does not manage dependencies between Applications natively. What has changed is the maturity of the tools available to work around it: ProgressiveSyncs is Beta rather than Alpha, Kargo has grown from an early project into a complete promotion layer, and a concrete proposal for native DAG-based ordering is under active discussion rather than sitting idle. Eventual Consistency, App-of-Apps, ApplicationSets ProgressiveSyncs, and Kargo each solve the dependency problem at a different scale and level of investment, and all four remain viable choices today while the native solution continues to develop.
For more on GitOps best practices generally, the GitOps Best Practices Whitepaper is available for download. The Akuity community Discord also covers tips, tricks, and updates across the Akuity Platform, Argo CD, and Kargo; join at akuity.community.
Additional Resources
[Blog Post] Argo CD Architectures Explained: Single vs. Per-Cluster vs. Hybrid
[Guide] Continuous Promotion with Kargo
[Blog Post] GitOps Is Incomplete Without Promotion: How Kargo Fixes That
[GitHub] argoproj/argo-cd Issue #7437, Application dependencies
Frequently Asked Questions about Argo CD Application Dependencies
What is the App of Apps pattern?
The App of Apps pattern is an Argo CD deployment strategy where a parent Application manages other child Applications. Sync waves and Application health checks let teams control deployment order across multiple Applications, ensuring dependencies such as a database before a backend service are respected. It treats a group of Applications as a single unit for deployment and lifecycle management.
What are sync waves?
Sync waves control the order in which resources or Applications apply during a sync. Each resource or Application carries a numeric wave value, and Argo CD applies lower-numbered waves first, moving sequentially to higher numbers. This ensures dependencies are respected, such as creating a Namespace before deploying Pods into it.
What are ApplicationSets ProgressiveSyncs?
ProgressiveSyncs is a Beta ApplicationSet feature that rolls out generated Applications in defined steps using the RollingSync strategy. Each step only proceeds once every Application in the previous step reports healthy, allowing a single ApplicationSet manifest to manage ordered, multi-environment rollouts without hand-writing individual Applications.
Does Argo CD support native dependencies between Applications?
Not yet. Argo CD has no built-in
dependsOnfield on the Application spec. Issue #7437 tracks the request, and an active proposal (PR #25282) introduces DAG-based sync-wave groups, though it remains alpha and scoped within a single Application. Eventual Consistency, App-of-Apps, ApplicationSets ProgressiveSyncs, and Kargo are the current patterns used to fill this gap.How does Kargo handle Application dependencies?
Kargo enforces ordering through Stage requirements: a Stage can require Freight to have already passed through an upstream Stage before becoming eligible for promotion. This produces the same ordering guarantee as sync waves in App-of-Apps, expressed as a promotion pipeline rather than Application annotations, and is most useful for teams that already need image watching and multi-environment promotion alongside dependency ordering.

