Why didn't you use the multithreaded executor from Tokio?
(Your response isn't entirely accurate though: it's using a thread pool whose size is configurable, not one thread per spaw_blocking)
I don't understand why some people think async is difficult to write. It's difficult if language doesn't have good support for it, but rust does. I remember async ruby was pretty weird to write initially.