Scaling Read Traffic in YugabyteDB with Follower Reads
YugabyteDB’s follower‑read feature routes read‑only queries to replicas, offloading the leader and cutting latency in geo‑distributed clusters. Enable with a session variable, verify via tablet‑server logs, and watch leader CPU drop. Trade‑off: staleness; not for write‑heavy paths.
06 Jul 2026, 18:31 UTC

The Problem: Leader Bottlenecks on Read-Heavy Workloads
In a distributed SQL database like YugabyteDB, every tablet has a single leader replica that handles all writes and, by default, all reads. When your application issues a high volume of SELECT statements, the leader’s CPU and network become the limiting factor—especially in geo‑distributed clusters where cross‑region latency adds up. Adding more nodes doesn’t help if the leader remains the hotspot.
The practical takeaway: YugabyteDB’s follower‑read feature lets read‑only queries be served by any up‑to‑date replica, spreading load across the cluster without schema changes.
How Follower Reads Work
YugabyteDB replicates each tablet using the Raft consensus protocol. A tablet typically has three replicas: one leader and two followers. When you enable follower reads, the query layer checks whether the transaction is declared read‑only and runs at a consistency level that permits stale snapshots (e.g., READ COMMITTED with the follower‑read hint). If so, it routes the request to a follower that holds the latest committed snapshot at the requested hybrid logical time (HLT). The follower serves the data directly, bypassing the leader.
Key terms:
- Hybrid Logical Time (HLT): A timestamp combining physical time and a logical counter, used to order events across nodes.
- Read‑only transaction: A transaction that contains no
INSERT,UPDATE,DELETE, or DDL statements. - Monotonic reads: Within a session, each successive read sees a snapshot at least as recent as the previous one, preventing time‑travel anomalies.
Enabling Follower Reads
No schema migration or application rewrite is required. You enable the feature per session (or globally via configuration) by setting a YSQL session variable:
-- Run in ysqlsh or any PostgreSQL‑compatible client connected to the cluster
SET yb_follower_reads = ON;
Where to run: Any client session that issues read‑only queries. Requires standard SELECT privileges on the target tables; no superuser rights needed.
Verification: After enabling, execute a read‑only query and check the tablet‑server logs (typically /home/yugabyte/tserver/logs/ on each node). Look for log lines containing FollowerRead or follower read—these indicate the request was handled by a follower replica.
Worked Example: Offloading a Reporting Dashboard
Imagine a dashboard that runs the following query every 5 seconds across a 3‑node cluster spanning us-east-1, us-west-2, and eu-west-1:
SELECT region, count(*) AS events, max(ts) AS latest
FROM analytics.events
WHERE ts > now() - interval '1 hour'
GROUP BY region;
Before follower reads, the leader in us-east-1 processes every execution, saturating its CPU. After running SET yb_follower_reads = ON; in the dashboard’s connection pool, the query layer picks a follower—often the one in the same region as the client—reducing latency and freeing the leader for writes.
Expected checks:
- Leader CPU utilization drops (monitor via
yb-mastermetrics or Prometheusprocess_cpu_seconds_total). - Query latency improves for clients near follower replicas.
- Tablet‑server logs show
FollowerReadentries for the dashboard’s session.
Risks: If the dashboard accidentally includes a write (e.g., an UPSERT for last‑viewed timestamp), the transaction falls back to the leader, causing a sudden latency spike. Keep read‑only paths strictly separated.
Trade‑offs and Limitations
Follower reads are not a free lunch. The data returned can be slightly stale—up to the replication propagation delay, typically tens to hundreds of milliseconds in a healthy cluster. Applications that require read‑your‑writes consistency (e.g., a user posting a comment and immediately seeing it) must either avoid follower reads for that flow or use a stronger consistency level such as REPEATABLE READ or SERIALIZABLE, which force leader execution.
Additional constraints:
- DDL statements (
ALTER TABLE,CREATE INDEX) and transactions mixing reads with writes cannot use follower reads; they silently fall back to the leader. - The
yb_follower_readssetting is session‑scoped. Connection poolers must ensure it’s set on each checkout, or you can set the cluster‑wide default via theyb-tserverflag--yb_enable_follower_reads=true(requires rolling restart). - Geo‑distributed clusters benefit most when followers are placed in regions close to read clients. If all replicas sit in one zone, latency gains are minimal.
How to Confirm It’s Working in Production
Run this diagnostic query from a session with follower reads enabled:
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM analytics.events WHERE id = 12345;
In the output, look for Follower Read in the plan node description. If you see Index Scan or Seq Scan without the follower annotation, the query ran on the leader. Compare execution_time and leader_cpu_usage before and after enabling the flag to quantify the offload.
If you need to revert, simply SET yb_follower_reads = OFF; in the affected sessions—no state change occurs on the cluster, so no rollback procedure is required.
Closing: Start Small, Measure, Then Expand
Enable follower reads on one read‑heavy, read‑only service first (e.g., a reporting API or cache‑warming job). Verify the log signatures and leader CPU drop. Once confident, roll out to other read‑only workloads. Keep write paths on the leader, and you’ll get horizontal read scaling without the operational complexity of a separate read‑replica cluster.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.