Skip to content

Reference Architecture

This page brings together production-tested architecture patterns, sizing math, and best practices for deploying ClusterControl and the database clusters it manages. The individual pieces: hardware sizing, HA setup, load balancer placement, network security, offline deployment, DR strategy are documented in depth on their own pages. This page assembles them into complete blueprints and answers "given my situation, what should this actually look like end to end?"

Use it as follows:

  1. Start with server sizing, networking, storage layout, SSH key management, and whether you need external CMON DB/Prometheus. These apply to every deployment regardless of size.
  2. Pick a ClusterControl deployment architecture based on how critical and how large your fleet is.
  3. Layer in multi-site/multi-datacenter, offline/restricted-network, or cloud considerations as they apply to your environment.
  4. Compare your plan against the worked example deployments and the database cluster topologies for the engines you run.

Info

This page is a curated overview, not a replacement for the detailed pages it links to. For exact step-by-step configuration, follow the links inline.

Resource consumption on the ClusterControl host is driven primarily by:

  • Number of managed nodes (database + load balancer): Each node adds SSH polling, Prometheus scrape targets, and CMON database writes.
  • Number of clusters: Each cluster gets its own CMON configuration file (/etc/cmon.d/cmon_<id>.cnf) and adds its own recurring management/monitoring jobs to the controller's workload.
  • Monitoring interval and retention: db_stats_collection_interval and host_stats_collection_interval (see ClusterControl Configuration) control how often CMON writes monitoring samples. Prometheus's own scrape interval and retention (default 15 days) control exporter-side storage.
  • Query monitoring: Agent-based query monitoring (cmonagent) adds CPU and network overhead per monitored node, proportional to query throughput.
  • Backup activity: Streaming backups through the ClusterControl host (rather than direct node-to-node or node-to-cloud) add CPU, network, and disk I/O spikes during backup windows.

Sizing tiers

Tier Managed nodes Recommended ClusterControl host HA/scale pattern
Minimum 1 2 CPU, 2 GB RAM, 20 GB disk Single instance
Small 3 – 15 4 CPU, 8 GB RAM, 50 GB disk Single instance. Add a Secondary Standby if the fleet is business-critical
Medium 15 – 50 16 CPU, 16 GB RAM, 150 GB disk Single instance + Secondary Standby, or CMON Controller Pool
Large 50 – 150 24 CPU, 32 GB RAM, 300 GB disk CMON Controller Pool or ClusterControl Replication with VIP
Very large 150 – 1000+ Multiple hosts, each sized as "Large" 5–8+ ClusterControl instances behind Ops-C

Note

The "Very large" instance count and the HA/scale pattern assigned to each tier are rough guidelines, not prescriptive rules: the right HA pattern depends more on criticality than raw node count, and the 5–8 figure is a documented starting point (How it Works? → Multiple controllers management) to adjust from based on observed per-instance load rather than follow rigidly.

The host specs above are baseline minimums by managed-node count, taken from the hardware requirements table. Cluster count, monitoring interval/retention, agent-based query monitoring, and streaming backups through the ClusterControl host (the drivers listed above) all add load independent of node count, so a fleet with many clusters or heavy query/backup activity should size toward the higher end of, or above, its tier. The Capacity planning section documents a real-world reference point of 8–24 CPU cores, 8–32 GB RAM, and 300 GB disk for a single controller managing 67 clusters (~130 nodes), meaningfully heavier than this table's Small/Medium figures for a similar node count. Treat the tiers here as a starting point and validate against observed load, not as a hard ceiling.

See Requirements → Hardware for the underlying reasoning per resource (CPU/RAM/disk/network), and Tuning for Large Deployment once a host is running hot.

CPU and RAM calculation

  • Start from the tier table above, based on managed node count, then adjust up if you have many small clusters (each with its own CMON configuration and recurring job/monitoring overhead) rather than few large ones, or if agent-based query monitoring is enabled fleet-wide.
  • RAM is dominated by the CMON database's InnoDB buffer pool. By default, ClusterControl allocates 50% of host RAM to innodb_buffer_pool_size. On a host dedicated to ClusterControl, you can push this to 70%, provided at least 2 GB is reserved for OS processes and caches:

    innodb_buffer_pool_size = total_RAM × (0.5 to 0.7)
    reserved_for_OS         ≥ 2 GB
    

    Check the InnoDB buffer pool hit ratio (SHOW ENGINE INNODB STATUS\G). A ratio close to 1000/1000 means the working set fits in RAM. A lower ratio means either more RAM or a higher buffer pool percentage is needed. See Tuning for Large Deployment → Tuning InnoDB buffer pool size for the safe change procedure.

Disk calculation

Disk usage has three independent drivers that should be sized and ideally partitioned. See Section 3 separately:

  1. CMON database growth: Driven by db_stats_collection_interval/host_stats_collection_interval (lower interval = more rows written per unit time) and the number of managed nodes/clusters. There is no fixed formula here since it depends on cluster count and history retention. Monitor /var/lib/mysql growth over the first weeks of production use and adjust.

  2. Prometheus time-series storage: This one is approximately calculable using Prometheus's general storage rule of thumb of ~1–2 bytes per compressed sample (a widely-used approximation from Prometheus's own storage model, not a ClusterControl-specific figure. Treat it as a starting estimate rather than an exact prediction):

    disk_bytes ≈ (active_time_series_count) × (86400 / scrape_interval_seconds) × retention_days × ~1.5 bytes
    

    Each managed node contributes multiple time series (node/process exporter + database-specific exporter. See How it Works? → Monitoring tools for the full exporter list). Increasing retention beyond the 15-day default, or adding many nodes, increases /var/lib/prometheus disk usage roughly linearly. See Requirements → Disk space.

  3. Backup repository (if used). See Backup repository architecture below. Size this independently of the two drivers above, since backup sets can dwarf monitoring data.

Real-world reference point

A single ClusterControl server with 24 CPUs, 32 GB RAM, and 150 GB disk (running at ~92% disk usage) has been observed in production managing 67 clusters and around 130 database/load balancer nodes. See How to Optimize Performance of ClusterControl and Its Components for tuning guidance beyond this point.

Backup repository architecture

Where backups land is itself a sizing and architecture decision:

  • On the database node: Fastest, no network hop, but ties the backup's survival to the node's survival.
  • On the ClusterControl node: Convenient for small deployments, but adds directly to the disk sizing above, and is explicitly not recommended if you run ClusterControl Replication.
  • Shared storage (NFS/CIFS/SMB) mounted identically across ClusterControl HA nodes. Required if backups need to be visible to more than one ClusterControl node.
  • Cloud/object storage (S3-compatible, Azure Blob, GCS): The recommended default for offsite durability. See Section 9 and Admin Guide → Backup & Restore.

Monitoring subsystem sizing

By default, all clusters share one Prometheus instance on the ClusterControl host. Split off a dedicated Prometheus host for a specific cluster when:

  • A single cluster generates a disproportionate share of metrics volume (very high node count, very high query rate).
  • The combined metrics volume across all clusters makes the shared instance a bottleneck.
  • You need a longer retention period than the 15-day default.

