Mono and Flux — Operators, Schedulers, and Practical Use
Fast recall
Quick revision
Core answer
Publishers and are cold by default — nothing happens until you subscribe. Composition is via operators in four families: transforming (map, flatMap, zip), error-handling (onErrorResume, retryWhen), combining (merge, concat, switchMap), and scheduling (subscribeOn, publishOn, timeout). Schedulers pick the thread pool: parallel() for CPU, boundedElastic() for blocking, single() for serial, immediate() for caller. Golden rules: use flatMap (not map) when the transform returns another Mono/Flux; never block on event-loop threads.Concrete reactive operator usage, scheduler selection, practical patterns and pitfalls
Using map instead of flatMap; blocking in reactive chain; misunderstanding cold vs hot; forgetting to subscribe
Discuss operator fusion, backpressure propagation, groupBy semantics, checkpoint for debugging, parallel Flux for CPU pipelines
Interview-ready guide
Interview answer
Mono is 0 or 1 async result; Flux is 0 to N. Both are Reactive Streams Publishers and are cold by default — nothing happens until subscribe.
Operators by family
- Transforming:
mapfor sync,flatMapfor async,concatMapfor ordered,switchMapfor cancel-and-restart - Filtering:
filter,take,skip,distinct - Combining:
mergeinterleaves,concatis strictly ordered,zipwaits for all,groupBysplits by key - Error handling:
onErrorReturn,onErrorResume,retryWhenwith backoff,timeout - Side effects:
doOnNext,log(),checkpoint(label)for debugging - Scheduling:
subscribeOn,publishOn
Schedulers
parallel()— CPU-bound non-blocking, sized to CPUsboundedElastic()— wrap blocking I/Osingle()— serial backgroundimmediate()— caller thread- Never run blocking code on
parallel()or Netty event loop
`subscribeOn` vs `publishOn`
subscribeOnaffects where the source subscription runs; first winspublishOnswitches scheduler for downstream operators; can appear multiple times
Context propagation
- Reactor
Contextplus Micrometer Context Propagation bridges MDC andSecurityContextacross thread hops
Golden rules
- Use
flatMapnotmapwhen transform returnsMono/Flux - Never block on event-loop threads
- Propagate context with Reactor
Context - Add
.checkpoint()and.log()when debugging
Top gotchas
Mono.just(expensiveCall())runs eagerly; useMono.fromCallablefor lazy- Cold publisher re-subscribed re-runs the source; use
.cache()for sharing @Transactionalis thread-bound; needTransactionalOperatorfor reactive- Backpressure mismatch causes memory explosion; bound buffers
Mental model
Mono/Fluxis a description, nothing runs until subscribe, operators add behavior, schedulers decide which thread runs what- If you're constantly fighting reactive, consider whether virtual threads fit better
Mono and Flux — Operators, Schedulers, and Practical Use
Direct Answer
Mono<T> represents 0 or 1 async result; Flux<T> represents 0..N async results. Both are Reactive Streams Publishers and are cold by default — nothing happens until you subscribe. Composition is via operators in four families: transforming (map, flatMap, zip), error-handling (onErrorResume, retryWhen), combining (merge, concat, switchMap), and scheduling (subscribeOn, publishOn, timeout). Schedulers pick the thread pool: parallel() for CPU, boundedElastic() for blocking, single() for serial, immediate() for caller. Golden rules: use flatMap (not map) when the transform returns another Mono/Flux; never block on event-loop threads.
Common Mistakes & Pitfalls
Using map instead of flatMap; blocking in reactive chain; misunderstanding cold vs hot; forgetting to subscribe
Check your understanding
Answer these without looking back at the article.
- What is the difference between subscribeOn and publishOn with examples?
- How do you wrap a blocking JDBC call safely in a reactive chain?
- When would you use switchMap vs flatMap vs concatMap?
- How does Reactor Context replace ThreadLocal for request-scoped data?
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.