<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/don-t-block-suspend-functions-w9mgyuf5f" -->

---
title: Don’t Block Suspend Functions | daily.dev
description: Blocking calls inside Kotlin suspend functions can silently break coroutine-based concurrency, since coroutines rely on cooperative scheduling rather than...
canonical: https://daily.dev/posts/don-t-block-suspend-functions-w9mgyuf5f
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Don’t Block Suspend Functions | daily.dev
og:description: Blocking calls inside Kotlin suspend functions can silently break coroutine-based concurrency, since coroutines rely on cooperative scheduling rather than...
og:url: https://daily.dev/posts/don-t-block-suspend-functions-w9mgyuf5f
og:image: https://api.daily.dev/og/posts/w9MGYuF5f.png
og:image:alt: Don’t Block Suspend Functions
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Don’t Block Suspend Functions

**[Square](https://daily.dev/sources/publicobject)** · 3 min read · 0 upvotes · 0 comments

## Summary

Blocking calls inside Kotlin suspend functions can silently break coroutine-based concurrency, since coroutines rely on cooperative scheduling rather than preemptive context switching used by threads. A demonstration shows swapping delay() for Thread.sleep() causes a program to hang forever because the blocking call starves other coroutines from running. The piece explains the difference between preemptive (thread) and cooperative (coroutine) concurrency models, describes a real failure scenario where a slow downstream service cascades into a full server outage, and lays out three personal rules: never call blocking functions from suspending functions, use Dispatchers.IO for blocking I/O, and avoid runBlocking().

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://publicobject.com/2026/01/22/dont-block-suspend-functions>

## Questions this post answers

### Why does my Kotlin coroutine program hang when I use Thread.sleep() instead of delay()?

Thread.sleep() blocks the underlying thread instead of suspending the coroutine, so the dispatcher cannot switch to run other coroutines waiting on that thread. In a cooperative concurrency model, a coroutine that blocks rather than suspends prevents other coroutines, including ones another job is waiting on with await(), from ever executing, causing the program to hang indefinitely.

_daily.dev surfaces practical writeups like this for developers debugging coroutine deadlocks._

### What is the difference between preemptive and cooperative concurrency models?

Preemptive concurrency, used by threads, lets the operating system forcibly take the CPU from a blocked thread and hand it to another, making context switches expensive and favoring coarse-grained concurrency. Cooperative concurrency, used by coroutines, requires each unit of work to voluntarily suspend so the dispatcher can run the next one, enabling thousands of lightweight coroutines but breaking down if any one of them blocks instead of suspending.

_developers comparing concurrency models can find deep dives like this through daily.dev._

### What rules should I follow to avoid blocking issues when writing Kotlin coroutines?

Never call a blocking function from a suspending function, use Dispatchers.IO when blocking calls are unavoidable since blocking there is acceptable, and never call runBlocking() since suspend can now be placed directly on main. Mixing blocking and suspending code is fragile because it depends on the caller's CoroutineDispatcher, and a single blocked coroutine can stall thousands of others under load.

_daily.dev helps Kotlin developers track best practices like these for reliable coroutine code._

## Similar posts on daily.dev

- [Working in Kotlin: Waiting Around with Coroutines](https://daily.dev/posts/working-in-kotlin-waiting-around-with-coroutines-vjhedyeww) · Atomic Spin · 0 upvotes · 0 comments
- [Coroutines, the Right Way: Where Your Money Code Actually Runs](https://daily.dev/posts/coroutines-the-right-way-where-your-money-code-actually-runs-hckmygkn4) · Medium · 0 upvotes · 0 comments
- [Kotlin Coroutines: Part 1 — Under the Hood](https://daily.dev/posts/kotlin-coroutines-part-1-under-the-hood-t748aplcy) · Medium · 1 upvotes · 0 comments
- [The Coroutine Secret Even 10\+ Year Android Developers Don’t Know](https://daily.dev/posts/the-coroutine-secret-even-10-year-android-developers-don-t-know-tozt1cmku) · ProAndroidDev · 4 upvotes · 0 comments

---

Tags: [#kotlin](https://daily.dev/tags/kotlin)

[View this post on daily.dev](https://daily.dev/posts/don-t-block-suspend-functions-w9mgyuf5f)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Don’t Block Suspend Functions","url":"https://daily.dev/posts/don-t-block-suspend-functions-w9mgyuf5f","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/don-t-block-suspend-functions-w9mgyuf5f"},"datePublished":"2026-08-23T12:22:05.425Z","dateModified":"2026-08-23T12:47:03.525Z","description":"Blocking calls inside Kotlin suspend functions can silently break coroutine-based concurrency, since coroutines rely on cooperative scheduling rather than...","image":"https://media.daily.dev/image/upload/s--ZrL_HSsR--/f_auto/v1722860399/public/Placeholder%2006","thumbnailUrl":"https://media.daily.dev/image/upload/s--ZrL_HSsR--/f_auto/v1722860399/public/Placeholder%2006","isAccessibleForFree":true,"articleSection":"Square","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Square","logo":"https://media.daily.dev/image/upload/s--QZPKZNBW--/f_auto,q_auto/v1787487457/logos/publicobject?_a=BAMAMicg0","url":"https://daily.dev/sources/publicobject"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/don-t-block-suspend-functions-w9mgyuf5f","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"kotlin","timeRequired":"PT3M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Square","item":"https://daily.dev/sources/publicobject"},{"@type":"ListItem","position":3,"name":"Don’t Block Suspend Functions"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/don-t-block-suspend-functions-w9mgyuf5f#faq","mainEntity":[{"@type":"Question","name":"Why does my Kotlin coroutine program hang when I use Thread.sleep() instead of delay()?","acceptedAnswer":{"@type":"Answer","text":"Thread.sleep() blocks the underlying thread instead of suspending the coroutine, so the dispatcher cannot switch to run other coroutines waiting on that thread. In a cooperative concurrency model, a coroutine that blocks rather than suspends prevents other coroutines, including ones another job is waiting on with await(), from ever executing, causing the program to hang indefinitely. daily.dev surfaces practical writeups like this for developers debugging coroutine deadlocks."}},{"@type":"Question","name":"What is the difference between preemptive and cooperative concurrency models?","acceptedAnswer":{"@type":"Answer","text":"Preemptive concurrency, used by threads, lets the operating system forcibly take the CPU from a blocked thread and hand it to another, making context switches expensive and favoring coarse-grained concurrency. Cooperative concurrency, used by coroutines, requires each unit of work to voluntarily suspend so the dispatcher can run the next one, enabling thousands of lightweight coroutines but breaking down if any one of them blocks instead of suspending. developers comparing concurrency models can find deep dives like this through daily.dev."}},{"@type":"Question","name":"What rules should I follow to avoid blocking issues when writing Kotlin coroutines?","acceptedAnswer":{"@type":"Answer","text":"Never call a blocking function from a suspending function, use Dispatchers.IO when blocking calls are unavoidable since blocking there is acceptable, and never call runBlocking() since suspend can now be placed directly on main. Mixing blocking and suspending code is fragile because it depends on the caller's CoroutineDispatcher, and a single blocked coroutine can stall thousands of others under load. daily.dev helps Kotlin developers track best practices like these for reliable coroutine code."}}]}
```

