> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/argoproj/argo-cd/llms.txt
> Use this file to discover all available pages before exploring further.

# High Availability Installation

> Install Argo CD in HA mode for production environments

The High Availability (HA) installation is the recommended deployment method for production environments. It provides redundancy, resiliency, and the ability to handle component failures without service disruption.

<Info>
  Argo CD is largely stateless. All data is persisted as Kubernetes objects in etcd. Redis is only used as a disposable cache and can be safely rebuilt without service disruption.
</Info>

## Prerequisites

* Kubernetes cluster (version 1.27+)
* **Minimum 3 worker nodes** (required for pod anti-affinity rules)
* kubectl CLI configured with cluster-admin access
* IPv4 networking (IPv6-only clusters are not supported)

<Warning>
  The HA installation requires at least **three different nodes** due to pod anti-affinity rules that prevent multiple replicas of the same component from running on the same node.
</Warning>

## Installation

<Steps>
  <Step title="Create the namespace">
    Create a dedicated namespace for Argo CD:

    ```bash theme={null}
    kubectl create namespace argocd
    ```
  </Step>

  <Step title="Apply the HA manifest">
    Install Argo CD using the HA manifest:

    ```bash theme={null}
    kubectl apply -n argocd --server-side --force-conflicts \
      -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/ha/install.yaml
    ```

    For a specific version:

    ```bash theme={null}
    kubectl apply -n argocd --server-side --force-conflicts \
      -f https://raw.githubusercontent.com/argoproj/argo-cd/v2.14.0/manifests/ha/install.yaml
    ```
  </Step>

  <Step title="Verify the deployment">
    Check that all pods are running with multiple replicas:

    ```bash theme={null}
    kubectl get pods -n argocd
    ```

    Expected output (with multiple replicas):

    ```
    NAME                                               READY   STATUS
    argocd-application-controller-0                    1/1     Running
    argocd-applicationset-controller-xxx               1/1     Running
    argocd-dex-server-xxx                              1/1     Running
    argocd-notifications-controller-xxx                1/1     Running
    argocd-redis-ha-haproxy-xxx                        1/1     Running
    argocd-redis-ha-haproxy-yyy                        1/1     Running
    argocd-redis-ha-haproxy-zzz                        1/1     Running
    argocd-redis-ha-server-0                           2/2     Running
    argocd-redis-ha-server-1                           2/2     Running
    argocd-redis-ha-server-2                           2/2     Running
    argocd-repo-server-xxx                             1/1     Running
    argocd-repo-server-yyy                             1/1     Running
    argocd-server-xxx                                  1/1     Running
    argocd-server-yyy                                  1/1     Running
    ```
  </Step>
</Steps>

## HA Architecture

<Tabs>
  <Tab title="Component Replicas">
    ### API Server (argocd-server)

    * **Type:** Deployment
    * **Replicas:** 2+ (configurable)
    * **Purpose:** Stateless API and UI servers
    * **Scaling:** Can be scaled horizontally for load distribution

    ```yaml theme={null}
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: argocd-server
    spec:
      replicas: 3
      template:
        spec:
          containers:
          - name: argocd-server
            env:
            - name: ARGOCD_API_SERVER_REPLICAS
              value: "3"
    ```

    ### Repository Server (argocd-repo-server)

    * **Type:** Deployment
    * **Replicas:** 2+ (configurable)
    * **Purpose:** Handles manifest generation
    * **Scaling:** Scale based on repository count and manifest generation load

    ### Application Controller (argocd-application-controller)

    * **Type:** StatefulSet
    * **Replicas:** 1 (can be sharded for large deployments)
    * **Purpose:** Reconciles application state
    * **Sharding:** Enable for managing 1000+ applications or multiple clusters
  </Tab>

  <Tab title="Redis HA">
    ### Redis High Availability Setup

    The HA installation includes Redis Sentinel for automatic failover:

    **Redis StatefulSet (argocd-redis-ha-server)**

    * **Replicas:** 3
    * **Purpose:** Redis cache cluster
    * **Includes:** Redis Sentinel for leader election

    **HAProxy Deployment (argocd-redis-ha-haproxy)**

    * **Replicas:** 3
    * **Purpose:** Load balancer for Redis instances
    * **Routes:** Connections to current Redis master

    ```yaml theme={null}
    # Redis HA StatefulSet
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: argocd-redis-ha-server
    spec:
      replicas: 3
      serviceName: argocd-redis-ha
      template:
        spec:
          containers:
          - name: redis
            image: redis:7.0.15-alpine
          - name: sentinel
            image: redis:7.0.15-alpine
    ```
  </Tab>

  <Tab title="Anti-Affinity">
    ### Pod Anti-Affinity Rules

    The HA manifests include anti-affinity rules to distribute pods across nodes:

    ```yaml theme={null}
    affinity:
      podAntiAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchLabels:
              app.kubernetes.io/name: argocd-server
          topologyKey: kubernetes.io/hostname
    ```

    This ensures:

    * No single node failure affects all replicas
    * Better resource distribution
    * Improved resilience

    <Warning>
      Requires at least 3 nodes. If you have fewer nodes, you'll need to adjust or remove anti-affinity rules.
    </Warning>
  </Tab>
