Reactor Backpressure — Strategies and Practical Handling
Fast recall
Quick revision
Core answer
flatMap(fn, N), prefetch tuning, and observability on buffer sizes. For genuinely mismatched rates, push the work off-process to Kafka or SQS.Real understanding of backpressure beyond the buzzword — strategy selection, when in-process backpressure is enough, and when you must push to an async boundary
Leaving unbounded buffers in production paths; ignoring backpressure until OOM; misconfiguring `flatMap` concurrency
Discuss Reactive Streams `request()` semantics, Reactor prefetch math, how HTTP/2 flow control interacts with WebClient, and Kafka as a durable backpressure boundary
Interview-ready guide
Interview answer
Backpressure is the mechanism by which a consumer tells the producer how much data it can handle through Subscription.request(n) in the Reactive Streams spec. Without it, a fast producer floods a slow consumer and blows up memory.
How it works under the hood:
- Demand flows backward: the consumer requests
n, and the producer promises no more than that - It's a pull-push hybrid — demand signal upstream, data downstream
- Reactor operators request in batches via prefetch (256 default)
- The system self-regulates 95% of the time
When backpressure becomes your problem:
- Inherently push sources — network stream, Kafka, websocket
- Slow downstream — DB inserts, rate-limited API
- Fan-out creating more work than one thread can handle
- Tight memory budget; can't buffer indefinitely
- Spiky producers bursting 10× steady rate
The four Reactor strategies:
- `onBackpressureBuffer(size)` for short bursts when you can pay the memory; always with overflow strategy
- `onBackpressureDrop` for sampleable streams; always with a counter so drops are visible
- `onBackpressureLatest` when only the most recent value matters
- `onBackpressureError` when a violation signals a bug — fail loudly
Concurrency control:
flatMap(fn, N)caps concurrent inner subscriptions; primary throughput knob- Prefetch override
flatMap(fn, N, prefetch)for memory-tight pipelines
When in-process isn't enough:
- Kafka or SQS as durable async boundary
- Reactor
Sinksfor in-process event bus with controlled backpressure - Reactor Kafka returns
Fluxwith end-to-end backpressure to the broker
The strategic answer: reactive's value is making backpressure explicit.
- Pick a strategy per pipeline and document the trade-off; monitor buffer sizes and drop counts; for structural mismatches, push to Kafka or SQS; never leave unbounded buffering in production.
- Virtual threads don't eliminate backpressure — they just change how you model it.
Reactor Backpressure — Strategies and Practical Handling
Direct Answer
Backpressure is the mechanism by which a consumer tells the producer how much data it can handle via Subscription.request(n) in the Reactive Streams spec. Without it, a fast producer floods a slow consumer and blows up memory. Reactor handles the happy path automatically — operators negotiate demand using a prefetch of 256 by default — but when producer and consumer rates mismatch structurally, you choose a strategy: onBackpressureBuffer(size) (buffer up to a bound; error or drop if exceeded), onBackpressureDrop (discard silently with instrumentation), onBackpressureLatest (keep only the newest), or onBackpressureError (fail fast). Pair with concurrency limits on flatMap(fn, N), prefetch tuning, and observability on buffer sizes. For genuinely mismatched rates, push the work off-process to Kafka or SQS.
Common Mistakes & Pitfalls
Leaving unbounded buffers in production paths; ignoring backpressure until OOM; misconfiguring flatMap concurrency
Check your understanding
Answer these without looking back at the article.
- How does HTTP/2 flow control interact with Reactor backpressure?
- What exactly does Reactor's prefetch parameter do?
- When would you push work to Kafka instead of handling backpressure in-process?
- How do you test backpressure behavior with StepVerifier?
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.