> ## 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.

# Global Tables

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 <InternalLink path="multiregion-overview">multi-region deployment</InternalLink>, <InternalLink path="table-localities#global-tables">`GLOBAL` table locality</InternalLink> is a good choice for tables with the following requirements:

* Read latency must be low, but write latency can be much higher.
* Reads must be up-to-date for business reasons or because the table is referenced by <InternalLink path="foreign-key">foreign keys</InternalLink>.
* Rows in the table, and all latency-sensitive reads, **cannot** be tied to specific regions.

In general, this pattern is suited well for reference tables that are rarely updated.

Tables with the `GLOBAL` locality can survive zone or region failures, depending on the database-level <InternalLink path="multiregion-overview#survival-goals">survival goal</InternalLink> setting.

For new clusters using the <InternalLink path="multiregion-overview">multi-region SQL abstractions</InternalLink>, Cockroach Labs recommends lowering the <InternalLink path="cockroach-start">`--max-offset`</InternalLink> setting to `250ms`. This setting is especially helpful for lowering the write latency of <InternalLink path="table-localities#global-tables">global tables</InternalLink>. Nodes can run with different values for `--max-offset`, but only for the purpose of updating the setting across the cluster using a rolling upgrade.

## Before you begin

### Fundamentals

Multi-region patterns require thinking about the following questions:

* What are your <InternalLink path="multiregion-overview#survival-goals">survival goals</InternalLink>? Do you need to survive a <InternalLink path="multiregion-survival-goals#survive-zone-failures">zone failure</InternalLink>? Do you need to survive a <InternalLink path="multiregion-survival-goals#survive-region-failures">region failure</InternalLink>?
* What are the <InternalLink path="multiregion-overview">table localities</InternalLink> that will provide the performance characteristics you need for each table's data?
  * Do you need low-latency reads and writes from a single region? Do you need that single region to be configurable at the <InternalLink path="table-localities#regional-by-row-tables">row level</InternalLink>? Or will <InternalLink path="table-localities#regional-tables">a single optimized region for the entire table</InternalLink> suffice?
  * Do you have a "read-mostly" <InternalLink path="table-localities#global-tables">table of reference data that is rarely updated</InternalLink>, but that must be read with low latency from all regions?

For more information about CockroachDB multi-region capabilities, review the following pages:

* <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>

In addition, reviewing the following information will be helpful:

* The concept of <InternalLink path="cockroach-start#locality">locality</InternalLink>, which CockroachDB uses to place and balance data based on how you define survival goal and table locality settings.
* The recommendations in our <InternalLink path="recommended-production-settings">Production Checklist</InternalLink>, including our <InternalLink path="recommended-production-settings#hardware">hardware recommendations</InternalLink>. Afterwards, perform a proof of concept to size hardware for your use case.
* <InternalLink path="performance-best-practices-overview">SQL Performance Best Practices</InternalLink>

### Cluster setup

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

<img src="https://mintcdn.com/cockroachlabs/-7uTB1VKbyjy3gp4/images/v24.3/topology-patterns/topology_multi-region_hardware.png?fit=max&auto=format&n=-7uTB1VKbyjy3gp4&q=85&s=43dadc18561df4171c06dbe6da755f7c" alt="Multi-region hardware setup" width="960" height="540" data-path="images/v24.3/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

### Summary

To use this pattern, set the <InternalLink path="multiregion-overview">table locality</InternalLink> to `GLOBAL`.

A *global* table is optimized for low-latency reads from every region in the database. This means that any region can effectively act as the home region of the table. The tradeoff is that writes will incur higher latencies from any given region, since writes have to be replicated across every region to make the global low-latency reads possible. Use global tables when your application has a "read-mostly" table of reference data that is rarely updated, and needs to be available to all regions.

For an example of a table that can benefit from the *global* table locality setting in a multi-region deployment, see the `promo_codes` table from the <InternalLink path="movr">MovR application</InternalLink>.

For instructions showing how to set a table's locality to `GLOBAL`, see <InternalLink path="alter-table">`ALTER TABLE... SET LOCALITY`</InternalLink>.

For more information about global tables, including troubleshooting information, see <InternalLink path="global-tables">Global Tables</InternalLink>.

### Steps

