Skip to main content
CockroachDB multi-region capabilities make it easier to run global applications. For an overview of these capabilities, see . In multi-region clusters, the distribution of data becomes a performance consideration. This makes it important to think about the of each database. Then, for each table in the database, use the right to locate data for optimal performance. In this tutorial, you will:
  1. Simulate a multi-region CockroachDB cluster on your local machine.
  2. Run a workload on the cluster using our fictional vehicle-sharing application called .
  3. See the effects of network latency on SQL query performance in the default (non-multi-region) configuration.
  4. Configure the cluster for good multi-region performance by issuing SQL statements that choose the right and .

Considerations

This page describes a demo cluster; it does not show best practices for a production deployment. For more information about production deployments of multi-region applications, see and the . Because the instructions on this page describe how to simulate a multi-region cluster on a single machine, the absolute performance numbers described below are not reflective of . Instead, the instructions are designed with the following goals:
  • To show the relative magnitude of the performance improvements to expect when you configure a multi-region cluster correctly.
  • To be as easy to try as possible with minimal configuration and setup.

Before you begin

Make sure you have:

A basic understanding of the MovR application

The workload you’ll run against the cluster is our open-source, fictional, peer-to-peer vehicle-sharing app, . Each instance represents users in a specific region:
  • europe-west1, covering the cities of Amsterdam, Paris, and Rome.
  • us-east1, covering the cities of New York, Boston, and Washington, D.C.
  • us-west1, covering the cities of Los Angeles, San Francisco, and Seattle.

The MovR schema

The six tables in the movr database store user, vehicle, and ride data for MovR:
TableDescription
usersPeople registered for the service.
vehiclesThe pool of vehicles available for the service.
ridesWhen and where users have rented a vehicle.
promo\_codesPromotional codes for users.
user\_promo\_codesPromotional codes in use by users.
vehicle\_location\_historiesVehicle location history.
Geo-partitioning schema All of the tables except promo_codes have a composite primary key of city and id, in that order. This means that the rows in these tables are ordered by their geography. These tables are read from and written to very frequently. To keep read and write latency low, you’ll use the for these tables. The data in the promo_codes table is different: it is not tied to geography, and it is rarely updated. This type of table is often referred to as a “reference table” or “lookup table”. In this case, you’ll use the to keep read latencies low. For a description of the sequence of SQL statements issued by the MovR application in response to user actions, see .

Step 1. Simulate a multi-region cluster

Use the following command to start the cluster. This particular combination of flags results in a demo cluster of 9 nodes, with 3 nodes in each region. It sets the appropriate and also simulates the network latency that would occur between nodes in these localities. For more information about each flag, see the documentation, especially for .
When the cluster starts, you’ll see a message like the one shown below, followed by a SQL prompt. Note the URLs for:
  • Viewing the : http://127.0.0.1:8080.
  • Connecting to the database from a or a : postgres://root@127.0.0.1:26257?sslmode=disable.
To verify that the simulated latencies are working as expected, check the in the DB Console. Round trip times between us-west1 and europe-west1 should be in the 150 ms range.

Step 2. Determine node locations

To determine which nodes are in which regions, you will need to refer to two (2) things:
  1. The output of the \demo ls from the SQL shell, which shows the TCP ports on the local machine that we will connect to from the MovR application.
  2. The node IDs shown on the Network Latency Page.
Here is the output of \demo ls from the SQL shell.
And here is the view on the Network Latency Page, which shows which nodes are in which cluster regions: Geo-partitioning network latency You can see by referring back and forth between \demo ls and the Network Latency Page that the cluster has the following region/node/port correspondences, which we can use to determine how to connect MovR from various regions:
Node IDRegionPort on localhost
N2europe-west126263
N5europe-west126264
N7europe-west126265
N4us-west126262
N6us-west126260
N9us-west126261
N1us-east126257
N3us-east126259
N8us-east126258

Step 3. Load and run MovR

Follow these steps to start 3 instances of MovR. Each instance is pointed at a node in a different region. This will simulate load from that region.
  1. In the SQL shell, create the movr database:
  2. Open a second terminal and run the command below to populate the MovR data set. The options are mostly self-explanatory. We limit the application to 1 thread because using multiple threads quickly overloads this small demo cluster’s ability to ingest data. As a result, loading the data takes about 90 seconds on a fast laptop.
  3. In the same terminal window, run the following command:
  4. Open a third terminal and run the following command:
  5. Open a fourth terminal and run the following command:

Step 4. Check service latency

Now that you have load hitting the cluster from different regions, check how the service latencies look before you do any multi-region configuration from SQL. This is the “before” case in the “before and after”. In the at http://127.0.0.1:8080, click on the left and hover over the timeseries graph. You should see the effects of network latency on this workload. Geo-partitioning SQL latency For each of the 3 nodes that you are pointing the movr workload at, the max latency of 99% of queries are in the 1-2 seconds range. The SQL latency is high because of the network latency between regions. To see the network latency between any two nodes in the cluster, click in the left-hand navigation. Geo-partitioning network latency Within a single region, round-trip latency is under 6 ms (milliseconds). Across regions, round-trip latency is significantly higher. For example:
  • Round-trip latency between N2 in europe-west1 and N3 in us-east1 is 87 ms.
  • Round-trip latency between N2 in europe-west1 and N4 in us-west1 is 196 ms.

Step 5. Execute multi-region SQL statements

The following SQL statements will configure: This information is necessary so that CockroachDB can move data around to optimize access to particular data from particular regions. The main focus is reducing latency in a global deployment. For more information about how this works at a high level, see the .
The following ALTER statements will take some seconds to run, since the cluster is under load.

Configure database regions

Back in the SQL shell, switch to the movr database:
Execute the following statements. They will tell CockroachDB about the database’s regions. This information is necessary so that CockroachDB can later move data around to optimize access to particular data from particular regions. For more information about how this works at a high level, see .

Configure table localities

Configure GLOBAL tables

As mentioned earlier, all of the tables except promo_codes are geographically specific. Because the data in promo_codes is not updated frequently (a.k.a., “read-mostly”), and needs to be available from any region, the right table locality is .
Next, alter the user_promo_codes table to have a foreign key into the global promo_codes table. This will enable fast reads of the promo_codes.code column from any region in the cluster.

Configure REGIONAL BY ROW tables

All of the tables except promo_codes contain rows which are partitioned by region, and updated very frequently. For these tables, the right table locality for optimizing access to their data is . Apply this table locality to the remaining tables. These statements use a CASE statement to put data for a given city in the right region and can take around 1 minute to complete for each table.
  • rides
  • user_promo_codes
  • users
  • vehicle_location_histories
  • vehicles

Step 6. Re-check service latency

As the multi-region schema changes complete, you should see changes to the following metrics:
  • SQL Queries: This number should go up, since the cluster can service more load due to better performance (due to better data locality and lower latency). In this particular run, the QPS has almost doubled, from 87 to 164.
  • Service Latency: SQL, 99th percentile: In general, even on a small demo cluster like this, the P99 latency should drop and also get less spiky over time, as schema changes finish and data is moved around. For this particular run, the P99 latency has dropped from ~1200 ms to ~870 ms, an over 25% improvement.
  • Replicas per Node: This will increase, since the data needs to be spread across more nodes in order to service the multi-region workload appropriately. There is nothing you need to do about this, except to note that it happens, and is required for CockroachDB’s improved multi-region performance features to work.
The small demo cluster used in this example is essentially in a state of overload from the start. The performance numbers shown here only reflect the direction of the performance improvements. You should expect to see much better absolute performance numbers than those described here .
Geo-partitioning SQL latency

See also