Argo CD Core Components Explained: Architecture, Roles, and Implementation Details
Argo CD consists of seven tightly-coupled components—the Application Controller, Repo Server, API Server, State Cache, Metrics Server, Hydrator, and CLI—that together implement a declarative GitOps workflow by reconciling Git repository state with live Kubernetes cluster resources.
Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes maintained in the argoproj/argo-cd repository. Understanding the Argo CD core components and their interactions is essential for operators who need to troubleshoot sync failures, optimize performance, or extend the platform with custom plugins. Each component serves a distinct purpose in the reconciliation pipeline, from fetching Git manifests to health-checking deployed resources.
Application Controller: The Reconciliation Engine
The Application Controller (controller/appcontroller.go) is the primary control loop that watches Application custom resources, reconciles desired state from Git with live cluster state, and handles synchronization, health checks, pruning, and finalizers.
This component maintains several rate-limited workqueues—including appRefreshQueue, operationQueue, and hydrationQueue—to manage concurrent operations without overwhelming the Kubernetes API. When a user requests a sync, the controller calls requestAppRefresh, which adds the application’s key to the refresh queue.
The controller publishes events to the Metrics Server for observability and delegates manifest generation to the Repo Server via gRPC calls. It relies on the State Cache to perform fast diffing between Git-defined resources and live cluster objects, avoiding expensive API calls for every reconciliation cycle.
Repo Server: Manifest Generation and Caching
The Repo Server (reposerver/server.go) functions as a specialized gRPC service that renders Kubernetes manifests from Git repositories, executes Config Management Plugins (CMP), Helm, Kustomize, and Jsonnet templates, and aggressively caches results to minimize clone operations.
When the Application Controller needs manifests, it invokes methods like repoClient.GetManifest against this service. The Repo Server persists cloned repositories in temporary directories and maintains an internal cache (reposerver/cache) to serve subsequent requests without re-fetching from Git. The NewServer function in reposerver/server.go initializes this gRPC service with optional TLS/mTLS encryption for secure cross-cluster communication.
API Server: Authentication and RBAC Layer
The API Server (cmd/argocd-server/commands/argocd_server.go), also referred to as argocd-server, hosts the web UI, REST/gRPC APIs, and the complete RBAC enforcement layer. This component authenticates users via OIDC, Dex, or local accounts before proxying application-specific requests to the Application Controller and Repo Server.
Unlike the controller which runs reconciliation loops, the API Server is primarily request-response oriented. It validates incoming Application CR updates, enforces project-level permissions, and serves real-time streaming data to the UI using the same gRPC contracts consumed by the CLI.
State Cache: Live Resource Indexing
The State Cache (controller/cache/cache.go) maintains an in-memory graph of live Kubernetes objects across all managed clusters, enabling O(1) lookups for resource health and relationships. This component runs informers that watch the Kubernetes API for changes, updating the cache index whenever resources are created, modified, or deleted.
During sync operations, the Application Controller queries this cache rather than listing resources directly from the API server, significantly reducing latency for large-scale deployments. The UI also queries this cache to display real-time application status without triggering API server load.
Metrics Server: Observability and Alerting
The Metrics Server (controller/metrics/metrics.go) exposes Prometheus-compatible metrics via an HTTP /metrics endpoint, ingesting data from the Application Controller and State Cache. Key metrics include app_refresh_total for sync counters, kubectl_exec_seconds for command latency, and orphaned resource warnings.
This component enables GitOps observability by tracking operation duration, queue depths, and resource utilization across the control plane. Operators can scrape these metrics to build dashboards alerting on sync failures or performance degradation in specific controllers.
Hydrator: Manifest Pre-Processing
The Hydrator (controller/hydrator/hydrator.go) is an optional component that expands high-level configuration tools—such as Helm charts, Kustomize bases, and Jsonnet—into raw Kubernetes manifests before storage in the Repo Server. Running in a dedicated workqueue to avoid blocking the main controller loop, the Hydrator writes hydrated manifests back to the repository when enabled.
This separation allows complex template rendering to occur asynchronously, preventing Helm or Kustomize execution from delaying active synchronization operations. The controller checks for hydrated manifests before requesting raw generation from the Repo Server.
CLI: Command-Line Interface
The Argo CD CLI (cmd/argocd/commands/*) provides a command-line client that communicates directly with the API Server, useful for scripting, CI/CD pipelines, and automation. Implemented in Go, the CLI uses identical gRPC/REST contracts as the web UI, ensuring a single source of truth for API behavior.
Commands such as argocd app sync translate to API calls that ultimately trigger the Application Controller’s reconciliation workflow, demonstrating how user-facing tools integrate with the core backend components.
How Argo CD Core Components Work Together
The following workflow illustrates how these components coordinate to deploy an application:
-
User Interaction – A developer creates or updates an
ApplicationCR via the UI, CLI (cmd/argocd/commands/app.go), or API Server. -
API Validation – The API Server validates the request, enforces RBAC policies, and persists the CR to the Kubernetes API.
-
Event Processing – The Application Controller detects the change via its informer, enqueuing a refresh request in
appRefreshQueue. -
Manifest Generation – The controller calls the Repo Server (
reposerver/server.go) to fetch or generate manifests from the specified Git revision. -
State Comparison – Using the State Cache (
controller/cache/cache.go), the controller compares desired Git state against live cluster resources without hitting the API server directly. -
Synchronization – The controller issues
kubectlapply, patch, or delete operations to converge the cluster state, respecting sync options like--pruneand--dry-run. -
Metrics Export – Throughout the cycle, the controller updates the Metrics Server with latency and status data for Prometheus scraping.
-
Optional Hydration – If enabled, the Hydrator preprocesses templates before the Repo Server caches the final manifests.
Code Examples: Interacting with Core Components
Triggering a Manual Sync via the API
The following Go code demonstrates how to request a manual application refresh, which enters the Application Controller’s processing queue:
// client is a generated Go client for the Argo CD API
ctx := context.Background()
appName := "default/my-app"
// Trigger a refresh with the latest revision
_, err := client.ApplicationService.Refresh(ctx, &application.ApplicationRefreshRequest{
Name: appName,
Namespace: "default",
Revision: "", // empty = latest
Prune: false,
DryRun: false,
Force: false,
Strategy: nil,
Resources: nil,
})
if err != nil {
log.Fatalf("Refresh failed: %v", err)
}
This request routes to controller/appcontroller.go → requestAppRefresh, which adds the application key to appRefreshQueue for reconciliation.
Registering a Repository with the Repo Server
To interact directly with the Repo Server for repository configuration:
// repoReq creates a repository definition for the Repo Server
repoReq := &apiclient.RepoServerSetGitRepositoryRequest{
Repository: &apiclient.GitRepository{
Repo: "https://github.com/example/manifests.git",
Username: "gituser",
Password: "gitpass", // secret – stored in a Kubernetes secret
Insecure: false,
},
}
resp, err := repoClient.SetGitRepository(ctx, repoReq)
if err != nil {
log.Fatalf("Failed to set repo: %v", err)
}
log.Printf("Repo cached at revision %s", resp.Revision)
The Repo Server’s NewServer function implements the SetGitRepository gRPC method defined in reposerver/server.go, caching the cloned repository for subsequent manifest generation calls.
Summary
- Argo CD core components form a declarative GitOps control plane consisting of the Application Controller, Repo Server, API Server, State Cache, Metrics Server, Hydrator, and CLI.
- The Application Controller (
controller/appcontroller.go) manages the central reconciliation loop using rate-limited queues and informers. - The Repo Server (
reposerver/server.go) generates and caches manifests via gRPC, supporting Helm, Kustomize, and custom plugins. - The State Cache (
controller/cache/cache.go) provides in-memory indexing of live cluster resources for fast diffing and health checks. - The API Server (
cmd/argocd-server/commands/argocd_server.go) handles authentication, RBAC, and UI serving as the user-facing entry point. - The Metrics Server (
controller/metrics/metrics.go) exposes Prometheus metrics for operational observability. - The Hydrator (
controller/hydrator/hydrator.go) optionally preprocesses templates asynchronously to prevent blocking the main sync loop.
Frequently Asked Questions
What is the primary responsibility of the Application Controller in Argo CD?
The Application Controller watches Application custom resources and reconciles the desired state stored in Git with the live state running in Kubernetes clusters. It handles synchronization, pruning, health assessments, and finalizers while managing work through prioritized queues like appRefreshQueue defined in controller/appcontroller.go.
How does the Repo Server improve Argo CD performance?
The Repo Server caches Git repository data and rendered manifests in memory, avoiding redundant clones and template executions. By serving pre-generated manifests via gRPC to the Application Controller, it eliminates network latency to Git providers and reduces computational overhead for repeated sync operations on the same commit.
What is the difference between the API Server and the Application Controller?
The API Server (cmd/argocd-server/commands/argocd_server.go) is a stateless request-response service handling user authentication, RBAC enforcement, and UI serving. The Application Controller (controller/appcontroller.go) is a stateful control loop that continuously watches resources and performs reconciliation. The API Server receives user commands and proxies them to the controller, which executes the actual GitOps synchronization logic.
When should I enable the Hydrator component in Argo CD?
Enable the Hydrator (controller/hydrator/hydrator.go) when using complex templating tools like Helm, Kustomize, or Jsonnet that require significant CPU time to render manifests. The Hydrator runs these operations in a separate workqueue, preventing expensive template rendering from blocking urgent synchronization operations in the main Application Controller loop.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →