Epoll is limited to file descriptors. Kqueue also supports waiting on process events (process exit, process fork, process exec, etc), on filesystem events, and a bunch of other things. Epoll also does not support batch updates and requires multiple system calls to apply updates for multiple file descriptors, while kqueue supports batch updating
and polling in a single system call. All in all kqueue is just superior to epoll. See also
http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod for various ways in which epoll is broken (search for "The epoll mechanism deserves honorable mention as the most misdesigned of the more advanced event mechanisms")