1. Create a database and set it as the default database:

   ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   CREATE DATABASE test;
   ```

   ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   USE test;
   ```

   [This cluster is already deployed across three regions](#cluster-setup). Therefore, to make this database a "multi-region database", issue the following SQL statement to <InternalLink path="alter-database#set-the-primary-region">set the primary region</InternalLink>:

   ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   ALTER DATABASE test PRIMARY REGION "us-east";
   ```

<Note>
  Every multi-region database must have a primary region. For more information, see <InternalLink path="multiregion-overview#database-regions">Database regions</InternalLink>.
</Note>

2. Issue the following <InternalLink path="alter-database#add-region">`ADD REGION`</InternalLink> statements to add the remaining regions to the database:

   ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   ALTER DATABASE test ADD REGION "us-west";
   ```

   ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   ALTER DATABASE test ADD REGION "us-central";
   ```
3. Create a <InternalLink path="table-localities#global-tables">`GLOBAL` table</InternalLink> by issuing the following statement:

   ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   CREATE TABLE postal_codes (
     id INT PRIMARY KEY,
     code STRING
   ) LOCALITY GLOBAL;
   ```

   Alternatively, you can set an existing table's locality to `GLOBAL` using <InternalLink path="alter-table#set-locality">`ALTER TABLE... SET LOCALITY`</InternalLink>:

   ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   > ALTER TABLE postal_codes SET LOCALITY GLOBAL;
   ```

<Tip>
  A good way to check that your <InternalLink path="multiregion-overview">table locality settings</InternalLink> are having the expected effect is by monitoring how the performance metrics of a workload change as the settings are applied to a running cluster.
</Tip>

For a tutorial showing how table localities can improve performance metrics across a multi-region cluster, see <InternalLink path="demo-low-latency-multi-region-deployment">Low Latency Reads and Writes in a Multi-Region Cluster</InternalLink>.

## Characteristics

### Latency

Global tables support low-latency, global reads of read-mostly data using an extension to CockroachDB's standard transaction protocol called <InternalLink path="architecture/transaction-layer#non-blocking-transactions">non-blocking transactions</InternalLink>.

#### Reads

Thanks to the <InternalLink path="architecture/transaction-layer#non-blocking-transactions">non-blocking transaction</InternalLink> protocol extension, reads against `GLOBAL` tables access a consistent local replica and therefore never leave the region. This keeps read latency low.

#### Writes

Writes incur higher latencies than reads, since they require a "commit-wait" step to ensure consistency. For more information about how this works, see <InternalLink path="architecture/transaction-layer#non-blocking-transactions">non-blocking transactions</InternalLink>.

### Resiliency

Because the `test` database does not specify a <InternalLink path="multiregion-overview#survival-goals">survival goal</InternalLink>, it uses the default <InternalLink path="multiregion-survival-goals#survive-zone-failures">`ZONE` survival goal</InternalLink>. With the default settings, an entire zone can fail without interrupting access to the database.

For more information about how to choose a database survival goal, see <InternalLink path="multiregion-survival-goals#when-to-use-zone-vs-region-survival-goals">When to Use `ZONE` vs. `REGION` Survival Goals</InternalLink>.

## Troubleshooting

### High follower read latency on global tables

Reads on multi-region global tables can experience sporadic high latency on <InternalLink path="follower-reads">follower reads</InternalLink> if the round trip time between cluster nodes is higher than 150ms. To work around this issue, consider setting the `kv.closed_timestamp.lead_for_global_reads_override` <InternalLink path="cluster-settings">cluster setting</InternalLink> to a value greater than 800ms.

The value of `kv.closed_timestamp.lead_for_global_reads_override` will impact write latency to global tables, so you should proceed in 100ms increments until the high read latency no longer occurs. If you've increased the setting to 1500ms and the problem persists, you should <InternalLink path="support-resources">contact support</InternalLink>.

## Alternatives

* If rows in the table, and all latency-sensitive queries, can be tied to specific geographies, consider the <InternalLink path="regional-tables">`REGIONAL` Table Locality Pattern</InternalLink> pattern.

## Tutorial

For a step-by-step demonstration showing how CockroachDB's multi-region capabilities (including `GLOBAL` and `REGIONAL` tables) give you low-latency reads in a distributed cluster, see the tutorial on <InternalLink path="demo-low-latency-multi-region-deployment">Low Latency Reads and Writes in a Multi-Region Cluster</InternalLink>.

## 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="demo-low-latency-multi-region-deployment">Low Latency Reads and Writes in a Multi-Region Cluster</InternalLink>
* <InternalLink path="migrate-to-multiregion-sql">Migrate to Multi-Region SQL</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-development">Development</InternalLink>
    * <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>
