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

# Dedicated read replicas

> Independently sized dedicated read replicas for scaling Postgres reads across locations.

export const PlatformAvailability = ({current, vitess, postgres, neki}) => {
  const docsHref = path => {
    if (!path) return path;
    const normalized = path.startsWith('/') ? path : `/${path}`;
    return normalized;
  };
  const labels = {
    vitess: 'Vitess',
    postgres: 'Postgres',
    neki: 'Neki'
  };
  const combinedLabels = {
    both: 'Vitess and Postgres',
    all: 'Vitess, Neki, and Postgres',
    'postgres-neki': 'Postgres and Neki'
  };
  if (combinedLabels[current]) {
    return <div className="not-prose mb-5 flex flex-wrap items-center gap-2" role="group" aria-label="Platform availability">
        <span data-engine="both" data-state="current" aria-current="true" className="inline-flex items-center gap-1.5 whitespace-nowrap rounded-full border px-2.5 py-1 text-[13px] font-semibold leading-tight no-underline data-[engine=vitess]:data-[state=current]:border-[#ffc59b] data-[engine=vitess]:data-[state=current]:bg-[#ffe8d8] data-[engine=vitess]:data-[state=current]:text-[#672002] dark:data-[engine=vitess]:data-[state=current]:border-[#962d00] dark:data-[engine=vitess]:data-[state=current]:bg-[#3c1403] dark:data-[engine=vitess]:data-[state=current]:text-[#ffe8d8] data-[engine=vitess]:data-[state=link]:border-[#ffc59b] data-[engine=vitess]:data-[state=link]:bg-transparent data-[engine=vitess]:data-[state=link]:text-[#b83a05] dark:data-[engine=vitess]:data-[state=link]:border-[#962d00] dark:data-[engine=vitess]:data-[state=link]:bg-transparent dark:data-[engine=vitess]:data-[state=link]:text-[#ffc59b] data-[engine=postgres]:data-[state=current]:border-[#a9dffe] data-[engine=postgres]:data-[state=current]:bg-[#ddf2ff] data-[engine=postgres]:data-[state=current]:text-[#0e3682] dark:data-[engine=postgres]:data-[state=current]:border-[#144eb6] dark:data-[engine=postgres]:data-[state=current]:bg-[#08204e] dark:data-[engine=postgres]:data-[state=current]:text-[#ddf2ff] data-[engine=postgres]:data-[state=link]:border-[#a9dffe] data-[engine=postgres]:data-[state=link]:bg-transparent data-[engine=postgres]:data-[state=link]:text-[#0b6ec5] dark:data-[engine=postgres]:data-[state=link]:border-[#144eb6] dark:data-[engine=postgres]:data-[state=link]:bg-transparent dark:data-[engine=postgres]:data-[state=link]:text-[#73c7f9] data-[engine=neki]:data-[state=current]:border-[#fbca00] data-[engine=neki]:data-[state=current]:bg-[#fbca00] data-[engine=neki]:data-[state=current]:text-[#1a1a1a] dark:data-[engine=neki]:data-[state=current]:border-[#fbca00] dark:data-[engine=neki]:data-[state=current]:bg-[#fbca00] dark:data-[engine=neki]:data-[state=current]:text-[#1a1a1a] data-[engine=neki]:data-[state=link]:border-[#fbca00] data-[engine=neki]:data-[state=link]:bg-transparent data-[engine=neki]:data-[state=link]:text-[#8f7200] dark:data-[engine=neki]:data-[state=link]:border-[#fbca00] dark:data-[engine=neki]:data-[state=link]:bg-transparent dark:data-[engine=neki]:data-[state=link]:text-[#fbca00] data-[engine=both]:data-[state=current]:border-[#d4d4d4] data-[engine=both]:data-[state=current]:bg-[#f0f0f0] data-[engine=both]:data-[state=current]:text-[#3d3d3d] dark:data-[engine=both]:data-[state=current]:border-[#525252] dark:data-[engine=both]:data-[state=current]:bg-[#2a2a2a] dark:data-[engine=both]:data-[state=current]:text-[#e5e5e5]">
          {combinedLabels[current]}
        </span>
      </div>;
  }
  const hasVitess = current === 'vitess' || Boolean(vitess);
  const hasPostgres = current === 'postgres' || Boolean(postgres);
  const hasNeki = current === 'neki' || Boolean(neki);
  const only = [hasVitess, hasPostgres, hasNeki].filter(Boolean).length === 1;
  const engines = [];
  if (current === 'vitess' || current === 'postgres' || current === 'neki') engines.push(current);
  if (hasVitess && current !== 'vitess') engines.push('vitess');
  if (hasNeki && current !== 'neki') engines.push('neki');
  if (hasPostgres && current !== 'postgres') engines.push('postgres');
  return <div className="not-prose mb-5 flex flex-wrap items-center gap-2" role="group" aria-label="Platform availability">
      {engines.map(engine => {
    const isCurrent = current === engine;
    const href = docsHref(engine === 'vitess' ? vitess : engine === 'postgres' ? postgres : neki);
    const label = only ? `${labels[engine]} only` : labels[engine];
    const state = isCurrent || !href ? 'current' : 'link';
    if (isCurrent || !href) {
      return <span key={engine} data-engine={engine} data-state={state} aria-current={isCurrent ? 'true' : undefined} className="inline-flex items-center gap-1.5 whitespace-nowrap rounded-full border px-2.5 py-1 text-[13px] font-semibold leading-tight no-underline data-[engine=vitess]:data-[state=current]:border-[#ffc59b] data-[engine=vitess]:data-[state=current]:bg-[#ffe8d8] data-[engine=vitess]:data-[state=current]:text-[#672002] dark:data-[engine=vitess]:data-[state=current]:border-[#962d00] dark:data-[engine=vitess]:data-[state=current]:bg-[#3c1403] dark:data-[engine=vitess]:data-[state=current]:text-[#ffe8d8] data-[engine=vitess]:data-[state=link]:border-[#ffc59b] data-[engine=vitess]:data-[state=link]:bg-transparent data-[engine=vitess]:data-[state=link]:text-[#b83a05] dark:data-[engine=vitess]:data-[state=link]:border-[#962d00] dark:data-[engine=vitess]:data-[state=link]:bg-transparent dark:data-[engine=vitess]:data-[state=link]:text-[#ffc59b] data-[engine=postgres]:data-[state=current]:border-[#a9dffe] data-[engine=postgres]:data-[state=current]:bg-[#ddf2ff] data-[engine=postgres]:data-[state=current]:text-[#0e3682] dark:data-[engine=postgres]:data-[state=current]:border-[#144eb6] dark:data-[engine=postgres]:data-[state=current]:bg-[#08204e] dark:data-[engine=postgres]:data-[state=current]:text-[#ddf2ff] data-[engine=postgres]:data-[state=link]:border-[#a9dffe] data-[engine=postgres]:data-[state=link]:bg-transparent data-[engine=postgres]:data-[state=link]:text-[#0b6ec5] dark:data-[engine=postgres]:data-[state=link]:border-[#144eb6] dark:data-[engine=postgres]:data-[state=link]:bg-transparent dark:data-[engine=postgres]:data-[state=link]:text-[#73c7f9] data-[engine=neki]:data-[state=current]:border-[#fbca00] data-[engine=neki]:data-[state=current]:bg-[#fbca00] data-[engine=neki]:data-[state=current]:text-[#1a1a1a] dark:data-[engine=neki]:data-[state=current]:border-[#fbca00] dark:data-[engine=neki]:data-[state=current]:bg-[#fbca00] dark:data-[engine=neki]:data-[state=current]:text-[#1a1a1a] data-[engine=neki]:data-[state=link]:border-[#fbca00] data-[engine=neki]:data-[state=link]:bg-transparent data-[engine=neki]:data-[state=link]:text-[#8f7200] dark:data-[engine=neki]:data-[state=link]:border-[#fbca00] dark:data-[engine=neki]:data-[state=link]:bg-transparent dark:data-[engine=neki]:data-[state=link]:text-[#fbca00] data-[engine=both]:data-[state=current]:border-[#d4d4d4] data-[engine=both]:data-[state=current]:bg-[#f0f0f0] data-[engine=both]:data-[state=current]:text-[#3d3d3d] dark:data-[engine=both]:data-[state=current]:border-[#525252] dark:data-[engine=both]:data-[state=current]:bg-[#2a2a2a] dark:data-[engine=both]:data-[state=current]:text-[#e5e5e5]">
              {label}
            </span>;
    }
    return <a key={engine} href={href} data-engine={engine} data-state={state} title={`View ${labels[engine]} documentation`} className="inline-flex items-center gap-1.5 whitespace-nowrap rounded-full border px-2.5 py-1 text-[13px] font-semibold leading-tight no-underline data-[engine=vitess]:data-[state=current]:border-[#ffc59b] data-[engine=vitess]:data-[state=current]:bg-[#ffe8d8] data-[engine=vitess]:data-[state=current]:text-[#672002] dark:data-[engine=vitess]:data-[state=current]:border-[#962d00] dark:data-[engine=vitess]:data-[state=current]:bg-[#3c1403] dark:data-[engine=vitess]:data-[state=current]:text-[#ffe8d8] data-[engine=vitess]:data-[state=link]:border-[#ffc59b] data-[engine=vitess]:data-[state=link]:bg-transparent data-[engine=vitess]:data-[state=link]:text-[#b83a05] dark:data-[engine=vitess]:data-[state=link]:border-[#962d00] dark:data-[engine=vitess]:data-[state=link]:bg-transparent dark:data-[engine=vitess]:data-[state=link]:text-[#ffc59b] data-[engine=postgres]:data-[state=current]:border-[#a9dffe] data-[engine=postgres]:data-[state=current]:bg-[#ddf2ff] data-[engine=postgres]:data-[state=current]:text-[#0e3682] dark:data-[engine=postgres]:data-[state=current]:border-[#144eb6] dark:data-[engine=postgres]:data-[state=current]:bg-[#08204e] dark:data-[engine=postgres]:data-[state=current]:text-[#ddf2ff] data-[engine=postgres]:data-[state=link]:border-[#a9dffe] data-[engine=postgres]:data-[state=link]:bg-transparent data-[engine=postgres]:data-[state=link]:text-[#0b6ec5] dark:data-[engine=postgres]:data-[state=link]:border-[#144eb6] dark:data-[engine=postgres]:data-[state=link]:bg-transparent dark:data-[engine=postgres]:data-[state=link]:text-[#73c7f9] data-[engine=neki]:data-[state=current]:border-[#fbca00] data-[engine=neki]:data-[state=current]:bg-[#fbca00] data-[engine=neki]:data-[state=current]:text-[#1a1a1a] dark:data-[engine=neki]:data-[state=current]:border-[#fbca00] dark:data-[engine=neki]:data-[state=current]:bg-[#fbca00] dark:data-[engine=neki]:data-[state=current]:text-[#1a1a1a] data-[engine=neki]:data-[state=link]:border-[#fbca00] data-[engine=neki]:data-[state=link]:bg-transparent data-[engine=neki]:data-[state=link]:text-[#8f7200] dark:data-[engine=neki]:data-[state=link]:border-[#fbca00] dark:data-[engine=neki]:data-[state=link]:bg-transparent dark:data-[engine=neki]:data-[state=link]:text-[#fbca00] data-[engine=both]:data-[state=current]:border-[#d4d4d4] data-[engine=both]:data-[state=current]:bg-[#f0f0f0] data-[engine=both]:data-[state=current]:text-[#3d3d3d] dark:data-[engine=both]:data-[state=current]:border-[#525252] dark:data-[engine=both]:data-[state=current]:bg-[#2a2a2a] dark:data-[engine=both]:data-[state=current]:text-[#e5e5e5]">
            {label}
            <svg aria-hidden="true" width="12" height="12" viewBox="0 0 12 12" fill="none" className="shrink-0">
              <path d="M2.5 6h7M6.5 3l3 3-3 3" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
          </a>;
  })}
    </div>;
};

