When building Android apps with Kotlin, one common question pops up again and again:
👉 “Should I use Flow to fetch a simple API response, or is that overkill?”
Some developers joke it’s like using a dagger to cut a fruit—possible, but maybe not the smartest choice. Let’s break this down in plain English, with examples, so you can make the right decision for your project.
The Basics: suspend vs Flow
suspendfunctions
Asuspendfunction runs a coroutine and gives you one-shot results. Perfect for calling an API once (e.g., fetching a user profile or loading a list).Flow
AFlowis like a stream of values over time. Instead of giving you one result, it can keep emitting multiple values (loading → cached data → refreshed data, etc.).
So the difference is simple:
suspend→ one resultFlow→ many results over time
Example 1: Using suspend for a Simple API Call
If your app just needs to call an API once and display the result, suspend keeps it clean and simple:
interface ItemsRepository {
suspend fun getItems(page: Int = 1, limit: Int = 20): Resource<List<Item>>
}
class ItemsRepositoryImpl(private val api: ApiService) : ItemsRepository {
override suspend fun getItems(page: Int, limit: Int): Resource<List<Item>> {
return try {
val response = api.getItems(page, limit)
Resource.Success(response.data.toDomain())
} catch (e: Exception) {
Resource.Error("Something went wrong: ${e.message}")
}
}
}
Why it’s good:
- Easy to read and test
- No unnecessary complexity
- Perfect for one-shot network calls
Example 2: When Flow Makes Sense
Now imagine you want:
- Loading → Cached DB → Fresh API updates
- Search with debounce (live search)
- Pagination / streaming results
That’s where Flow shines:
override fun getItems(page: Int, limit: Int): Flow<Resource<List<Item>>> = flow {
emit(Resource.Loading)
try {
val resp = api.getItems(page, limit)
emit(Resource.Success(resp.data.toDomain()))
} catch (e: Exception) {
emit(Resource.Error("Error: ${e.message}"))
}
}
Here, Flow lets you emit multiple states (loading, success, error) and combine with other streams.
Decision Checklist ✅
- One-time call → use
suspend - Need multiple emissions or stream behavior → use
Flow - Using Paging 3 → Flow is required
- Search, caching, or reactive updates → Flow fits best
So… Is Flow Overkill for Simple API Calls?
Yes — for simple, one-time API calls, using Flow is like using a dagger to cut a fruit.
Stick with suspend.
But — if your use case involves streams, caching, or reactive UI updates, Flow is not just useful, it’s the right tool.
The real skill is knowing when to keep it simple and when to go reactive.
Final Thoughts
As a Kotlin Android developer, your job isn’t to use the fanciest tool — it’s to pick the right tool for the problem.
- Use
suspendwhen you just need a single result. - Use
Flowwhen you expect multiple updates or want to combine async streams.
The next time you’re about to wrap every API call in Flow, ask yourself:
👉 “Am I building a stream… or just fetching data once?”
Sometimes, the simplest knife cuts the fruit best.
Pro tip for interviews: If asked this question, explain both approaches and then say:
“For simple one-time API calls, I prefer
suspendfor clarity. But if the use case involves streaming updates, caching, or reactive UI, Flow is the better choice.”
That shows you understand the trade-offs — which is what interviewers love.

