I personally found coroutines are useful only in conjunction with a library wrapping OS system calls to interact with sockets (epoll/iouring on Linux, for instance), providing an event loop, and handles the complexity of multithreading. The most fleshed out one out there is probably boost asio.
Nice to see a mirror of my experience.