See Section 5 for how to configure a dedicated or fully external Prometheus.

2. Networking setup

ClusterControl should sit in a management zone that can reach the database zone over SSH, database-native, and Prometheus scrape ports, but is not directly reachable from the public Internet.

flowchart LR
    admin[/DBA / SysAdmin/] -->|HTTPS 443,<br>admin network only| bastion([Bastion / VPN<br>optional but recommended])
    bastion --> cc[ClusterControl<br>Management Zone]
    internet[/Internet/] -.->|blocked| cc
    internet -.->|blocked| dbzone
    cc -->|SSH 22, database-native ports,<br>Prometheus scrape 9011/9100+| dbzone@{ shape: procs, label: "Database & Load<br>Balancer Zone" }
    ops -.->|CMON RPC 9500/9501 via ClusterControl Proxy| cc

Port matrix

Service Default port
SSH 22
HTTPS (ClusterControl GUI) 443
CMON RPC 9500
CMON RPC (TLS) 9501
CMON Events (notifications) 9510
CMON SSH (web-based console) 9511
CMON Cloud 9518
Streaming backup transfer (socat/netcat) 9999, falling back to 9990–9998 (configurable)
ClusterControl Proxy (Ops-C / multi-controller) 19501
Prometheus 9090
Node/process exporters (all managed nodes) 9100 / 9011

This is a condensed view. The full per-database-engine and per-load-balancer port matrix (MySQL, Galera, MongoDB, PostgreSQL, HAProxy, ProxySQL, MaxScale, Keepalived, garbd, SQL Server, Redis/Valkey, Elasticsearch) is maintained in one place to avoid drift: see Requirements → Firewall and security groups. Open the full 9990–9999 range (not just 9999) so concurrent or fallback backup streams aren't blocked; see netcat_port in Reference Manuals → ClusterControl Controller.

SSH trust model

  • Management/deployment operations are agentless, relying entirely on passwordless, key-based SSH from the ClusterControl host to every managed node. Monitoring, by contrast, is agent-based (Prometheus + exporters, plus cmonagent for query monitoring). See How it Works? → Monitoring operation.
  • Trust is one-directional: managed nodes never need to SSH back into the ClusterControl host.
  • Lock down SSH so that managed nodes only accept SSH connections from the ClusterControl host, and the ClusterControl host itself is not reachable via SSH from outside the admin network. See Securing ClusterControl → SSH and Requirements → SSH key-based authentication.

Encryption architecture

Traffic Recommendation
Admin/browser → ClusterControl GUI HTTPS with a properly signed certificate (default is self-signed). See Securing ClusterControl → HTTPS
ClusterControl clients → CMON controller Prefer RPC-TLS (port 9501) over plaintext RPC (port 9500)
Application → database Enable database-native TLS and manage certificates centrally. See Management → Certificates
Database → database (replication) Enable replication-layer TLS where supported by the database engine
ClusterControl → cloud/offsite backup storage Use the cloud provider's TLS endpoint. Consider backup encryption at rest

Secrets management and centralized authentication

For stricter secrets management than flat CMON configuration files (which must be locked to 700 permissions, root-owned. See Securing ClusterControl → File permission), integrate HashiCorp Vault: the controller authenticates to Vault on startup and stores/retrieves credentials there instead.

flowchart LR
    cmon[ClusterControl<br>Controller] -->|fetch credentials<br>on startup| vault[(HashiCorp Vault)]
    cmon -->|manage & monitor| db@{ shape: procs, label: "Database nodes" }

See Integration → Hashicorp Vault for configuration parameters (vault_token, vault_addr, vault_path, vault_auto_migrate).

For access control, integrate an existing directory service (Active Directory, FreeIPA, OpenLDAP) so users authenticate with corporate credentials, and map LDAP groups onto ClusterControl user groups/privileges, combined with Users & Teams to scope what each team can see and do. See Integration → LDAP.

3. Storage configuration and partitioning

Rather than a single root partition for everything, separate the workloads that write to disk so a runaway one (typically backups or Prometheus) cannot starve the others:

Mount point Contains Notes
/ (root) OS, ClusterControl packages Keep this insulated from data growth by moving the items below to their own mounts
/var/lib/mysql CMON database (MySQL/MariaDB) Fast, low-latency storage (SSD). This is on the hot path for every job and monitoring write
/var/lib/prometheus Prometheus time-series data Size per the disk calculation above. Grows with retention and node count
/var/log (or a dedicated log partition) cmon.log, cmon_<id>.log CMON writes almost every second per cluster, so a spindle/cheap disk is fine here since writes are sequential. Point logfile= in cmon_X.cnf at this partition
Backup repository mount Local backup copies (if stored on the ClusterControl node) Use a separate partition, ideally on networked/clustered storage (NFS/CIFS/SMB) for easy mounting during restores. Never let this share the root partition

See Tuning for Large Deployment → File System and Partitioning and Requirements → Disk space for the full guidance this table is based on.

4. SSH key management and rotation

Initial setup

ClusterControl uses libssh with RSA (fully tested) or other supported public-key algorithms (ssh-dss, ssh-ed25519, ecdsa-sha2-nistp256/384/521) for passwordless, key-based SSH from the ClusterControl host to every managed node. See Requirements → SSH key-based authentication for generating and distributing the initial key pair, and Requirements → Operating system user for the sudo/pbrun/doas privilege-escalation options that pair with it.

Best practices for the key itself:

  • Use a dedicated key pair for ClusterControl. Never reuse a personal or shared administrator key, so revoking access for one purpose doesn't require rotating everything else that key touches.
  • Keep the private key permissioned 600 and owned by root, the standard SSH requirement for a private key file, stricter even than the 700 required of CMON configuration files themselves (see Securing ClusterControl → File permission).
  • For larger or segmented environments, consider a key per environment or per network segment (e.g., one key for production, one for staging) to limit blast radius if a single key is ever compromised.

Rotation procedure

