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

# Table Localities

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>;
};

*Table locality* determines how CockroachDB optimizes access to the table's data. Every table in a multi-region database has a "table locality setting" that configures one or more *home regions* at the table or row level. A table or row's home region is where the <InternalLink path="architecture/replication-layer#leases">leaseholder</InternalLink> of its ranges is placed, along with a number of voting replicas determined by the <InternalLink path="multiregion-survival-goals#when-to-use-zone-vs-region-survival-goals">survival goal</InternalLink> of the database.

By default, all tables in a multi-region database are *regional* tables—that is, CockroachDB optimizes access to the table's data from a single home region (by default, the database's primary region).

For information about the table localities CockroachDB supports, see the sections:

* [Regional tables](#regional-tables) provide low-latency reads and writes for an entire table from **a single region**.
* [Regional by row tables](#regional-by-row-tables) provide low-latency reads and writes for one or more rows of a table from **a single region**. Different rows in the table can be optimized for access from **different regions**.
* [Global tables](#global-tables) are optimized for low-latency reads from **all regions**.

<Note>
  Table locality settings are used for optimizing latency under different read and write patterns. If you are optimizing for read and write access to all of your tables from a single region (the primary region), there is nothing else you need to do once you set your <InternalLink path="multiregion-overview#database-regions">database's primary region</InternalLink>.
</Note>

## Regional tables

In a *regional* table, access to the table will be fast in the table's home region and slower in other regions. In other words, CockroachDB optimizes access to data in a regional table from a single region. By default, a regional table's home region is the <InternalLink path="multiregion-overview#database-regions">database's primary region</InternalLink>, but that can be changed to use any region in the database. Regional tables work well when your application requires low-latency reads and writes for an entire table from a single region.

For instructions showing how to set a table's locality to `REGIONAL BY TABLE` and configure its home region, see <InternalLink path="alter-table">`ALTER TABLE ... SET LOCALITY`</InternalLink>.

By default, all tables in a multi-region database are *regional* tables that use the database's primary region. Unless you know your application needs different performance characteristics than regional tables provide, there is no need to change this setting.

## Regional by row tables

In a *regional by row* table, each row is optimized for access from a specific home region. Each row's home region is specified in a hidden <InternalLink path="alter-table">`crdb_region` column</InternalLink>, which defaults to the region of the <InternalLink path="architecture/life-of-a-distributed-transaction#gateway">gateway node</InternalLink> that inserted the row. The `REGIONAL BY ROW` setting automatically <InternalLink path="partitioning">partitions</InternalLink> the table and all of <InternalLink path="table-localities#indexes-on-regional-by-row-tables">its indexes</InternalLink> by region using `crdb_region` as the partition key prefix.

Use regional by row tables when individual rows are frequently accessed from a single region, and your application requires low-latency reads and writes at the row level. A typical `REGIONAL BY ROW` use case is the `users` table in the <InternalLink path="movr">MovR application</InternalLink>, where user data can be co-located with the user's region for better performance.

To take advantage of regional by row tables:

* Use unique key lookups or queries with <InternalLink path="limit-offset">`LIMIT`</InternalLink> clauses to enable <InternalLink path="cost-based-optimizer#locality-optimized-search-in-multi-region-clusters">locality optimized searches</InternalLink> that prioritize rows in the gateway node's region. If there is a possibility that the results of the query all live in local rows, CockroachDB will first search for rows in the gateway node's region. The search only continues in remote regions if rows in the local region did not satisfy the query.

* Use <InternalLink path="foreign-key#rules-for-creating-foreign-keys">foreign keys</InternalLink> that reference the <InternalLink path="alter-table">`crdb_region` column</InternalLink> in <InternalLink path="table-localities#regional-by-row-tables">`REGIONAL BY ROW`</InternalLink> tables, unless <InternalLink path="alter-table#turn-on-auto-rehoming-for-regional-by-row-tables">auto-rehoming is enabled</InternalLink> for those tables.

* <InternalLink path="alter-table#turn-on-auto-rehoming-for-regional-by-row-tables">Turn on auto-rehoming for regional by row tables</InternalLink>. A row's home region will be automatically set to the gateway region of any <InternalLink path="update">`UPDATE`</InternalLink> or <InternalLink path="upsert">`UPSERT`</InternalLink> statements that write to those rows.

For instructions showing how to set a table's locality to `REGIONAL BY ROW` and configure the home regions of its rows, refer to <InternalLink path="alter-table">`ALTER TABLE ... SET LOCALITY`</InternalLink>.

For more information on regional by row tables, see the [Cockroach Labs blog post](https://www.cockroachlabs.com/blog/regional-by-row/).

<InternalLink path="multiregion-overview#secondary-regions">Secondary regions</InternalLink> are not compatible with databases containing <InternalLink path="table-localities#regional-by-row-tables">`REGIONAL BY ROW`</InternalLink> tables. CockroachDB does not prevent you from defining secondary regions on databases with regional by row tables, but the interaction of these features is not supported.

Therefore, Cockroach Labs recommends that you avoid defining secondary regions on databases that use regional by row table configurations.

To change the column or expression used to determine row locality for a regional by row table defined with `REGIONAL BY ROW AS {column}`, refer to <InternalLink path="alter-table">Modify the region column or its expression</InternalLink>.

### Indexes on `REGIONAL BY ROW` tables

In <InternalLink path="multiregion-overview">multi-region deployments</InternalLink>, most users should use <InternalLink path="table-localities#regional-by-row-tables">`REGIONAL BY ROW` tables</InternalLink> instead of explicit index <InternalLink path="partitioning">partitioning</InternalLink>. When you add an index to a `REGIONAL BY ROW` table, it is automatically partitioned on the <InternalLink path="alter-table">`crdb_region` column</InternalLink>. Explicit index partitioning is not required.

While CockroachDB process an <InternalLink path="alter-database#add-region">`ADD REGION`</InternalLink> or <InternalLink path="alter-database#drop-region">`DROP REGION`</InternalLink> statement on a particular database, creating or modifying an index will throw an error. Similarly, all <InternalLink path="alter-database#add-region">`ADD REGION`</InternalLink> and <InternalLink path="alter-database#drop-region">`DROP REGION`</InternalLink> statements will be blocked while an index is being modified on a `REGIONAL BY ROW` table within the same database.

This behavior also applies to <InternalLink path="inverted-indexes">GIN indexes</InternalLink>.

For an example that uses unique indexes but applies to all indexes on `REGIONAL BY ROW` tables, see <InternalLink path="alter-table#add-a-unique-index-to-a-regional-by-row-table">Add a unique index to a `REGIONAL BY ROW` table</InternalLink>.

Regional by row tables can take advantage of <InternalLink path="hash-sharded-indexes">hash-sharded indexes</InternalLink> provided the `crdb_region` column is not part of the columns in the hash-sharded index.

## Global tables

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

## When to use regional vs. global tables

Use a <InternalLink path="table-localities#regional-by-row-tables">`REGIONAL` table locality</InternalLink> if:

* Your application requires low-latency reads and writes from a single region (either at the <InternalLink path="table-localities#regional-by-row-tables">row level</InternalLink> or the <InternalLink path="table-localities#regional-tables">table level</InternalLink>).
* Access to the table's data can be slower (higher latency) from other regions.

Use a <InternalLink path="table-localities#global-tables">`GLOBAL` table locality</InternalLink> if:

* Your application has a "read-mostly" table of reference data that is rarely updated, and that needs to be available to all regions.
* You can accept that writes to the table will incur higher latencies from any given region, since writes use a novel <InternalLink path="architecture/transaction-layer#non-blocking-transactions">non-blocking transaction protocol</InternalLink> that uses a timestamp "in the future". Note that the observed write latency is dependent on the <InternalLink path="cockroach-start">`--max-offset`</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.

## 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="demo-low-latency-multi-region-deployment">Low Latency Reads and Writes in a Multi-Region Cluster</InternalLink>
* <InternalLink path="topology-patterns">Topology Patterns</InternalLink>
* <InternalLink path="disaster-recovery-planning">Disaster Recovery</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">`SET SECONDARY REGION`</InternalLink>
* <InternalLink path="alter-database#drop-secondary-region">`DROP SECONDARY REGION`</InternalLink>

For an in-depth data placement support comparison and a demonstration of how the [Federal Wire Act (1961)](https://en.wikipedia.org/wiki/Federal_Wire_Act) can only be satisfied with CockroachDB, watch the following video:

<iframe width="560" height="315" src="https://www.youtube.com/embed/3p9VcZOf1Y4" title="YouTube video player" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />
