Still a fan of async programming, but that's a false benefit in my books :)
There's a reason that most OS native UI frameworks use some sort of event polling structure(WNDPROC[1], Looper/Handler[2], etc) because they're a nice structure for efficient handling of events. Tokio lets you do that across a diverse of events and get the same type of savings.
[1] https://en.wikipedia.org/wiki/Message_loop_in_Microsoft_Wind...
[2] https://developer.android.com/reference/android/os/Looper
Furthermore, some classes of major macro-optimizations can't be implemented effectively if you do everything with kernel threading. This is the reason most modern server software architectures tend be thread-per-core pure async with no real multithreading per se -- it is for the performance.
At a more practical engineering level, these architectures are not more complicated, just different. Some things are much simpler to design because most multithread coordination problems go away. It is nice to be able to write virtually all of your code in single-threaded style where you don't have to worry about locking and consistency, especially as concurrency increases. On the other hand, you have to learn how to design schedules because the OS will no longer be doing that (poorly) for you. It isn't free in that you have to develop expertise in things you may not know but it is often worth it.