ssh_identity is a per-cluster CMON configuration option (set inside /etc/cmon.d/cmon_<id>.cnf). If it is left undefined for a cluster, CMON falls back to the os_user's home directory and looks for .ssh/id_rsa. If every cluster relies on that default rather than setting ssh_identity explicitly, they all resolve to the same key path, which is consistent with how Migrating ClusterControl to Another Server handles the key: it copies/replaces the key at that one fixed path (e.g. /root/.ssh/id_rsa) rather than editing every cmon_<id>.cnf. If you have set ssh_identity explicitly to a custom, per-cluster path for any cluster, you'll need to update those files individually instead. Rotate without downtime by adding the new key before removing the old one:

  1. Generate a new key pair at a temporary path on the ClusterControl host (ssh-keygen -t rsa -f ~/.ssh/id_rsa.new), keeping the old key pair in place for now.
  2. Append (not replace) the new public key to ~/.ssh/authorized_keys on every managed node, via configuration management or with ssh-copy-id -i ~/.ssh/id_rsa.new.pub <os_user>@<managed-node>.
  3. Verify passwordless SSH with the new identity from the ClusterControl host to every node (ssh -i ~/.ssh/id_rsa.new <os_user>@<managed-node>).
  4. Move the new private key over the existing path (e.g. mv ~/.ssh/id_rsa.new /root/.ssh/id_rsa and mv ~/.ssh/id_rsa.new.pub /root/.ssh/id_rsa.pub). Only if ssh_identity= was explicitly set to a custom, per-cluster path do you need to place it there and update the corresponding /etc/cmon.d/cmon_<id>.cnf files instead.
  5. Restart the cmon service and confirm management/monitoring jobs continue to run normally.
  6. Once confirmed stable, remove the old public key from authorized_keys on every managed node, and securely delete the old private key.

  7. Rotate on a regular schedule (aligned to your organization's key-rotation policy) and immediately after any personnel offboarding or suspected key exposure.

  8. Migrating ClusterControl to new hardware is a natural point to rotate keys as well. See Migrating ClusterControl to Another Server, which calls out key rotation explicitly as part of security/compliance re-segmentation.

5. Using an external CMON database and external Prometheus

External CMON database

By default, the installer provisions a local MySQL/MariaDB server on the ClusterControl host to act as the CMON database (mysql_hostname=127.0.0.1). This can instead point at a MySQL/MariaDB server you already operate, for example a centrally-managed, already-HA MySQL service:

  • During manual installation, initialize the controller against a remote database explicitly:

    cmon --init \
         --mysql-hostname="<external-db-host-or-ip>" \
         --mysql-port="3306" \
         --mysql-username="cmon" \
         --mysql-password="xxxx" \
         --mysql-database="cmon" \
         --hostname="<clustercontrol-host-ip>" \
         --rpc-token="<generated-token>" \
         --controller-id="clustercontrol"
    

    See Manual Installation for the full procedure, and the mysql_hostname/mysql_port configuration options for all supported aliases. * The install script (install-cc) also supports reusing an existing local MySQL server rather than installing a new one. See Quickstart.

Attention

The CMON database sits on the hot path for nearly every management and monitoring operation, so an external database must be low-latency (TCP, not WAN) and reachable at all times, or ClusterControl will block waiting for a working connection. Plan its own HA and backups independently. ClusterControl does not manage the lifecycle of a database it did not provision.

External Prometheus

There are two distinct patterns, depending on whether ClusterControl should manage the Prometheus lifecycle:

  • Dedicated Prometheus node, still managed by ClusterControl: reconfigure a cluster's agent-based monitoring to point at a separate host over SSH (prometheus_hostname, prometheus_ssh_user, and related options). ClusterControl still installs, configures, and daemonizes Prometheus and exporters there. See Integration → Prometheus.
  • Fully external Prometheus, not managed by ClusterControl: use the cmon_sd service discovery tool, which exposes an HTTP endpoint listing every node ClusterControl currently manages (as Prometheus http_sd_configs targets). Point your own, independently-run Prometheus at this endpoint instead of relying on ClusterControl's built-in instance.
flowchart LR
    cmon[ClusterControl<br>Controller] -->|TCP: mysql_hostname| extdb[(External MySQL/MariaDB<br>managed elsewhere)]
    cmon -.->|SSH: prometheus_hostname| dedicatedprom[(Dedicated Prometheus<br>still CC-managed)]
    cmonsd[cmon_sd<br>service discovery] -->|HTTP targets| extprom[(Fully external Prometheus<br>not CC-managed)]
    cmon -.-> cmonsd

6. ClusterControl deployment architectures

6.1 Single ClusterControl controller

The default and simplest architecture: one cmon controller manages one or more clusters. Per How it Works? → Architecture, "ClusterControl components must reside on a node separate from the database cluster". For example, a three-node Galera Cluster requires ClusterControl on a fourth, independent node (see Online Installation → Requirements). Running it on a managed database node itself isn't a supported topology.

flowchart LR
    A[/DBA/SysAdmin/] -->|HTTPS/CLI| B[["ClusterControl<br>#40;single instance#41;"]]
    B -->|SSH + Prometheus| C@{ shape: procs, label: "Database &<br>load balancer nodes" }

Appropriate for small, non-critical fleets (see the sizing tiers). Has no built-in redundancy for the ClusterControl layer itself: if this host is lost, monitoring and automation pause until it (or a restore of it) comes back, though the database clusters themselves keep running unaffected.

6.2 Active/passive secondary standby

A second, independent ClusterControl instance imports and monitors the same clusters as the primary, but with auto-recovery disabled, so it never races the primary to perform failover.

flowchart TD
    U[/DBA/<br>SysAdmin/] --> A[ClusterControl A<br><i><strong>Active</strong></i><br>#40;auto-recovery enabled#41;]
    B[ClusterControl B<br><i><strong>Standby</strong></i><br>#40;auto-recovery disabled#41;]
    A ==> |manage & monitor|D[[Database/<br>Load balancer nodes]]
    B ==> |monitor only|D
  • No shared state between the two instances: each has its own CMON database and configuration.
  • Promotion is manual: to fail over, enable auto-recovery on the standby and disable it on the old primary.
  • Cheapest and simplest HA pattern. Also, the natural monitoring leg of a multi-site deployment.
  • One license covers both instances: licensing is bound to managed node count, not ClusterControl instance count.

See Redundancy & High Availability → Secondary Standby for the full setup procedure.

6.3 CMON Controller Pool

A pool of controllers shares the workload of managing clusters, instead of a single controller carrying the entire fleet. GA since ClusterControl 2.4.0.

flowchart TB
    u[/DBA/SysAdmin/] --> gui[ClusterControl GUI]
    subgraph pool["CMON Controller Pool #40;shared config via NFS#41;"]
        c1[Controller 1]
        c2[Controller 2]
        c3[Controller 3]
    end
    gui --> c1 & c2 & c3
    c1 & c2 & c3 -.->|shared configuration| nfs[(NFS)]
    c1 & c2 & c3 -->|manage & monitor<br>a subset of clusters| db@{ shape: procs, label: "Database & load<br>balancer nodes" }
  • Horizontal scaling: controllers can be added to or removed from the pool as workload grows or shrinks, redistributing clusters across the pool.
  • Shared CMON configuration kept consistent across the pool via NFS.
  • Gradual adoption: pool mode can be enabled/disabled on an existing controller without a full re-deployment.
  • Reach for this pattern when a single controller becomes a performance bottleneck, not just an availability one, e.g., medium-to-large fleets where job scheduling and monitoring load need to be spread horizontally.

See Redundancy & High Availability → CMON Controller Pool for enabling, adding, and removing controllers.

6.4 ClusterControl Replication with VIP

A primary-secondary HA architecture built from open-source building blocks (MySQL replication, rsync/lsyncd, Keepalived), where only one ClusterControl instance is active at a time and a virtual IP (VIP) provides a single, stable endpoint for both the GUI and outbound management traffic. Introduced in ClusterControl 2.4.0.

flowchart TD
    U[/DBA/<br>SysAdmin/] --> V((VIP))
    V --> |active|A[ClusterControl A<br>#40;**primary**#41;] -..-> |replicate|B[ClusterControl B<br>#40;**secondary**#41;]
    V -..-> |standby|B
    A & B --> C([Prometheus<br>external, dedicated host])
    A ==> |outbound<br>via VIP|V ==> D[[Database/<br>Load balancer nodes]]
    subgraph "ClusterControl Replication"
        A
        B
    end

Key components and constraints:

  • MySQL replication gives CMON database redundancy (primary → replica). File syncing (rsync/lsyncd) keeps ClusterControl's own files consistent one-way. Keepalived owns the VIP.
  • Requires a minimum of 3 nodes: two ClusterControl nodes plus an external Prometheus host: Prometheus must not be co-located with ClusterControl, and is itself a single point of failure unless you add remote-write to a second Prometheus.
  • The VIP relies on Layer-2 broadcast (VRRP), so this is a LAN pattern by default: usable across a WAN only if L2 connectivity is bridged/extended, and this is a poor fit for most cloud VPCs (see Section 9).
  • Managed cluster backups should not be stored on local disk on either ClusterControl node. The exception is shared storage (NFS/CIFS/SMB) mounted at the same path on both, since it remains reachable regardless of which node is active.
  • Requires MySQL 8+ with the CLONE plugin enabled.

See Redundancy & High Availability → ClusterControl Replication for the full deployment steps, including OS-specific instructions.

6.5 Multi-controller with Ops-C

For very large fleets, running more controllers is not enough on its own. ClusterControl Ops-C ("Operations Center") provides a single, centralized view, aggregating status across independently-running controllers through the ClusterControl Proxy (ccmgr).

flowchart TD
    A[/<b>Users</b>/] --> C
    B([<b>ClusterControl Proxy - ccmgr</b>])
    C[<b>ClusterControl Ops-C</b>]
    D[<b>ClusterControl Controller #1</b><br>/api/v2]
    F[<b>ClusterControl Controller #N</b><br>/api/v2]
    E@{ shape: procs, label: "<b>Database/Load balancer nodes</b>"}
    G@{ shape: procs, label: "<b>Database/Load balancer nodes</b>"}
    C <--> B
    B --> D
    B --> F
    D --> E
    F --> G
  • As a rule of thumb, plan for 5 to 8 ClusterControl instances per 1000+ database nodes, depending on hardware size per instance. Treat this as a starting point and adjust based on observed per-instance load (see the sizing tiers above).
  • Installed by default since ClusterControl 2.3.2, but disabled until enabled under Settings → License → Enable Multiple Controllers, which provisions a dedicated root user used only for managing CMON controllers. This integration user can itself authenticate via an existing LDAP or Active Directory service instead of a local ClusterControl password.
  • Because Ops-C only aggregates and visualizes, it does not itself need to be highly available in the same sense as a controller.

See User Guide → ClusterControl Ops-C and Reference Manuals → ClusterControl Proxy.

6.6 Choosing between patterns

Criteria Secondary Standby CMON Controller Pool ClusterControl Replication (VIP)
Primary goal Availability (DR-style) Horizontal scale + availability Availability with a single, stable endpoint
Failover Manual N/A. Workload is already distributed Automatic, VIP-based
Shared state between CC instances None Shared config via NFS MySQL replication + file sync
Extra infrastructure +1 CC host +N CC hosts, shared NFS +1 CC host, +1 dedicated Prometheus host
WAN-friendly Yes Depends on latency to shared NFS No. LAN/L2-only by default
Cloud-friendly Yes Yes Needs a cloud-native VIP substitute. See Section 9
Best for Small/medium fleets, cross-DC monitoring leg Medium/large fleets outgrowing one controller Fleets needing a single, always-on endpoint

Note

The WAN-friendly/Cloud-friendly assessment for CMON Controller Pool is a general characterization of shared-NFS behavior, not a specific claim documented in Redundancy & High Availability. Validate NFS latency and availability for your own network before relying on it across sites or clouds.

7. Multi-site / multi-datacenter deployment

Pattern A: stretched cluster across data centers

A single ClusterControl instance manages nodes spread across two or more data centers. This requires low, stable WAN latency between sites. There's no fixed, ClusterControl-documented threshold for this, but as a general guideline, keep round-trip latency as low as possible (well under 100 ms is a commonly cited target) for certification-based clustering (Galera/PXC), since every write must be certified across all sites before committing.

flowchart TB
    cc[/ClusterControl/]
    subgraph DC1["Data Center 1 (Primary)"]
        n1[(Node 1)]
        n2[(Node 2)]
    end
    subgraph DC2["Data Center 2 (DR)"]
        n3[(Node 3)]
    end
    n1 <--> n2
    n1 <-->|synchronous/asynchronous<br>replication| n3
    n2 <-->|synchronous/asynchronous<br>replication| n3
    cc -.->|manages & monitors<br>SSH / Prometheus| n1 & n2 & n3

Place ClusterControl in, or nearest to, the data center you consider primary. See Requirements → Network bandwidth. For Galera-based clusters spanning sites, use Galera segments to group nodes by physical site: only one node per segment relays writesets to the other segments, reducing cross-WAN chatter. See the Galera Segment note in Add Database Node → MySQL Galera.

Pattern B: ClusterControl HA across data centers

Applies the Secondary Standby pattern to a cross-site database topology. A single active ClusterControl instance in DC1 deploys the primary cluster and, via Create Replica Cluster, a second, independent cluster in DC2 linked by uni or bi-directional replication. The same controller manages and monitors both clusters, the same way it would if they were in one DC (this is the controller you'd run s9s replication --list against for either side. See Create Replica Cluster). A standby ClusterControl instance in DC2 imports and monitors those same two clusters as well, exactly as Secondary Standby specifies, but with auto-recovery disabled.

flowchart TB
    subgraph DC1["Data Center 1 (Primary)"]
        ccA[ClusterControl A<br>Active]
        clusterA[(Primary Cluster)]
    end
    subgraph DC2["Data Center 2 (DR)"]
        ccB[ClusterControl B<br>Standby]
        clusterB[(Secondary / Replica Cluster)]
    end
    ccA -->|manage & monitor| clusterA & clusterB
    ccB -.->|monitor only| clusterA & clusterB
    clusterA -->|replication<br>uni- or bi-directional| clusterB

If DC1 (and the active controller with it) goes down, promote the standby per Section 6.2's usual procedure (enable auto-recovery on ClusterControl B) to take over active management and monitoring of both clusters. Independently of that, failing over the database traffic to the secondary cluster means disabling read-only on it and redirecting application traffic there (automatic if a load balancer already sits in front, manual otherwise). See Deploy and Failover to Secondary Cluster for that procedure. If replication was bi-directional, failback can happen once the old primary returns and catches up to zero lag. Otherwise, the old primary must be rebuilt from the secondary.

Pattern C: cluster-to-cluster (C2C) replication

For active-active or DR setups where two separate clusters need to stay in sync, ClusterControl can create a replication layer between a source and a target cluster (uni or bi-directional) via Create Replica Cluster, initiated from the source cluster's dashboard. The clusters are independent database topologies linked by replication, not independently-managed ClusterControl deployments. The controller that creates the link manages and monitors both sides:

Cluster-to-Cluster replication diagram

Attention

Active-active (bi-directional) replication is only recommended when applications write to disjoint data sets on either cluster, since the underlying replication engines do not offer conflict detection or resolution.

All nodes in the replica cluster are read-only by default, making this pattern suitable both as read-scaling across regions and as DR: the same replica cluster can serve both purposes. See Scaling → Create Replica Cluster.

Pattern D: three-data-center quorum for Galera

A refinement of Pattern A for exactly two "real" sites: a 2-node/1-node split can survive loss of the one-node site but not loss of the two-node site. Instead, place one database node in each real site and a lightweight garbd arbitrator in a third, independent site to provide a third vote.

flowchart TB
    subgraph DC1["Data Center 1"]
        n1[(Node 1)]
    end
    subgraph DC2["Data Center 2"]
        n2[(Node 2)]
    end
    subgraph DC3["Data Center 3 (tie-breaker only)"]
        g[[garbd<br>vote-only, no data]]
    end
    n1 <-->|replication| n2
    n1 -.->|vote| g
    n2 -.->|vote| g

This gives true multi-site fault tolerance (losing any one of the three sites still leaves a quorum) at a fraction of the cost of a full third data node, since garbd carries no data. Deploy garbd on its own host in DC3, not on the ClusterControl node itself. See Create Load Balancer → Galera Arbitrator for deployment details.

Disaster recovery: backup-based fallback

Regardless of which pattern above you run, layer a low-cost, backup-based fallback underneath it: schedule backups, upload them to cloud/offsite storage, and verify restores periodically. This is slower to recover (hours, not minutes) but has no standing infrastructure cost, and catches scenarios (e.g., logical corruption) that replication alone would faithfully propagate rather than protect against.

The one-click Create Cluster from Backup GUI wizard is currently limited to Galera Cluster (MariaDB Galera, Percona XtraDB Cluster) backups. For every other engine, restore the backup onto new nodes using that engine's own restore procedure (see Admin Guide → Backup & Restore) and import the result as a new cluster instead.

8. Offline or restricted-network deployment

In air-gapped or restricted-network environments, ClusterControl, the underlying OS, and every database engine's packages must come from a repository reachable inside the network: there is no direct path to the public Internet at any point.

Two documented approaches, depending on scope:

  • Single-purpose air-gap tarball: run install-cc --airgap-repo on a temporary host matching the target OS to build and export a .deb/.rpm repository tarball, then import it on the air-gapped ClusterControl host. See Offline Installation.
  • Full satellite repository server: for air-gapped environments that also need to deploy databases (MySQL, MariaDB, PostgreSQL, MongoDB, etc.) offline, stand up an internal repository mirror serving OS, database-vendor, and Severalnines packages to every node. See Deploy Database Cluster in Offline Environment.

Operational considerations specific to this architecture:

  • What won't work without Internet, even after installation: uploading backups to cloud storage, Cloud Providers integration, load balancer deployment (needs EPEL/vendor repos), in-place upgrades, and new cluster/database deployment: all of these need their own repository access, satellite-mirrored or otherwise. See the full list in Offline Installation.
  • Monitoring exporters (Prometheus, node/process/database exporters) must be pre-downloaded into /var/cache/cmon/packages on the ClusterControl node. The source URLs are listed in /usr/share/cmon/templates/packages.conf. See How it Works? → Monitoring tools.
  • NTP must be served from an internal time source reachable by every node, since public NTP servers are unreachable. See Requirements → Timezone.
  • Licensing normally activates automatically over the Internet. For offline environments, request an offline trial license from Severalnines Sales in advance (contact Sales directly regarding production licensing for air-gapped environments). See Getting Started → Editions and releases.

9. Cloud deployment considerations

Cloud deployments follow the same architecture patterns as on-premise ones, with a handful of cloud-specific adjustments:

flowchart TB
    admin[/DBA/SysAdmin/] -->|HTTPS, via VPN/bastion| bastion([Bastion host /<br>VPN endpoint])
    subgraph vpc["Cloud VPC / VNet"]
        subgraph pub["Public subnet"]
            bastion
            nat([NAT Gateway])
        end
        subgraph priv["Private subnet#40;s#41;"]
            cc[ClusterControl<br>on persistent block storage]
            db@{ shape: procs, label: "Database & load<br>balancer nodes" }
        end
    end
    bastion --> cc
    cc -->|SSH / database-native / Prometheus| db
    db -.->|outbound package/repo access only| nat
    cc -.->|outbound package/repo/license access| nat
    cc -->|backup upload| s3[(Object storage<br>S3 / GCS / Azure Blob)]
  • Launch from a marketplace image where available to skip manual dependency setup, or install manually into an existing VPC. See ClusterControl on Marketplaces for the passwordless-SSH and key-pair setup specific to cloud-launched hosts.
  • VIP-based failover needs a cloud-native substitute. ClusterControl Replication's Keepalived VIP relies on Layer-2 broadcast (VRRP), which most cloud VPCs/VNets do not support across subnets. In the cloud, prefer the Secondary Standby or CMON Controller Pool patterns instead. If a single stable endpoint is required, a DIY option (not a ClusterControl-provided or documented feature, so build and test it independently) is to front ClusterControl with the cloud provider's own load balancer, or a reassignable Elastic IP / floating private IP driven by a custom failover script.
  • Use persistent, network-attached block storage (EBS, Persistent Disk, Managed Disk) for /var/lib/mysql (CMON DB) and /var/lib/prometheus. Never ephemeral/instance-local storage, which is lost on stop or reclaim.
  • Use native object storage for backups (Amazon S3, Google Cloud Storage, Azure Blob, or any S3-compatible provider) rather than local disk, for durability and to avoid growing the ClusterControl host's own storage. See Integration → Cloud Providers.
  • Keep ClusterControl and its managed nodes in the same region on low-latency private networking, but distribute HA database members across availability zones where supported to avoid a single-zone failure. Use a Secondary Standby or Ops-C for cross-region visibility instead of stretching a single controller across regions.
  • Security groups/NSGs replace on-prem firewalls: apply the same port matrix as security group rules, scoped to the specific subnets/security groups that need each port rather than 0.0.0.0/0.

10. Example deployments

The following examples stitch the patterns above into complete blueprints for three common situations. Treat the numbers and pattern choices as a starting point, not a hard rule. Validate against your own workload using Section 1.

10.1 SME / internal database usage (standard customers)

A typical profile for a small-to-mid-size company running ClusterControl to manage its own production databases for internal applications (ERP, e-commerce backend, internal tools), the most common ClusterControl deployment shape.

Layer Choice
ClusterControl Single instance, 4 CPU / 8 GB RAM / 50 GB disk
Database topology One Galera/PXC cluster (3 nodes) + HAProxy/Keepalived (2 nodes)
Monitoring Default shared Prometheus on the ClusterControl host
Backups Daily full + streaming to cloud storage, delete-after-upload enabled
DR Backup-based fallback only
Security Self-signed TLS acceptable initially. SSH locked to the ClusterControl host only
flowchart TB
    u{{Applications}} --> vip((VIP))
    vip -->|active| lb1[HAProxy]
    vip -.->|standby| lb2[HAProxy standby]
    lb1 & lb2 --> n1[(Node 1)] & n2[(Node 2)] & n3[(Node 3)]
    cc[/ClusterControl<br>single instance/] -.->|manages & monitors| n1 & n2 & n3 & lb1 & lb2
    cc -->|backup| cloud[(Cloud storage)]

10.2 Private DBaaS provider

A profile for a larger organization: a software vendor running many tenant/product databases internally, or a regulated enterprise (such as a bank) offering database infrastructure as an internal shared service across business units. "Private" here means the consumers are internal teams/products, not external paying customers. The emphasis shifts to multi-tenancy, RBAC, audit, and compliance rather than public self-service.

Layer Choice
ClusterControl CMON Controller Pool or Secondary Standby per region/business unit
Database topology Multiple clusters segmented per business unit/product, mixing engines per Section 11
Monitoring Dedicated Prometheus per business unit or high-volume cluster
Backups Centralized backup repository (NFS or private object storage), with scheduled verification
Access control LDAP/Active Directory-backed Users & Teams, scoped per business unit. Database Audit Logs enabled for compliance
Security RPC-TLS, HashiCorp Vault for credential storage, network-segmented per business unit
flowchart TB
    ldap[(LDAP / Active Directory)] --> gui[ClusterControl GUI]
    subgraph pool["CMON Controller Pool"]
        c1[Controller - BU A]
        c2[Controller - BU B]
    end
    gui --> c1 & c2
    c1 --> a@{ shape: procs, label: "Business Unit A clusters" }
    c2 --> b@{ shape: procs, label: "Business Unit B clusters" }
    c1 & c2 -.->|credentials| vault[(HashiCorp Vault)]
    c1 & c2 -.->|audit logs| audit[(Centralized audit log store)]

10.3 Public DBaaS provider

A profile for a telecom or service provider offering database hosting/management as a product to external, paying customers, requiring strict tenant isolation, self-service automation, and scale across regions or subsidiaries.

Layer Choice
ClusterControl Multiple controller pools per region/subsidiary, aggregated via Ops-C
Automation Customer self-service built on the ClusterControl RPC API and/or Terraform Provider, rather than the GUI directly
Database topology One cluster (or cluster set) per tenant, isolated at the network and credential level
Monitoring Dedicated Prometheus per region. Per-tenant dashboards/alerting
Backups Regional object storage repositories, isolated per tenant
Security Full RPC-TLS, Vault-backed credentials, strict per-tenant network segmentation
flowchart TB
    A[/Customers/] --> C[Self-service portal<br>#40;RPC API / Terraform#41;]
    C --> D[ClusterControl Ops-C]
    B([ClusterControl Proxy - ccmgr])
    D <--> B
    B --> R1[Controller pool<br>Region 1]
    B --> R2[Controller pool<br>Region 2]
    R1 --> E1@{ shape: procs, label: "Tenant clusters, Region 1" }
    R2 --> E2@{ shape: procs, label: "Tenant clusters, Region 2" }

At this scale, building and operating this multi-region control/data-plane split yourself is a significant undertaking. CCX, Severalnines' own hosted database-as-a-service platform, already implements this pattern as a productized control plane/data plane architecture: a control plane (RBAC, deployment, job runner, auth, backups, metrics via VictoriaMetrics/Grafana, alerting) driving a data plane that provisions MySQL, MariaDB, PostgreSQL, Redis, and SQL Server across AWS, Google Cloud, OpenStack, or VMware, backed by S3-compatible storage:

CCX Cloud Service Provider Architecture

Providers building a customer-facing DBaaS offering should evaluate building on CCX (or a similar architecture modeled on it) against self-hosting a bespoke Ops-C/controller-pool stack. The trade-off is control and customization (self-hosted) versus time-to-market and operational overhead (CCX).

11. Database cluster reference topologies

The following patterns show recommended production architectures, including load balancer and VIP placement, for each database family managed by ClusterControl. For a minimal, step-by-step deployment (fixed IPs, exact commands), see the linked Day-1 Operations tutorial instead. This section focuses on the shape of the architecture and the reasoning behind each choice.

Family Pattern Minimum production nodes Recommended production nodes Load balancer
MySQL, MariaDB Single-primary replication 2 (1 primary + 1 replica) 3 (1 primary + 2 replicas) ProxySQL, HAProxy, or MaxScale + Keepalived
PostgreSQL, TimescaleDB Single-primary replication 2 (1 primary + 1 replica) 3 (1 primary + 2 replicas) HAProxy + Keepalived (PgBouncer optional)
MySQL Group Replication, Galera/PXC/MariaDB Cluster Multi-primary certification-based clustering 3 (odd count) 3 (odd count) HAProxy or ProxySQL + Keepalived
MongoDB Replica set 3 (1 primary + 2 secondaries, odd count) 3 (odd count) Driver-based (mongos for sharded only)
MongoDB Sharded cluster 11 total (3 config servers + 2 shards × 3 nodes + 2 mongos for HA) Same as minimum. Add shards as data grows 2+ mongos routers
Redis, Valkey Sentinel 3 (1 primary + 2 replicas, each with Sentinel) 3 (odd count) Sentinel-aware client
Redis, Valkey Cluster 6 (3 masters + 3 replicas) Same as minimum. Add shards (masters) as write throughput needs grow Cluster-aware client
SQL Server Always On availability group 2 (1 primary + 1 secondary replica) 3 (1 primary + 2 secondary replicas) Direct-connect to replica IPs (no ClusterControl-managed listener. See 11.5)
Elasticsearch High availability cluster 5 (3 master-eligible + 2 data nodes) 5, scaling data nodes (not master-eligible ones) as load grows Coordinating node / client access

Note

Kubernetes-hosted databases follow a different operational model: ClusterControl connects to your Kubernetes environment via the ClusterControl Kubernetes Proxy instead of managing nodes over SSH. See Integration → Kubernetes.

11.1 Single-primary replication (MySQL, MariaDB, PostgreSQL, TimescaleDB)

flowchart TB
    u{{<b>Applications</b>}} -->|RW/RO| vip((VIP))
    vip -->|active<br>Keepalived| lb1[<b>Load Balancer</b><br>ProxySQL / HAProxy / MaxScale]
    vip -.->|standby| lb2[<b>Load Balancer</b><br>standby]
    lb1 & lb2 -->|RW| p[(<b>Primary</b>)]
    lb1 & lb2 -.->|RO| r1[(<b>Replica</b>)] & r2[(<b>Replica</b>)]
    p -->|replicates| r1 & r2
    cc[/<b>ClusterControl</b>/] -.->|manages & monitors| p & r1 & r2 & lb1 & lb2
    subgraph "Single-Primary Replication"
        p
        r1
        r2
    end
  • Start with one replica for read scaling and failover. Add more as read load grows. This pattern scales reads linearly by adding replicas behind the load balancer.
  • Route writes and reads through a load balancer rather than the application directly, so failover is transparent. See Create Load Balancer.
  • Deploy at least two load balancer nodes with Keepalived VIP to avoid the load balancer becoming a single point of failure. The Percona XtraDB Cluster, MySQL Group Replication, and PostgreSQL Streaming Replication Day-1 tutorials all call this out explicitly as the production recommendation, and the MariaDB Cluster tutorial deploys it by default. Not every tutorial in this family sets up two load balancers in its minimal example (the logical-replication and TimescaleDB walkthroughs don't), so treat this as the production target regardless of which example you started from.

Why 2 replicas, not 1, is the production baseline. The table above lists the bare technical minimum (1 primary + 1 replica = 2 nodes), but size for 3 nodes (1 primary + 2 replicas) on anything business-critical. When the primary fails, ClusterControl's automatic recovery promotes one replica to primary and reconfigures every other replica to follow it. With only 1 replica, that single failover event leaves you with a lone primary and zero replicas until someone manually provisions a new one, no more read scaling and no more failover target. The old primary itself doesn't simply rejoin as a replica either way: for MySQL/MariaDB it comes back up but stays excluded from replication until manually restaged, while for PostgreSQL/TimescaleDB ClusterControl forcefully shuts it down to prevent accidental writes. See the same two Failover and Recovery sections linked above for each mechanism. With 2 replicas, the same failover event still leaves you with a primary and 1 replica: reads keep working and you still have somewhere to fail over to next time.

  • PostgreSQL/TimescaleDB specifics: only HAProxy is supported as a ClusterControl-managed load balancer here. ProxySQL and MariaDB MaxScale support MySQL, MariaDB, and Galera Cluster only (see Create Load Balancer → Support Matrix). Add PgBouncer (optional) in front of the primary when connection counts are high. PostgreSQL forks a backend process per connection, so pooling reduces resource consumption more than it would for MySQL/MariaDB's threaded connection model. ClusterControl supports session, transaction, and statement pool modes (see Create Load Balancer → PgBouncer). Because ClusterControl surfaces the new primary after a failover but does not automatically redirect existing application connections to it, put HAProxy (or PgBouncer pointed at HAProxy) in front of the cluster rather than connecting the application directly to a node's IP. Otherwise, you have to manually find and re-point to the new primary yourself.
  • MySQL/MariaDB specifics: ProxySQL and MaxScale add SQL-aware, replication-topology-aware routing (they detect the new writable primary after a failover automatically), while HAProxy does simpler TCP-level health-check-based routing, either works, but ProxySQL/MaxScale need less manual reconfiguration of health-check scripts if you change topology later.
  • Consider a delayed replica for point-in-time protection against logical mistakes (e.g., accidental DELETE/DROP).
  • Relevant tutorials: MySQL Replication, PostgreSQL Streaming Replication, PostgreSQL Logical Replication, TimescaleDB Streaming Replication.

11.2 Multi-primary certification-based clustering (Galera, Percona XtraDB Cluster, MariaDB Cluster, MySQL Group Replication)

flowchart TB
    u{{<b>Applications</b>}} --> vip((VIP))
    vip -->|active<br>Keepalived| lb1[<b>Load Balancer</b><br>HAProxy / ProxySQL]
    vip -.->|standby| lb2[<b>Load Balancer</b><br>standby]
    lb1 & lb2 --> n1[(<b>Node 1</b>)] & n2[(<b>Node 2</b>)] & n3[(<b>Node 3</b>)]
    g[[Galera Arbitrator<br>#40;garbd, optional tie-breaker#41;]] -.-> n1 & n2 & n3
    cc[/<b>ClusterControl</b>/] -.->|manages & monitors| n1 & n2 & n3 & lb1 & lb2 & g
    subgraph "Quorum-Based Cluster (odd node count)"
        n1
        n2
        n3
    end

This diagram shows the shared node/quorum shape; which nodes actually accept writes differs by engine, see Write routing below. Galera/PXC/MariaDB Cluster route writes to all three nodes by default. MySQL Group Replication commonly runs single-primary instead, with only one node accepting writes at a time even though all are technically eligible.

  • Always use an odd number of nodes (3, 5, ...) to avoid split-brain when computing quorum.
  • When you can only afford two full nodes, deploy garbd as a lightweight, vote-only third participant instead of a full database node, on its own host, not the ClusterControl node itself, which is an unsupported placement for garbd (see Create Load Balancer → Garbd).
  • MySQL Group Replication follows the same quorum-based node shape as Galera (odd node count, same arbitration guidance), but differs in write routing, see below.
  • ProxySQL and MaxScale add SQL-aware query routing on top of the same node layout, while HAProxy is a simpler Layer-4 router.

Write routing: multi-writer vs. single-writer. Galera/PXC/MariaDB Cluster are certification-based multi-primary systems, every node can accept writes, and ClusterControl's own MariaDB Galera Cluster tutorial deploys HAProxy with read/write splitting turned off, load-balancing writes across all three nodes with no host distinction. This is a reasonable default for workloads with little row-level write contention. But conflicts between concurrent writes on different nodes are only caught at commit time (certification), so hot rows or a small, frequently-updated working set see more rollback-and-retry overhead as write concurrency across nodes increases. This same cost is why the Percona XtraDB Cluster tutorial recommends restoring a large dataset on a single node first, explicitly because every insert would otherwise be certified by Galera write-set replication, and why the MariaDB Cluster tutorial gives the same restore-on-one-node advice, attributed there more generally to the cost of synchronous replication rather than certification by name. If your write pattern has enough contention to matter, pin writes to a single node at a time instead: with HAProxy, set one backend server's Role to active and the rest to backup (see Create Load Balancer → HAProxy) so all traffic goes to one node until it fails over to a backup. This is a deliberate configuration choice on top of ClusterControl's defaults (which load-balance across all nodes as shown above), not something it sets up automatically for Galera.

MySQL Group Replication's own tutorial takes the opposite default: it deploys HAProxy with read/write splitting turned on, relying on the mysqlchk_rw_split health-check script to track whichever single node is currently the read-write primary, consistent with Group Replication's common single-primary operating mode, where only one member accepts writes at a time even though all members are technically eligible.

11.3 Document store (MongoDB)

flowchart LR
    u{{Applications}} --> p[(Primary)]
    p -->|replicates| s1[(Secondary)] & s2[(Secondary)]
    cc[/ClusterControl/] -.->|manages & monitors| p & s1 & s2
    subgraph "Replica Set (odd member count)"
        p
        s1
        s2
    end

The MongoDB driver is replica-set aware, so no external load balancer is required. Keep the member count odd, so the set can always compute a majority for primary election (an even count risks a tied vote with no winner). Add a hidden member, a full data-bearing member excluded from the driver's default read routing, for reporting/analytics/backup workloads that would otherwise compete with production traffic for resources. Reach for a vote-only arbiter only when you can't afford a third full data node, since an arbiter holds no data and can't serve reads, whereas a hidden member does both.

Relevant tutorials: MongoDB Replica Set, MongoDB Enterprise Replica Set.

flowchart TB
    u{{Applications}} --> m1[Mongos Router 1] & m2[Mongos Router 2]
    m1 & m2 --> cfg1[(Config Server 1)] & cfg2[(Config Server 2)] & cfg3[(Config Server 3)]
    m1 & m2 --> sh1p[(Shard 1<br>Primary)] & sh2p[(Shard 2<br>Primary)]
    sh1p -->|replicates| sh1s1[(Shard 1<br>Secondary)]
    sh1p -->|replicates| sh1s2[(Shard 1<br>Secondary)]
    sh2p -->|replicates| sh2s1[(Shard 2<br>Secondary)]
    sh2p -->|replicates| sh2s2[(Shard 2<br>Secondary)]
    cc[/ClusterControl/] -.->|manages & monitors| m1 & m2 & cfg1 & cfg2 & cfg3 & sh1p & sh1s1 & sh1s2 & sh2p & sh2s1 & sh2s2
    subgraph "Config Server Replica Set"
        cfg1
        cfg2
        cfg3
    end
    subgraph "Shard 1"
        sh1p
        sh1s1
        sh1s2
    end
    subgraph "Shard 2"
        sh2p
        sh2s1
        sh2s2
    end

Run the config server replica set at 3 members, not 2: an even-numbered replica set can tie during election and fail to produce a primary, and for config servers specifically that means the whole cluster's routing metadata becomes unavailable for writes until it resolves. The same reasoning applies to each shard's own replica set: run 3 nodes per shard, not 2, so losing a single member still leaves a majority available to elect a primary. Note that the Day-1 tutorial's own minimal example uses only 2 config servers and 1 mongos (its prerequisites even allow co-locating that one mongos on the ClusterControl node, purely to keep the walkthrough small) rather than the production target below. Treat 3 config servers, 3 nodes per shard, and 2+ mongos routers as the production target, not the tutorial's example. Deploy at least two mongos routers so applications are not left without a routing path if one fails. As data grows, add shards horizontally. For geographically or tenant-partitioned access patterns, consider zone sharding.

Relevant tutorial: MongoDB Sharded Cluster.

11.4 In-memory key-value store (Redis, Valkey)

flowchart TD
    u{{Applications<br>#40;Sentinel-aware client#41;}} -->|RW| p[Primary + Sentinel]
    u -.->|RO, optional| r1[Replica + Sentinel] & r2[Replica + Sentinel]
    p -->|replicates| r1 & r2
    p -.->|quorum & failover vote| r1 & r2
    r1 -.->|quorum & failover vote| r2 & p
    r2 -.->|quorum & failover vote| r1 & p
    cc[/ClusterControl/] -.->|manages & monitors| p & r1 & r2

Use an odd number of Sentinel-monitored nodes, so a quorum can always be reached for automatic failover. Run one Sentinel process per Redis node, co-located on that same host. The Day-1 tutorial's topology does this by default (3 nodes, 3 Sentinels) rather than running a separate, centralized pool of Sentinels, so a network partition that isolates one Redis host also isolates its Sentinel's view along with it, keeping quorum voting meaningful. Choose Sentinel when the dataset fits on a single primary.

Relevant tutorials: Redis Sentinel, Valkey Sentinel.

flowchart TB
    u{{Applications<br>#40;cluster-aware client#41;}} --> m1[Master A] & m2[Master B] & m3[Master C]
    m1 -->|replicates| r1[Replica A]
    m2 -->|replicates| r2[Replica B]
    m3 -->|replicates| r3[Replica C]
    cc[/ClusterControl/] -.->|manages & monitors| m1 & m2 & m3 & r1 & r2 & r3

Choose Cluster over Sentinel once the working set outgrows a single primary's memory. Each master should have at least one replica, a masterless shard has no failover target. To scale write throughput, add more shards (masters), not just more replicas to existing shards: ClusterControl's built-in scaling action for this topology only adds a replica to an existing shard, so introducing an additional shard for write scaling is a separate, manual step.

Relevant tutorials: Redis Cluster, Valkey Cluster.

11.5 SQL Server Always On availability group

flowchart LR
    u{{Applications}} -->|writes| p[(Primary Replica)]
    u -.->|reads, direct to replica IP| s1[(Secondary Replica)] & s2[(Secondary Replica)]
    p -->|replicates| s1 & s2
    cc[/ClusterControl/] -.->|manages & monitors<br>manual promote on failure| p & s1 & s2

This topology differs from the others in this section in one important way: ClusterControl's SQL Server support doesn't deploy an AG Listener or automatic quorum-based failover. The Day-1 tutorial has applications connect for reads directly to a replica's IP address rather than through a listener, and recovering from a primary failure is a manual Promote Replica action in the ClusterControl GUI/CLI, not an automatic failover. If your application needs transparent, listener-based reconnection or SQL Server's own automatic quorum-based failover, set up the AG Listener and the underlying cluster quorum (WSFC on Windows, Pacemaker on Linux) yourself using SQL Server's native tooling, and use ClusterControl for monitoring/management on top of that. This isn't something the deployment wizard configures for you.

  • Recommended: 3 nodes (1 primary + 2 secondaries), not the 2-node technical minimum. The same failover-headroom logic as Section 11.1 applies here too: promoting one secondary should still leave a remaining secondary in place, rather than a lone primary with no replica until one is rebuilt. This also matches the Day-1 tutorial's own example, which deploys 1 primary + 2 secondaries rather than the bare 1+1 minimum.
  • Since failover here is a manual action rather than an automatic one, alert on primary/replica health promptly (see Alerts & Notifications) so someone can trigger the promotion quickly rather than relying on it happening on its own.

Relevant tutorials: Standalone (not recommended beyond throwaway/dev use, it's a single node with no replica at all), Always-On Availability Group.

11.6 Search cluster (Elasticsearch)

flowchart TB
    u{{Applications}} --> d1[(Hot Data Node)] & d2[(Hot Data Node)]
    d1 & d2 -.->|age out| dw[(Warm/Cold Data Node<br>optional tiering)]
    m1[Master-eligible] & m2[Master-eligible] & m3[Master-eligible] -.->|cluster state<br>quorum| d1 & d2 & dw
    cc[/ClusterControl/] -.->|manages & monitors| d1 & d2 & dw & m1 & m2 & m3

Separate the three master-eligible nodes from the data nodes so a data-node failure never risks a split-brain election. Keep the master-eligible count odd (3 is the standard baseline) so the cluster can always elect from a majority even if one is unreachable. Scale by adding data nodes as ingest/query load grows, not master-eligible ones. The Single-node Cluster tutorial itself states plainly that it "isn't recommended for production workloads... use it in production only for low-stakes workloads where downtime and potential data loss are acceptable," and the High Availability Cluster tutorial cautions against over-scaling in the other direction too: a larger node count adds its own coordination/processing overhead, so add nodes to match measured load rather than provisioning far ahead of it. Node-level HA is necessary but not sufficient on its own. Also, set each index's number_of_replicas to at least 1, so losing a data node doesn't also mean losing a shard's only copy. For larger, time-series-like datasets, consider hot-warm(-cold) tiering. Relevant tutorials: Single-node Cluster, High Availability Cluster.

See Also