DEV

Kotlin Flow and RxJava both tackle async data streams — but they make very different tradeoffs. This episode breaks down cold vs. hot streams, backpressure handling, operator depth, and how to pick the right tool for your Android project.

Show Notes

Reactive programming on Android means choosing how your app handles asynchronous data — and for most teams, that choice eventually comes down to Kotlin Flow or RxJava. This episode of DEV.co digs into the practical differences between the two libraries, drawing on the Kotlin Flow vs. RxJava comparison article to give developers a clear framework for making that call. Whether you're greenfielding a new app or inheriting a legacy codebase, the tradeoffs are more nuanced than "new vs. old."

The episode covers the core concepts engineers need to evaluate before committing to either approach:

  • Cold vs. hot streams: Flow is cold by default — each collector gets a fresh sequence — while RxJava manages hot and cold through subjects and operators, offering flexibility that rewards careful boundary-setting.
  • Backpressure strategies: Flow uses suspending functions to let a slow collector naturally pace the producer; RxJava provides explicit strategies through Flowable and Observable, with different risk profiles depending on which you reach for.
  • Kotlin Flow's strengths: Built for coroutines, Flow brings structured concurrency, predictable lifecycle handling, and readable pipelines — a natural fit for teams already working with suspend functions and coroutine scopes.
  • Where Flow falls short: Its operator catalog is focused, not exhaustive. Edge-case pipeline combinations may require custom extensions, and interop with Java-only modules can be awkward.
  • RxJava's case for staying: A battle-tested operator library, expressive type distinctions (Single, Flowable, Completable, Maybe), and fine-grained scheduler control make RxJava hard to beat in performance-sensitive or heavily Rx-integrated modules.
  • Decision framework and practical tips: The episode lays out when to migrate, when to stay put, and how to manage a hybrid approach safely — including guidance on module boundaries, error-handling audits, and documenting threading contracts.

The episode closes with actionable advice that applies regardless of which library you choose: enforce one stream model per module, keep operator chains small and named, and never let exceptions silently disappear into logs. The goal is a codebase that a future teammate can read without a decoder ring.

More from the show: if you're thinking about architecture and build hygiene on mobile, check out the episode on Swift Package Manager Best Practices for Modular iOS Architecture and Faster Builds for a complementary take on keeping large codebases maintainable.

DEV.co

RFP.co

What is DEV?

Software and web development from the side that has to ship it and then live with it. Architecture decisions with a cost attached, scoping, technical debt, hiring and vendor selection, and the AI tooling question every engineering team is now answering whether they planned to or not.

Each episode takes one decision — rewrite or refactor, framework choice, build versus buy, how to scope a fixed-bid project honestly — and works through the tradeoffs, including the ones that only show up in year two. Written for engineering leads, technical founders and the people who fund them. Five or six minutes, no hand-waving.

Topics include rewrite versus refactor, build versus buy, scoping fixed-bid work honestly, technical debt you should keep, framework and platform choices, hiring and vendor selection, code review culture, and where AI tooling actually helps.

Produced by DEV.co, web and software development. Full details, services and further reading at https://dev.co