epoll and kqueue are readiness models, and IOCP is a completion model. What's the actual difference, and where does it show up in how Node scales?
Can explain readiness versus completion at the syscall level, then work out Node's connection-scaling profile straight from that model
So with a readiness model like epoll or kqueue, you register interest in a set of file descriptors and the kernel tells you which ones are ready to read or write, and then the application does the actual read or write itself. With a completion model like IOCP on Windows, you submit the operation up front, you hand the kernel a buffer to read into, and it notifies you once the operation has finished. Node hides both of these behind libuv, so your JavaScript sees the same callback API on every platform. The scaling result is that one thread can watch huge numbers of connections, because it never blocks on any single socket. It makes one call that comes back with whichever sockets need attention. That's basically what made the single-threaded event loop workable for the C10K problem that thread-per-connection servers struggled with.