How do you throttle replication bandwidth in Kafka, and what's the tradeoff between intra-cluster replica throttling and cross-cluster MirrorMaker 2 throttling?
answer
- two layers: replica throttle vs MM2 quotas
- leader/follower.replication.throttled.rate + --throttle
- MM2 = Connect client => producer/consumer_byte_rate quotas
- too low => lag/RPO; too high => WAN saturation
- size above ingest + headroom; raise for catch-up
basics
~20 sInside one cluster you throttle replica traffic with leader.replication.throttled.rate / follower.replication.throttled.rate (set via kafka-configs / kafka-reassign-partitions). Across clusters, MM2 runs as Connect clients, so you throttle it with producer/consumer quotas and tasks.max. Throttle too low and lag/RPO grows; too high and you saturate the WAN.
solid answer
~40 sKafka has two distinct throttling layers. (1) **Intra-cluster replica throttling** limits how fast followers fetch from leaders during partition reassignment or rebalancing: you set `leader.replication.throttled.rate` and `follower.replication.throttled.rate` (bytes/sec) plus the `*.replication.throttled.replicas` lists, typically applied automatically by `kafka-reassign-partitions.sh --throttle`. This protects normal produce/consume traffic from being starved by a big rebalance. (2) **Cross-cluster (MM2) throttling**: MirrorMaker 2 is Kafka Connect, so it reads/writes as ordinary clients — you throttle it with client/user **quotas** (`producer_byte_rate`, `consumer_byte_rate`) set per client-id/principal via kafka-configs, and you bound parallelism with `tasks.max`. The tradeoff: throttle replication too aggressively and replication lag accumulates, blowing your RPO; throttle too loosely and replication saturates the inter-region WAN or the target brokers, hurting live traffic. The right answer is to size throttles above steady ingest with headroom, and to raise them temporarily during backlog catch-up.
go deeper
Know there's a way to limit replication speed and that too slow means the copy falls behind.
Distinguish intra-cluster replica throttling from MM2 client quotas and the lag-vs-saturation tradeoff.
Name the exact configs (replication.throttled.rate, producer/consumer_byte_rate, tasks.max) and the --throttle/--verify workflow.
Design bandwidth governance: headroom sizing, catch-up policy, topic prioritization, and protecting shared WAN/tenants while meeting RPO.
**Two different problems, two mechanisms.** People conflate 'replication throttling' but Kafka has two unrelated layers. **1. Intra-cluster replica throttling (within one cluster).** Inside a single Kafka cluster, followers replicate partitions from leaders. During a *partition reassignment* (moving replicas between brokers, e.g. after adding brokers) this catch-up traffic can flood the network and starve normal producers/consumers. Kafka lets you cap it: - Broker/topic dynamic configs `leader.replication.throttled.rate` and `follower.replication.throttled.rate` (bytes/sec) limit, respectively, how fast a leader serves throttled replicas and how fast a follower fetches. - The topic configs `leader.replication.throttled.replicas` and `follower.replication.throttled.replicas` say *which* replicas the throttle applies to. - In practice you don't hand-set these — `kafka-reassign-partitions.sh --throttle <bytesPerSec>` applies them for the duration of a reassignment and you remove them with `--verify` afterward. You can also set them directly via `kafka-configs.sh --alter --add-config`. This is about protecting *live traffic from rebalancing traffic* inside one cluster. It has nothing to do with cross-cluster mirroring. **2. Cross-cluster MirrorMaker 2 throttling.** MM2 copies data *between* clusters and runs on Kafka Connect. To MM2's source and target clusters it is just a *consumer* (reading the source) and a *producer* (writing the target). So you throttle it with the same tools you throttle any client: - **Client/user quotas**: `producer_byte_rate` and `consumer_byte_rate` (bytes/sec) applied per `client-id`, `user` (principal), or both, via `kafka-configs.sh --alter --add-config 'producer_byte_rate=...,consumer_byte_rate=...' --entity-type clients/users`. Give MM2's Connect workers a known client-id/principal and quota that. - **Parallelism**: `tasks.max` on the MM2 connectors plus source partition count cap how many parallel streams run. - Network-level shaping (QoS on the WAN link) is sometimes layered on top. This is about protecting *the WAN link and the target cluster* from mirror traffic — and conversely, ensuring mirror traffic gets *enough* bandwidth. **The central tradeoff.** Cross-cluster bandwidth is finite (and over a WAN, expensive and shared). - **Throttle too low** -> replication throughput < ingest rate -> **replication lag accumulates** -> your DR copy falls further behind -> **RPO blows out** (you'd lose more data on failover). After any outage the backlog can never drain. - **Throttle too high / none** -> mirror traffic saturates the inter-region link or overloads target brokers -> live produce/consume latency spikes, or other tenants on a shared link suffer. **Doing it right.** - Size the MM2 quota *above peak steady-state ingest* with headroom so lag stays near zero in normal operation. - Keep a *catch-up* plan: after MM2 downtime, temporarily raise the quota (or `tasks.max`) so the backlog drains within the RPO budget, then return to baseline. - Prioritize DR-critical topics; exclude or deprioritize bulk/non-critical topics so the budget protects what matters. - Monitor replication-latency and the lag derivative; an upward trend means the throttle is below ingest. **Edge cases / pitfalls.** Forgetting to remove an intra-cluster reassignment throttle (`--verify` step) leaves replicas permanently rate-limited, risking under-replication. Quotas applied to the wrong client-id miss MM2 entirely. A single global quota across many MM2 tasks can serialize them; quota granularity (per client-id vs per user) matters. Setting the cross-cluster quota *at* ingest rate (no headroom) guarantees creeping lag.
- MM2 isn't a normal broker process — so how do you actually rate-limit its cross-cluster traffic?Because MM2 runs on Kafka Connect and acts as an ordinary consumer (source) and producer (target), you apply client/user quotas — producer_byte_rate and consumer_byte_rate via kafka-configs against MM2's client-id or principal — and bound tasks.max. The intra-cluster leader/follower replication throttles do NOT apply to MM2.
- What's the operational risk if you forget to clear an intra-cluster reassignment throttle?The leader/follower.replication.throttled.rate stays in effect indefinitely, permanently rate-limiting follower catch-up. Followers can fall out of the ISR or stay under-replicated, increasing data-loss risk. Always run kafka-reassign-partitions.sh --verify to remove the throttle after the reassignment completes.
saying these in an interview costs you the question
- Thinking leader/follower.replication.throttled.rate throttles MirrorMaker 2 (it's intra-cluster only).
- Setting the cross-cluster quota exactly at ingest rate with no headroom, then being surprised lag grows.
- Leaving a reassignment throttle in place after the move completes.