Buffered batched loading optimization with Kotlin Coroutines and Channels

Batching many API requests in a single API call 😅

Enough words! Let’s get to the implementation!

Let’s start with defining Loader interface that we are going to optimize.

interface Loader<ID, T> {
suspend fun loadByIds(ids: Set<ID>): Map<ID, T>
  1. Instead of calling the API right away, loadByIds method will queue a request for loading via a Channel and “return” a Deferred which can be awaited.
  2. There will be a pool of workers which will pull as many requests as possible from the Channel, combine these requests into a single request (batching) and finally call the API with the new request.
private data class LoadRequest<ID, T>(  
val ids: Set<ID>,
val result: CompletableDeferred<Map<ID, T>>
val additionalRequest: LoadRequest<ID, T>? = 
select {
requests.onReceive { it }
onTimeout(0) { null }
try {
val loadedObjects = delegateLoader.loadByIds(idsToLoad)
requestsToProcess.forEach { processedRequests ->
loadedObjects.filterKeys { processedRequests.ids.contains(it) }
} catch (e: Exception) {
requestsToProcess.forEach { it.result.completeExceptionally(e) }


For testing I’ve created a simple TestLoader that emulates API calls with a response time from 10ms to 30ms.

val requests = 3_000
(1..requests).map { step ->
val idToLoad = step % 300
async {
val result = loader.loadByIds(setOf(idToLoad))
assertEquals(1, result.size)
assertEquals(idToLoad, result[idToLoad])
val regularTime = measureTime { loadTest(TestLoader()) }
val batchedTime = measureTime {
loadTest(BatchLoader(delegateLoader = TestLoader()))



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store