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

# Follow-the-Workload Topology

export const InternalLink = ({version, path = "", children, ...props}) => {
  let detectedVersion = version || "stable";
  if (typeof window !== 'undefined' && !version) {
    const match = window.location.pathname.match(/\/docs\/([^/]+)/);
    if (match) {
      detectedVersion = match[1];
    }
  }
  const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
  return <a href={`/docs/${detectedVersion}/${normalizedPath}`} {...props}>
      {children}
    </a>;
};

In a multi-region deployment, follow-the-workload is the default behavior for tables that do not have a <InternalLink path="multiregion-overview">table locality</InternalLink>. In general, this is a good choice only for tables with the following requirements:

* The table is active mostly in one region at a time, e.g., following the sun.
* In the active region, read latency must be low, but write latency can be higher.
* In non-active regions, both read and write latency can be higher.
* Table data must remain available during a region failure.

<Tip>
  If read performance is your main focus for a table, but you want low-latency reads everywhere instead of just in the most active region, consider <InternalLink path="global-tables">global tables</InternalLink> or <InternalLink path="topology-follower-reads">follower reads</InternalLink>.

  Note that if you start using the <InternalLink path="multiregion-overview">multi-region SQL abstractions</InternalLink> for a database, CockroachDB will no longer provide the follow-the-workload behavior described on this page for that database.
</Tip>

## Before you begin

### Fundamentals

* Multi-region topology patterns are almost always table-specific. If you haven't already, <InternalLink path="topology-patterns#multi-region">review the full range of patterns</InternalLink> to ensure you choose the right one for each of your tables.
* Review how data is replicated and distributed across a cluster, and how this affects performance. It is especially important to understand the concept of the "leaseholder". For a summary, see <InternalLink path="architecture/reads-and-writes-overview">Reads and Writes in CockroachDB</InternalLink>. For a deeper dive, see the CockroachDB <InternalLink path="architecture/overview">Architecture Overview</InternalLink>.
* Review the concept of <InternalLink path="cockroach-start#locality">locality</InternalLink>, which CockroachDB uses to place and balance data based on how you define <InternalLink path="configure-replication-zones">replication controls</InternalLink>.
* Review the recommendations and requirements in our <InternalLink path="recommended-production-settings">Production Checklist</InternalLink>.
* This topology doesn't account for hardware specifications, so be sure to follow our <InternalLink path="recommended-production-settings#hardware">hardware recommendations</InternalLink> and perform a POC to size hardware for your use case. For optimal cluster performance, Cockroach Labs recommends that all nodes use the same hardware and operating system.
* Adopt relevant <InternalLink path="performance-best-practices-overview">SQL Best Practices</InternalLink> to ensure optimal performance.

### Cluster setup

Each <InternalLink path="topology-patterns#multi-region">multi-region pattern</InternalLink> assumes the following setup:

<img src="https://mintcdn.com/cockroachlabs/H2p_QgztDgzpDDkl/images/v26.2/topology-patterns/topology_multi-region_hardware.png?fit=max&auto=format&n=H2p_QgztDgzpDDkl&q=85&s=a023f5b4298054d830bf41abf04ba64a" alt="Multi-region hardware setup" width="960" height="540" data-path="images/v26.2/topology-patterns/topology_multi-region_hardware.png" />

#### Hardware

* 3 regions
* Per region, 3+ AZs with 3+ VMs evenly distributed across them
* Region-specific app instances and load balancers
  * Each load balancer redirects to CockroachDB nodes in its region.
  * When CockroachDB nodes are unavailable in a region, the load balancer redirects to nodes in other regions.

#### Cluster startup

Start each node with the <InternalLink path="cockroach-start#locality">`--locality`</InternalLink> flag specifying its region and AZ combination. For example, the following command starts a node in the `west1` AZ of the `us-west` region:

```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
$ cockroach start \
--locality=region=us-west,zone=west1 \
--certs-dir=certs \
--advertise-addr=<node1 internal address \
--join=<node1 internal address:26257,<node2 internal address:26257,<node3 internal address:26257 \
--cache=.25 \
--max-sql-memory=.25 \
--background
```

## Configuration

