I'll give you a real world example. I wrote some code that listened to a websockets URL from thousands of Reddit posts - specifically, the one that sends new messages on new comments - so I could see a stream of Reddit comments for any given sub.
Implemented it using Tungstenite (synchronous) and it created thousands of threads to listen, and used enormous chunks of memory (several GB) for the stack space + memory reading for every single WS stream.
Implemented it using Tokio_tungstenite, the async alternative, and it used a handful of MB of memory and barely any CPU to listen to thousands of WS servers.
If I were using the author's library, I would call `.some_endpoint(...)` and that would return a `SpotifyResult<String>`, so I'm struggling to understand why `some_endpoint` is async. I could see if two different threads were calling `some_endpoint` then awaiting would allow them to both use resources, but if you're running two threads, doesn't that already accomplish the same thing? I'm pretty naive to concurrency.