<PlatformAvailability current="postgres" vitess="/vitess/scaling/read-only-regions" />

## Overview

Dedicated read replicas maintain continuously updated copies of a production branch in locations you select. Use them to serve read traffic closer to your applications and users or to isolate read-heavy workloads from the primary cluster.

A dedicated read replica differs from the [replicas in your primary cluster](/docs/postgres/scaling/replicas):

* Primary-cluster replicas provide high availability and read capacity within the primary location.
* Dedicated read replicas are distincy Postgres nodes from the primary cluster and provide independently sized read capacity in a location you select.

Each dedicated read replica has a unique name and contains one or more read-only instances. Configure its location, cluster size, replica count, storage, and supported Postgres parameters independently of the primary cluster. You can create multiple dedicated read replicas in the same location.

Dedicated read replicas can be created in the same cloud region as the primary or different ones from the same cloud privider.
You may not, for example, have your primary in an AWS region and a dedicated read replica in a GCP region.

Database administrators and organization administrators can create and manage dedicated read replicas.

<Warning>
  PlanetScale asynchronously replicates changes to dedicated read replicas. Applications that query them must tolerate [replication lag and temporarily stale results](/docs/postgres/scaling/replicas#data-consistency-and-replication-lag).
</Warning>

## Create a dedicated read replica

<Steps>
  <Step>
    In the [PlanetScale dashboard](https://app.planetscale.com), select your database and production branch.
  </Step>

  <Step>
    Select **Clusters** in the left navigation, then select the **Dedicated read replicas** tab.
  </Step>

  <Step>
    Select **Add a dedicated read replica**.
  </Step>

  <Step>
    Enter a unique name, then choose the location, number of replicas, cluster size, and storage settings. The dashboard shows the estimated monthly compute and storage cost.
  </Step>

  <Step>
    Select **Add dedicated read replica**. The dedicated read replica appears with a **Provisioning** status until it is ready.
  </Step>
</Steps>

## Change a dedicated read replica

Set the cluster size, replica count, storage, and supported Postgres parameters independently for each dedicated read replica.

<Steps>
  <Step>
    Open the production branch's **Clusters** page and select **Dedicated read replicas**.
  </Step>

  <Step>
    Change the **Replica size** or **Number of replicas** for the cluster.
  </Step>

  <Step>
    For network-attached storage, configure the minimum disk size, storage limit, autoscaling, IOPS, or throughput.
  </Step>

  <Step>
    To change a supported Postgres parameter, expand **Customize cluster parameters** and enter the new value.
  </Step>

  <Step>
    Select **Save replica changes**. Changes apply immediately.
  </Step>
</Steps>

The **Changes** tab shows the status and history of dedicated read replica changes.

Storage settings apply independently to each dedicated read replica. For storage controls and limits, see [Cluster storage configuration](/docs/postgres/cluster-configuration/cluster-storage).

Set parameter values on a dedicated read replica at or above the corresponding primary-cluster values. Changing a parameter restarts the dedicated read replica.

For PlanetScale Metal, a dedicated read replica size must have enough storage for the primary cluster's current disk usage and required headroom.

## Connect to a dedicated read replica

Managed roles and passwords work across the primary cluster and its dedicated read replicas. The host and username are different for each dedicated read replica. The dashboard displays the connection details at creation time.

<Steps>
  <Step>
    Open the production branch and select **Connect**.
  </Step>

  <Step>
    Create or select a role.
  </Step>

  <Step>
    Under **Connection target**, choose the named dedicated read replica that you want to connect to.
  </Step>

  <Step>
    Copy the connection string or individual connection values that the dashboard provides.
  </Step>
</Steps>

You can also select a read-only connection target from a role's details page under **Settings** > **Roles**.

<Note>
  The generated username ends in `|replica`, which distributes connections across the read-only instances in the selected cluster.
</Note>

Dedicated read replicas reject `INSERT`, `UPDATE`, `DELETE`, and other write operations.

To retrieve connection details from the CLI, pass the dedicated read replica name to `pscale role get`:

```bash theme={null}
pscale role get <database> <branch> <role-id> --dedicated-read-replica <dedicated-read-replica-name>
```

## Monitor a dedicated read replica

Prometheus metrics for a dedicated read replica use `planetscale_database_branch_id` to identify the replica and `planetscale_upstream_database_branch_id` to identify its parent database branch. See the [Prometheus metrics reference](/docs/postgres/monitoring/prometheus-metrics-postgres).

## Manage dedicated read replicas with the API

The [PlanetScale API](/docs/api/reference/getting-started-with-planetscale-api) supports dedicated read replica management:

* [List dedicated read replicas](/docs/api/reference/list_dedicated_read_replicas)
* [Create a dedicated read replica](/docs/api/reference/create_dedicated_read_replica)
* [Get a dedicated read replica](/docs/api/reference/get_dedicated_read_replica)
* [Update a dedicated read replica](/docs/api/reference/update_dedicated_read_replica)
* [Delete a dedicated read replica](/docs/api/reference/delete_dedicated_read_replica)
* [List dedicated read replica change requests](/docs/api/reference/list_dedicated_read_replica_change_requests)

Creating a dedicated read replica requires a unique name and region slug. The API defaults to one instance and the primary cluster's size when you omit `replicas` and `cluster_size`.

Create and update requests accept a `storage` object containing `minimum_storage_bytes`, `maximum_storage_bytes`, `storage_autoscaling`, `storage_iops`, and `storage_throughput_mibs`.

Get, update, and delete requests identify a dedicated read replica by name. To retrieve role connection details for a specific cluster, pass its name in the [`dedicated_read_replica` query parameter](/docs/api/reference/get_role).

## Delete a dedicated read replica

<Steps>
  <Step>
    Open the production branch's **Clusters** page and select **Dedicated read replicas**.
  </Step>

  <Step>
    Select **Delete replica cluster** for the cluster you want to remove.
  </Step>

  <Step>
    Confirm by selecting **Delete replica cluster**.
  </Step>
</Steps>

<Warning>
  Deleting a dedicated read replica is irreversible and stops its connection endpoint.
</Warning>

## Pricing

The dashboard displays the estimated monthly compute and storage cost when you create or change a dedicated read replica. PlanetScale prorates charges when you create, delete, or resize clusters.

Compute charges consist of:

* The location's dedicated read replica rate for the first instance.
* The standard additional-replica rate for every instance after the first.

For network-attached storage, PlanetScale bills every instance in a dedicated read replica for its configured storage, IOPS, and throughput. PlanetScale Metal cluster prices include their local storage.

Cross-region replication traffic for Postgres dedicated read replicas is billed per GB with no included allowance. See [cross-region dedicated read replica traffic pricing](/docs/postgres/pricing#cross-region-dedicated-read-replica-traffic).

## Need help?

Get help from [the PlanetScale Support team](https://planetscale.com/contact?initial=support), or join our [Discord community](https://pscale.link/community) to see how others are using PlanetScale.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.