It is opitimized and automatically applies backpressure on producer, so you can write your own processing logic without worrying about all the buffering details. If you use it with a coroutine that does not have its own dispatcher, then the end-result (performance-wise) is the same as if you’ve manually wrote the corresponding state machine in your onNext/onError/onComplete methods.