Scale Reads with DigitalOcean Managed Database Read Replicas
Offload read queries from your primary database by adding a read replica and routing application traffic to separate endpoints.
04 Feb 2026, 19:58 UTC

Your API is slow, and the database CPU graph is flatlining at 90 percent. The tables are indexed, the queries are efficient, and most traffic is reads—dashboards, feeds, search results. Scaling up to a larger managed database node buys more CPU and RAM, but it does not reduce the number of concurrent read queries hitting the same primary instance.
The practical alternative is a read replica. DigitalOcean Managed Databases can provision a read-only follower for PostgreSQL, MySQL, and Redis. The replica stays synchronized with the primary through asynchronous replication, and your application can send SELECT traffic to the replica’s own connection string while writes continue on the primary.
This post covers how to add a replica, route reads in application code, verify replication health, and understand the cost and consistency trade-offs before you change production traffic.
How Read Replicas Work
A read replica is a separate database node that mirrors data from the primary node. When your application writes to the primary, the primary streams those changes to the replica using the database engine’s native replication protocol. Because streaming is asynchronous, a committed write on the primary may not appear on the replica immediately. That delay is replication lag, and it is usually sub-second under normal load but can grow during heavy write bursts.
Replicas are read-only. Any INSERT, UPDATE, or DELETE sent to the replica endpoint is rejected. They are not automatic failover targets in the same way as high-availability standby nodes; they are distinct endpoints that your application must explicitly address.
Provision a Replica and Collect Connection Strings
In the DigitalOcean Cloud Console, open your managed database cluster, go to the replica or node settings, and add a read replica. You can choose the same region as the primary for minimal lag, or a nearby region to reduce read latency for users in that geography. Remote regions increase network travel time and can widen replication lag.
After the replica is provisioned, DigitalOcean provides a dedicated connection string. You now have at least two endpoints:
- Primary: accepts reads and writes
- Replica: accepts reads only
Add both connection strings to your application configuration. Do not hard-code passwords; use environment variables or a secrets manager. Also add the application’s outbound IP addresses to the database cluster’s trusted sources firewall rules, or the replica will reject connections.
Example: Separate Read and Write Pools in Node.js
This example uses the `pg` client for PostgreSQL. It creates two pools: one for writes and one for reads. Placeholders such as `PRIMARY_HOST` and `REPLICA_HOST` must be replaced with the hostnames from your DigitalOcean cluster details.
const { Pool } = require('pg');
const writePool = new Pool({
connectionString: process.env.DATABASE_WRITE_URL,
// Example: postgresql://doadmin:PASSWORD@PRIMARY_HOST:25060/defaultdb?sslmode=require
});
const readPool = new Pool({
connectionString: process.env.DATABASE_READ_URL,
// Example: postgresql://doadmin:PASSWORD@REPLICA_HOST:25060/defaultdb?sslmode=require
});
async function getUserProfile(userId) {
const result = await readPool.query('SELECT id, email, bio FROM users WHERE id = $1', [userId]);
return result.rows[0];
}
async function updateUserBio(userId, bio) {
await writePool.query('UPDATE users SET bio = $1 WHERE id = $2', [bio, userId]);
}
Run this code in your application host or container, not inside the managed database. DigitalOcean managed nodes do not provide SSH access, so you cannot run application logic on the database server itself.
Verify the Replica and Check Replication Lag
Connect to the replica from a machine that has network access to the cluster, such as your laptop or an app server in the same VPC:
psql "postgresql://doadmin:PASSWORD@REPLICA_HOST:25060/defaultdb?sslmode=require"
Required permissions: a database user with login privileges and a password, plus the client IP added to the cluster’s trusted sources. Risk: connection strings contain credentials; avoid pasting them into terminal history or logs.
Once connected, confirm the node is read-only:
SHOW transaction_read_only;
Expected result: `on`. Then run a simple read:
SELECT count(*) FROM users;
To check replication lag, query the primary—not the replica—if your database user has permission to view replication statistics:
SELECT client_addr, state, sent_lsn, write_lsn, flush_lsn, replay_lsn FROM pg_stat_replication;
This view requires privileges that standard DigitalOcean managed database users may not have. If the query returns a permission error, use the DigitalOcean dashboard’s database monitoring graphs instead. Look for the replication lag metric and compare it against your application’s acceptable staleness window.
A practical check after a write: insert a timestamped row on the primary, then immediately query the same row from the replica. If the row is missing or stale, you have observed replication lag. Design read queries to tolerate that delay.
Trade-offs and Limitations
- Cost: Each replica is a full node with its own compute and storage charges. Two replicas roughly triple the database layer’s hourly cost compared to a single-node primary.
- Consistency: Reads may return data that is milliseconds to seconds behind the primary. Do not route financial ledger reads or immediately-after-write reads to the replica unless your application can handle stale data.
- Read-only: Write attempts to the replica fail with a connection or transaction error. Your application must route writes to the primary.
- Storage: Replicas mirror the primary’s storage allocation. If you increase primary disk size, confirm replica capacity remains sufficient.
Decide Whether to Add a Replica
Start with one replica in the same region as your primary. Offload your most expensive read-only reports and dashboard queries first. Monitor the dashboard’s replication lag graph and the replica’s CPU and memory. If lag stays low and read CPU on the primary drops, the replica is working. If lag spikes during writes, either reduce replica read load or reconsider whether vertical scaling or query optimization is a better fit.
Read replicas scale read capacity, not write throughput. They are a useful tool when reads are the bottleneck, but they do not make writes faster.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.