I had the problem that some lib operations block the coroutine. This can even lead to a deadlock if coroutines waiting for each other. My solution was to use the java cached thread pool executor which dynamically adds and removes threads to the pool if needed. Try:
Executors.newCachedThreadPool().asCoroutineDispatcher()
However, this also means that it always provides a thread if needed. So you have to take care to not start too many threads in parallel…