Cold & Hot Streams in Kotlin Flow

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

In this lesson, you’ll learn about cold and hot streams in Kotlin Flow. Understanding the distinction between these two types of streams is important for effectively managing data flows in your apps.

Cold Streams

Cold streams are streams that don’t start emitting items until an observer subscribes. They’re passive and only begin their operations when a consumer is present. This behavior ensures that all subscribers see the entire sequence from the beginning, making cold streams ideal for precise and repeatable operations.

fun orderOfProcessing(): Flow<String> = flow {
  emit("Nantes")
  delay(1000)
  emit("Imperator")
  delay(1000)
  emit("Chantenay")
  delay(1000)
}

fun processCarrots(scope: CoroutineScope = GlobalScope) {
  val firstProcessingLine = scope.launch {
    orderOfProcessing().collect { type ->
      println("Processing carrots on Line 1: $type")
    }
  }

  val secondProcessingLine = scope.launch {
    orderOfProcessing().collect { type ->
      println("Processing carrots on Line 2: $type")
    }
  }

  // ...
}

fun main() = runBlocking {
  processCarrots()
  delay(5000)
}

Hot Streams

Hot streams, on the other hand, are active regardless of the presence of subscribers. They emit items, and these items can be lost if no observers are collecting at the time of emission. This makes hot streams ideal for representing events or data that are independent of individual subscribers’ timing, such as UI events or sensor data.

val processingType: MutableSharedFlow<String> = MutableSharedFlow<String>()

suspend fun switchCarrotType(type: String) {
  processingType.emit(type)
}

fun processCarrots(scope: CoroutineScope = GlobalScope) {
  val firstProcessingLine = scope.launch {
    processingType.collect { type ->
      println("Processing carrots on Line 1: $type")
    }
  }

  val secondProcessingLine = scope.launch {
    delay(1000)
    processingType.collect { type ->
      println("Processing carrots on Line 2: $type")
    }
  }

  // ...
}

fun main() = runBlocking {
  processCarrots()
  switchCarrotType("Nantes")
  delay(2000)
  switchCarrotType("Imperator")
  delay(5000)
}

Wrap-Up

In this lesson, you’ve explored the differences between cold and hot streams in Kotlin Flow. Cold streams replay the emitted data for each collector, ensuring consistency, while hot streams emit data independently of subscribers, suitable for real-time and event-based data.

See forum comments
Download course materials from Github
Previous: Introduction Next: Hot Streams Demo