GitOps in 2026: Flux vs ArgoCD — An Honest Comparison After Two Years in Production
Our infrastructure team has been running both Flux and ArgoCD in production since early 2024. Not as a bake-off -- we inherited Flux from one acquisition and ArgoCD from another, and both needed to coexist while we evaluated consolidation. After two years managing 14 clusters totaling roughly 400 nodes across three cloud providers, we have formed opinions grounded in operational reality rather than conference talks. This is that comparison.
Architecture: Pull-Based, But Differently
Both Flux and ArgoCD implement the GitOps pull model: a controller running inside the cluster watches a Git repository and reconciles the cluster state to match the declared state. The architectural differences lie in how they decompose this responsibility.
Flux is a set of composable controllers. The source-controller fetches artifacts from Git, Helm, or OCI repositories. The kustomize-controller applies Kustomize overlays. The helm-controller manages Helm releases. Each controller operates independently with its own reconciliation loop. This modularity means you can use Flux's source management without its Kustomize engine, or swap in your own components.
ArgoCD is a monolithic application server with a distinct UI, API server, repo server, and application controller. The repo server clones repositories, renders manifests (Helm, Kustomize, Jsonnet, plain YAML), and caches them. The application controller compares rendered manifests against live cluster state and performs sync operations.
In practice, Flux's composability is a double-edged sword. It provides flexibility but pushes architectural decisions onto the operator. ArgoCD's opinionated architecture means less decision-making upfront but less flexibility when you hit edge cases.
Multi-Cluster Management
This is where the tools diverge most sharply.
ArgoCD supports multi-cluster natively. A single ArgoCD instance (or an HA set) can manage applications across dozens of clusters by registering external cluster credentials. The UI provides a unified view of all applications across all clusters. We manage 14 clusters from two ArgoCD instances (one per region for latency reasons).
Flux takes the opposite approach: each cluster runs its own Flux controllers. Multi-cluster management is achieved through repository structure -- a shared Git repo with per-cluster overlays. There is no central control plane or unified view. You get consistency through Git conventions, not through a management layer.
# Typical Flux multi-cluster repo structure
clusters/
production-us-east/
flux-system/
gotk-sync.yaml
infrastructure/
kustomization.yaml
apps/
kustomization.yaml
production-eu-west/
flux-system/
gotk-sync.yaml
infrastructure/
kustomization.yaml
apps/
kustomization.yaml
base/
infrastructure/
cert-manager/
ingress-nginx/
apps/
api-gateway/
worker/
For teams with 3-5 clusters, Flux's approach is cleaner. Beyond 10 clusters, the lack of a unified management plane becomes painful. We spent considerable effort building custom tooling to answer simple questions like "which version of service X is running across all clusters?" -- a question ArgoCD answers out of the box.
Secrets Management
Neither tool handles secrets natively, which is correct -- secrets should not live in Git in plaintext. Both ecosystems have mature solutions, but the ergonomics differ.
With Flux, we use Mozilla SOPS integrated via the kustomize-controller. Encrypted secrets are committed to Git and decrypted at apply time using age keys or cloud KMS:
# .sops.yaml in the repo root
creation_rules:
- path_regex: .*\.secret\.yaml$
age: age1ql3z7hjy5...
encrypted_regex: ^(data|stringData)$
With ArgoCD, we use the Vault plugin (argocd-vault-plugin) which replaces placeholders in manifests with values fetched from HashiCorp Vault at render time:
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
annotations:
avp.kubernetes.io/path: "secret/data/production/db"
type: Opaque
stringData:
password: <password>
Sealed Secrets works with both but introduces its own controller and key management overhead. For organizations already running Vault, the ArgoCD Vault plugin provides the smoothest experience. For smaller teams without Vault, SOPS with Flux is simpler to operate.
We also tested the External Secrets Operator, which decouples secret management from the GitOps tool entirely. It pulls secrets from Vault, AWS Secrets Manager, or GCP Secret Manager at runtime via ExternalSecret CRDs. For organizations with heterogeneous secret backends, this is currently our recommended approach regardless of which GitOps tool you run.
Drift Detection and Remediation
Both tools detect drift -- the divergence between Git-declared state and live cluster state. The difference is in behavior and visibility.
ArgoCD categorizes applications as Synced, OutOfSync, or Unknown, and provides a detailed diff view in the UI showing exactly which fields have drifted. It supports configurable sync policies: manual sync (detect and alert, human approves), auto-sync (detect and remediate automatically), and self-heal (continuously revert manual changes).
Flux continuously reconciles by default. There is no "OutOfSync" state that persists -- Flux will attempt to reapply the desired state on every reconciliation interval (default: 10 minutes). You can configure force: true on Kustomizations to overwrite manual changes, but there is no built-in diff view. Detecting what changed requires examining controller logs or using flux diff kustomization from the CLI.
We found ArgoCD's drift detection UX significantly better for debugging. When a developer manually patches a deployment in production (it happens), ArgoCD shows exactly what changed and who synced what. Flux silently reverts the change on the next reconciliation, which is arguably the correct behavior but makes postmortem analysis harder.
Performance at Scale (400 Nodes)
At our scale, both tools required tuning beyond defaults.
ArgoCD's repo server became a bottleneck around 300 managed applications. Each sync operation clones the repository and renders manifests, which is CPU and memory intensive with large Helm charts. We addressed this by:
- Increasing repo server replicas to 5 with
--parallelismlimit 3per replica. - Enabling the manifest cache with a 24-hour TTL for stable applications.
- Splitting monorepos into per-team repositories to reduce clone times.
- Setting
resource.exclusionsto ignore high-churn resources like Events and EndpointSlices.
The ArgoCD application controller also required attention. At 300+ managed applications, we increased the --status-processors and --operation-processors flags and allocated 4 GB of RAM to the controller pod. Without this tuning, sync operations would queue and the UI would show stale state for minutes at a time.
Flux's per-cluster architecture means no single controller manages more than 80-100 applications, so we hit fewer scaling walls. However, the source-controller's Git polling can generate significant GitHub API traffic across 14 clusters. We mitigated this with webhook receivers instead of polling and by using OCI artifacts for Helm charts instead of Git-based HelmRepositories.
# Flux webhook receiver to replace polling
apiVersion: notification.toolkit.fluxcd.io/v1
kind: Receiver
metadata:
name: github-receiver
namespace: flux-system
spec:
type: github
secretRef:
name: webhook-token
resources:
- apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
name: app-manifests
On our largest cluster (400 nodes, approximately 12,000 pods), Flux maintained a combined memory footprint of around 512 MB across all controllers. ArgoCD on a comparable cluster consumed 4 GB for the application controller and 2 GB for the repo server. The resource difference is significant at scale and is a direct consequence of ArgoCD's centralized architecture.
Developer Experience
ArgoCD wins on developer experience for teams that are not deeply Kubernetes-literate. The web UI provides application topology views, log streaming, resource tree visualization, and one-click rollbacks. Developers can see their deployment status without touching kubectl. The ApplicationSet controller further improves the experience by generating applications from templates, reducing boilerplate for teams managing many similar services.
Flux's developer experience is CLI-first. The flux CLI is excellent for operators but presents a learning curve for application developers. There is no official UI, though third-party options like Weave GitOps exist. In practice, we built a thin internal portal on top of Flux's notification controller webhooks to give developers deployment visibility -- essentially recreating what ArgoCD provides out of the box.
One area where Flux's approach pays off is CI/CD integration. Because Flux resources are plain CRDs, updating image tags or chart versions in Git is the only interface. Any CI system that can commit to a Git repository can trigger Flux deployments, which eliminates the need for ArgoCD-specific API calls or CLI invocations in pipelines.
When to Pick Which
After operating both in production for two years, our recommendations:
Choose Flux when:
- Your team has strong Kubernetes and GitOps expertise.
- You want fine-grained control over the reconciliation pipeline.
- You prefer composable, Unix-philosophy tooling over monolithic platforms.
- Your cluster count is moderate (under 10) and per-cluster autonomy is valued.
- You are already invested in Kustomize-heavy workflows.
- Resource efficiency per cluster is a concern (edge, IoT, cost-constrained environments).
Choose ArgoCD when:
- You need a unified multi-cluster management plane with a visual interface.
- Developer self-service and visibility (via UI) are priorities.
- You manage a large number of applications and need centralized observability.
- Your teams use a mix of Helm, Kustomize, and Jsonnet.
- You want RBAC-scoped access to deployment operations via the UI or API.
- You need built-in SSO, audit logging, and fine-grained project-level access control.
We ultimately consolidated on ArgoCD for application delivery and retained Flux for cluster-level infrastructure bootstrapping (cert-manager, ingress controllers, CRDs). This hybrid approach leverages ArgoCD's strengths in application management and developer experience while using Flux's lightweight reconciliation for foundational cluster components that rarely need a UI.
Neither tool is categorically better. The right choice depends on your team's operational maturity, cluster topology, and how much you value a polished UI versus composable primitives. What matters most is committing to the GitOps model itself -- the specific controller is a secondary decision.