The main benefit of having async (or Go-style M:N scheduling) is that you can afford to launch as many tasks/fibers/goroutines/... as you want, as long as you have RAM. If you're using OS threads, you need to pool them responsively to avoid choking your CPU with context-switches, running out of OS threads, running out of RAM, etc. – hardly impossible, but if you're doing more than just I/O, you can run into interesting deadlocks.