</Tabs>

## HA vs Standard Installation

| Component                     | Standard            | High Availability                |
| ----------------------------- | ------------------- | -------------------------------- |
| argocd-server                 | 1 replica           | 2+ replicas                      |
| argocd-repo-server            | 1 replica           | 2+ replicas                      |
| argocd-application-controller | 1 replica           | 1 replica (shardable)            |
| Redis                         | Single deployment   | Redis HA (3 replicas + Sentinel) |
| HAProxy                       | Not included        | 3 replicas                       |
| Anti-affinity                 | No                  | Yes (requires 3+ nodes)          |
| Suitable for                  | Development/Testing | Production                       |

## Scaling Strategies

<AccordionGroup>
  <Accordion title="Scaling the API Server">
    Increase replicas for handling more concurrent users:

    ```bash theme={null}
    kubectl scale deployment argocd-server -n argocd --replicas=3
    ```

    Update the `ARGOCD_API_SERVER_REPLICAS` environment variable:

    ```yaml theme={null}
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: argocd-server
    spec:
      replicas: 3
      template:
        spec:
          containers:
          - name: argocd-server
            env:
            - name: ARGOCD_API_SERVER_REPLICAS
              value: "3"
    ```

    <Note>
      The `ARGOCD_API_SERVER_REPLICAS` variable is used to divide the limit of concurrent login requests between replicas.
    </Note>
  </Accordion>

  <Accordion title="Scaling the Repository Server">
    Increase replicas for handling more manifest generation:

    ```bash theme={null}
    kubectl scale deployment argocd-repo-server -n argocd --replicas=3
    ```

    **Tuning Parameters:**

    * `--parallelismlimit`: Control concurrent manifest generations (default: 20)
    * `--repo-cache-expiration`: Cache duration (default: 24h)
    * `ARGOCD_EXEC_TIMEOUT`: Command execution timeout (default: 90s)

    ```yaml theme={null}
    containers:
    - name: argocd-repo-server
      command:
      - argocd-repo-server
      args:
      - --parallelismlimit=50
      - --repo-cache-expiration=1h
      env:
      - name: ARGOCD_EXEC_TIMEOUT
        value: "2m"
    ```
  </Accordion>

  <Accordion title="Sharding the Application Controller">
    For managing 1000+ applications, enable controller sharding:

    ```yaml theme={null}
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: argocd-application-controller
    spec:
      replicas: 2
      template:
        spec:
          containers:
          - name: argocd-application-controller
            env:
            - name: ARGOCD_CONTROLLER_REPLICAS
              value: "2"
            args:
            - --status-processors=50
            - --operation-processors=25
            - --sharding-method=consistent-hashing
    ```

    **Sharding Methods:**

    * `legacy`: UID-based distribution (non-uniform)
    * `round-robin`: Equal distribution across shards (alpha)
    * `consistent-hashing`: Bounded load algorithm (alpha)

    <Warning>
      The `round-robin` and `consistent-hashing` algorithms are experimental. Test thoroughly before using in production.
    </Warning>
  </Accordion>
</AccordionGroup>

## Namespace-Level HA Installation

For HA installation without cluster-admin privileges:

```bash theme={null}
# Install CRDs first
kubectl apply --server-side --force-conflicts \
  -k https://github.com/argoproj/argo-cd/manifests/crds\?ref\=stable

# Install HA namespace-scoped resources
kubectl create namespace argocd
kubectl apply -n argocd --server-side --force-conflicts \
  -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/ha/namespace-install.yaml
```

## Performance Tuning