Aside from [deploying a cluster across three regions](#cluster-setup) properly, with each node started with the <InternalLink path="cockroach-start#locality">`--locality`</InternalLink> flag specifying its region and zone combination, this behavior requires no extra configuration. CockroachDB will balance the replicas for a table across the three regions and will assign the range lease to the replica in the region with the greatest demand at any given time (the follow-the-workload feature). This means that read latency in the active region will be low while read latency in other regions will be higher due to having to leave the region to reach the leaseholder. Write latency will be higher as well due to always involving replicas in multiple regions.

<img src="https://mintcdn.com/cockroachlabs/H2p_QgztDgzpDDkl/images/v26.2/topology-patterns/topology_follower_reads1.png?fit=max&auto=format&n=H2p_QgztDgzpDDkl&q=85&s=036516efd4fc1af5e2dfa3c36cb406d4" alt="Follow-the-workload table replication" width="960" height="540" data-path="images/v26.2/topology-patterns/topology_follower_reads1.png" />

<Note>
  Follow-the-workload is also used by <InternalLink path="configure-replication-zones#create-a-replication-zone-for-a-system-range">system ranges containing important internal data</InternalLink>.
</Note>

## Characteristics

### Latency

#### Reads

Reads in the region with the most demand will access the local leaseholder and, therefore, never leave the region. This makes read latency very low in the currently most active region. Reads in other regions, however, will be routed to the leaseholder in a different region and, thus, read latency will be higher.

For example, in the animation below, the most active region is `us-east` and, thus, the table's leaseholder is in that region:

1. The read request in `us-east` reaches the regional load balancer.
2. The load balancer routes the request to a gateway node.
3. The gateway node routes the request to the leaseholder replica.
4. The leaseholder retrieves the results and returns to the gateway node.
5. The gateway node returns the results to the client. In this case, reads in the `us-east` remain in the region and are lower latency than reads in other regions.

<img src="https://mintcdn.com/cockroachlabs/H2p_QgztDgzpDDkl/images/v26.2/topology-patterns/topology_follow_the_workload_reads.png?fit=max&auto=format&n=H2p_QgztDgzpDDkl&q=85&s=3ca58d07ef7ed033c2032fa62fe03f09" alt="Follow-the-workload topology reads" width="960" height="540" data-path="images/v26.2/topology-patterns/topology_follow_the_workload_reads.png" />

#### Writes

The replicas for the table are spread across all 3 regions, so writes involve multiple network hops across regions to achieve consensus. This increases write latency significantly.

For example, in the animation below, assuming the most active region is still `us-east`:

1. The write request in `us-east` reaches the regional load balancer.
2. The load balancer routes the request to a gateway node.
3. The gateway node routes the request to the leaseholder replica.
4. While the leaseholder appends the write to its Raft log, it notifies its follower replicas.
5. As soon as one follower has appended the write to its Raft log (and thus a majority of replicas agree based on identical Raft logs), it notifies the leaseholder and the write is committed on the agreeing replicas.
6. The leaseholders then return acknowledgement of the commit to the gateway node.
7. The gateway node returns the acknowledgement to the client.

<img src="https://mintcdn.com/cockroachlabs/H2p_QgztDgzpDDkl/images/v26.2/topology-patterns/topology_follow_the_workload_writes.gif?s=32e1f6f8b6c9b1c98410e95587033b4e" alt="Follow-the-workload topology writes" width="960" height="540" data-path="images/v26.2/topology-patterns/topology_follow_the_workload_writes.gif" />

### Resiliency

Because this pattern balances the replicas for the table across regions, one entire region can fail without interrupting access to the table:

<img src="https://mintcdn.com/cockroachlabs/H2p_QgztDgzpDDkl/images/v26.2/topology-patterns/topology_follower_reads_resiliency.png?fit=max&auto=format&n=H2p_QgztDgzpDDkl&q=85&s=c480553211876872e584faad9a7d8cfb" alt="Follow-the-workload topology region failure" width="960" height="540" data-path="images/v26.2/topology-patterns/topology_follower_reads_resiliency.png" />

## See also

* <InternalLink path="multiregion-overview">Multi-Region Capabilities Overview</InternalLink>
* <InternalLink path="choosing-a-multi-region-configuration">How to Choose a Multi-Region Configuration</InternalLink>
* <InternalLink path="multiregion-survival-goals#when-to-use-zone-vs-region-survival-goals">When to Use `ZONE` vs. `REGION` Survival Goals</InternalLink>
* <InternalLink path="table-localities#when-to-use-regional-vs-global-tables">When to Use `REGIONAL` vs. `GLOBAL` Tables</InternalLink>
* <InternalLink path="multiregion-overview#secondary-regions">Secondary regions</InternalLink>
* <InternalLink path="alter-database#set-secondary-region">`ALTER DATABASE ... SET SECONDARY REGION`</InternalLink>
* <InternalLink path="alter-database#drop-secondary-region">`ALTER DATABASE ... DROP SECONDARY REGION`</InternalLink>
* <InternalLink path="topology-patterns">Topology Patterns Overview</InternalLink>
  * Single-region patterns
    * <InternalLink path="topology-basic-production">Basic Production</InternalLink>
  * Multi-region patterns
    * <InternalLink path="regional-tables">`REGIONAL` Tables</InternalLink>
    * <InternalLink path="global-tables">`GLOBAL` Tables</InternalLink>
    * <InternalLink path="topology-follower-reads">Follower Reads</InternalLink>
    * <InternalLink path="topology-follow-the-workload">Follow-the-Workload</InternalLink>
