Ok after some more reading, I think the typical execution of an API request on a ktor server looks like this -
• ktor server creates a coroutine to handle the call
• repository layer calls a suspend func to retrieve db objects
• the coroutine is suspended (freeing server threads to do other work)
• the coroutine is resumed when the suspend func completes
However, when using a database driver that is blocking, the thread bottleneck is moved to the threadpool for I/O. Some drivers like R2DBC are non-blocking and follow a reactive pattern to solve this.
However, I'm not as concerned about the database connection pool being exhausted. As long as the server can keep accepting new requests and suspending their respective coroutines until the db eventually works its way through them all.