<Tabs>
  <Tab title="Application Controller">
    ### Processor Configuration

    ```yaml theme={null}
    containers:
    - name: argocd-application-controller
      args:
      # For 1000 applications
      - --status-processors=50
      - --operation-processors=25
      - --repo-server-timeout-seconds=120
      env:
      - name: ARGOCD_RECONCILIATION_TIMEOUT
        value: "180s"
      - name: ARGOCD_RECONCILIATION_JITTER
        value: "60"
    ```

    ### Resource Requests/Limits

    ```yaml theme={null}
    resources:
      requests:
        cpu: 1000m
        memory: 2Gi
      limits:
        cpu: 2000m
        memory: 4Gi
    ```
  </Tab>

  <Tab title="Repository Server">
    ### Parallelism and Caching

    ```yaml theme={null}
    containers:
    - name: argocd-repo-server
      args:
      - --parallelismlimit=50
      - --repo-cache-expiration=1h
      env:
      - name: ARGOCD_EXEC_TIMEOUT
        value: "2m30s"
      - name: ARGOCD_GIT_ATTEMPTS_COUNT
        value: "3"
      - name: TMPDIR
        value: "/tmp"
      volumeMounts:
      - name: tmp
        mountPath: /tmp
    volumes:
    - name: tmp
      emptyDir:
        sizeLimit: 10Gi
    ```
  </Tab>

  <Tab title="Redis HA">
    ### Redis Resource Tuning

    ```yaml theme={null}
    # Redis StatefulSet resources
    containers:
    - name: redis
      resources:
        requests:
          cpu: 100m
          memory: 256Mi
        limits:
          cpu: 500m
          memory: 512Mi
    - name: sentinel
      resources:
        requests:
          cpu: 50m
          memory: 64Mi
        limits:
          cpu: 100m
          memory: 128Mi
    ```
  </Tab>
</Tabs>

## Monitoring and Observability

### Metrics Endpoints

All components expose Prometheus metrics:

* **argocd-server:** `:8083/metrics`
* **argocd-repo-server:** `:8084/metrics`
* **argocd-application-controller:** `:8082/metrics`

### Key Metrics

```yaml theme={null}
# Application reconciliation duration
argocd_app_reconcile

# Git request total
argocd_git_request_total

# Kubernetes API requests per application
argocd_app_k8s_request_total
```

### Enable Profiling (Optional)

```yaml theme={null}
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cmd-params-cm
  namespace: argocd
data:
  controller.profile.enabled: "true"
  reposerver.profile.enabled: "true"
  server.profile.enabled: "true"
```

Access profiling:

```bash theme={null}
kubectl port-forward svc/argocd-metrics 8082:8082 -n argocd
go tool pprof http://localhost:8082/debug/pprof/heap
```

## Upgrading

To upgrade the HA installation:

```bash theme={null}
kubectl apply -n argocd --server-side --force-conflicts \
  -f https://raw.githubusercontent.com/argoproj/argo-cd/<version>/manifests/ha/install.yaml
```

<Warning>
  Always review the [upgrade notes](https://argo-cd.readthedocs.io/en/stable/operator-manual/upgrading/overview/) before upgrading. Take backups of critical data.
</Warning>

## Disaster Recovery

### Backup Strategy

Since Argo CD stores all state in Kubernetes objects:

```bash theme={null}
# Backup all Argo CD resources
kubectl get applications,applicationsets,appprojects -n argocd -o yaml > argocd-backup.yaml

# Backup configuration
kubectl get configmaps,secrets -n argocd -o yaml > argocd-config-backup.yaml
```

### Restore Strategy

```bash theme={null}
# Restore resources
kubectl apply -f argocd-backup.yaml
kubectl apply -f argocd-config-backup.yaml
```

<Note>
  Redis is only a cache. Even if Redis data is lost, Argo CD will rebuild the cache automatically.
</Note>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Pods stuck in Pending (Anti-affinity issues)">
    If you have fewer than 3 nodes, you'll need to adjust anti-affinity rules:

    ```bash theme={null}
    kubectl patch deployment argocd-server -n argocd --type json \
      -p='[{"op": "remove", "path": "/spec/template/spec/affinity"}]'
    ```

    Or create a kustomization that removes anti-affinity rules.
  </Accordion>

  <Accordion title="Redis HA connection issues">
    Check Redis Sentinel status:

    ```bash theme={null}
    kubectl exec -it argocd-redis-ha-server-0 -n argocd -c sentinel -- \
      redis-cli -p 26379 SENTINEL masters
    ```

    Check HAProxy status:

    ```bash theme={null}
    kubectl logs -n argocd deploy/argocd-redis-ha-haproxy
    ```
  </Accordion>

  <Accordion title="High CPU/Memory usage">
    Review metrics and adjust resource limits:

    ```bash theme={null}
    kubectl top pods -n argocd
    kubectl describe pod -n argocd <pod-name>
    ```

    Consider enabling profiling to identify bottlenecks (see Monitoring section).
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Configure SSO" icon="key" href="/configuration/sso">
    Set up Single Sign-On for your team
  </Card>

  <Card title="Add Clusters" icon="server" href="/configuration/clusters">
    Register external Kubernetes clusters
  </Card>

  <Card title="Monitoring" icon="chart-line" href="/operations/monitoring">
    Set up Prometheus and Grafana
  </Card>

  <Card title="Backup & Restore" icon="database" href="/operations/disaster-recovery">
    Implement disaster recovery
  </Card>
</CardGroup>
