> Well, that depends what you mean by "most of the time".

It means "most of the time". As in the majority of cases, in the real world, not in hypotheticals such as...

> But if you have a server that served tens-of-thousands of concurrent requests/sessions,

"If you have..." -- But I do not, that's the point. A server with tens-of-thousands of concurrent requests is the absolute exception and so not "most of the time". Most web-sites or blogs can be happy if they have a thousand visitors per day, and that's already optimistic. They could be served by hand, or even by a Rails app.

For example, I work for Wunderlist (Alexa rank ~1600). We have over 10 million users (of our API), so already an unusual high-load case, yet we get "only" on the order of 10K requests per minute. (Well, that was last summer, so more now :-) )

Considering that most requests take a couple or maybe dozens of milliseconds, the amount of actual concurrency required to handle this throughput is orders of magnitude below what you describe. In order to keep latencies down and not just throughput up, you want to up the concurrency a bit, but to nowhere near your "but if" case. And that's an app with 10 million very active users. The case you describe is simply highly atypical. That doesn't mean it never happens, it's just not very common, even on the server.

That's what I mean when I write "most of the time".

Clients, on the other hand, tend to deal at most with on the order of 100 outstanding I/O requests (that's already pushing it pretty hard). Whether you use kernel threads, user threads or another of these async mechanisms is almost entirely a matter of programmer convenience, performance will be largely indistinguishable. On the client, I have a hard time seeing your case pretty much ever.

So you have none of the clients and a tiny percentage of servers with the need for 10s of thousands of concurrent requests. The other case is what happens "most of the time". That also doesn't mean you can't use a user-thread approach in those cases, you certainly can, it's just not necessary.

---

I am not sure I am getting through to you with the UI thread. One more try: yes, I understand you can reschedule your fibers (and thus not block the UI thread). I am saying it doesn't help, because you have an actual control flow and data dependencies that are essential, they are not artifacts of technology.

Scenario: You have an iPhone app that displays flickr images. You start the app, there are no images yet, they have to be fetched. But you UICollectionView just came into focus and is asking you, the data source, for the Subviews. You know that there are 10 images, so you tell it that. It then asks you for the the visible subviews. At this point, you have to return something, because the collection view wants to display something. But you don't have the image yet, it's still in transit. Still the UI has to display something to the user. So you can return empty UIImageViews. Or you can return placeholder views.

No matter what you do, you have to do it now as the UI is being displayed, because you can't de-schedule the user that is looking at the screen.

And later, when those images do trickle in from the network connection, you have to somehow asynchronously update that UI you displayed earlier. You simply cannot do it synchronously because at the time the display is built, the data just isn't there yet.