Reducing Geo-Distributed Latency with YugabyteDB Follower Reads
Learn how to use YugabyteDB follower reads to reduce geo-distributed read latency from 100ms+ to single-digit milliseconds by serving requests from local replicas.
07 May 2026, 20:10 UTC

The Cost of Strong Consistency in Global Apps
In a geo-distributed database, the laws of physics create a persistent engineering hurdle: speed of light. When you deploy a cluster across three regions (e.g., US-East, US-West, and EU-West) to ensure high availability, a standard read request must typically travel to the tablet leader. If your user is in London but the leader for their data is in Virginia, every single query incurs a round-trip latency of 100ms or more.
For many applications, this "leader-hop" is unnecessary. While writes must be linearizable to prevent data corruption, many read-heavy workloads—such as product catalogs, user profiles, or configuration settings—can tolerate a few seconds of staleness in exchange for single-digit millisecond response times. This is where Follower Reads (also known as timeline reads) become a critical architectural lever.
How Follower Reads Bypass the Leader
By default, YugabyteDB routes reads to the Raft leader to ensure the most current data is returned. Follower reads allow the database to serve the request from the nearest replica (the follower) in the local region.
To prevent "time travel" anomalies—where a user sees a new value and then suddenly sees an older value on a subsequent refresh—YugabyteDB uses a Hybrid Logical Clock (HLC). The tablet leader tracks a "safe time" timestamp that it knows all followers have already replicated. When a follower read is requested, the follower serves the data as of that safe timestamp. This guarantees timeline consistency: the data may be slightly stale, but it is internally consistent and monotonically increasing.
Implementation and Configuration
Follower reads are an opt-in feature. You can enable them at the session level or for a specific transaction using YSQL (the PostgreSQL-compatible API).
Session-Level Enablement
To route all subsequent reads in a connection to the nearest follower, run the following command on your client connection:
SET yb_read_from_followers = on;
Transaction-Level Enablement
For more granular control, you can specify follower reads for a specific transaction block:
BEGIN;
SET TRANSACTION FOLLOWER READS;
SELECT * FROM user_profiles WHERE user_id = '123';
COMMIT;
The amount of allowed staleness is controlled by the cluster-wide setting yb_follower_read_staleness_ms (which defaults to 30 seconds). If a follower's data is older than this threshold, the request will fail or fall back to the leader to avoid serving excessively stale data.
Worked Example: Multi-Region Latency Reduction
Consider a SaaS application deployed across us-east-1, us-west-2, and eu-central-1. A table containing tenant_settings is replicated across all three regions.
| Read Type | Request Path (User in EU) | Typical Latency | Consistency |
|---|---|---|---|
| Standard Read | EU Client → US-East Leader | 120ms - 150ms | Linearizable |
| Follower Read | EU Client → EU Follower | 2ms - 10ms | Timeline (Bounded Staleness) |
Verifying the Execution Path
To confirm that your query is actually hitting a follower and not routing to the leader, use EXPLAIN ANALYZE. Run this from a client connected to a node in a non-leader region:
SET yb_read_from_followers = on;
EXPLAIN ANALYZE SELECT * FROM tenant_settings WHERE tenant_id = 'abc';
In the output, look for the "Executed on: follower" annotation. If you see "Executed on: leader," the request was routed away from the local node, likely because no local replica exists for that specific tablet.
Trade-offs and Constraints
Follower reads are not a silver bullet. There are three primary limitations to consider:
- Read-Your-Writes Gap: If a user updates their profile (Write to Leader in US-East) and immediately refreshes the page (Follower Read in EU), they may see the old data for a few seconds. For critical paths like password changes or financial balances, keep
yb_read_from_followers = off. - Resource Contention: Follower reads consume CPU and I/O on the same nodes handling replication apply. For massive analytical workloads (OLAP), use xCluster asynchronous replication to a dedicated read-only cluster instead of using follower reads on the primary cluster.
- DDL Blocking: Schema changes (like
ALTER TABLE) require leader coordination. Reads on followers may be blocked or return errors until the schema change has propagated across all replicas.
Summary Checklist for Implementation
- Identify Read-Heavy Tables: Target reference data or metadata that changes infrequently.
- Configure Session Logic: Update your application's connection pool or middleware to issue
SET yb_read_from_followers = on;for read-only sessions. - Validate Latency: Use
pgbenchorEXPLAIN ANALYZEto verify the reduction in round-trip time. - Define Staleness: Adjust
yb_follower_read_staleness_msbased on your application's tolerance for old data.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.