The Event Loop + The Two Kitchens Dispatched while code runs. Cooked on the kitchen's own clock. Collected only here, at poll. Between every callback: drain nextTick, then Promise queue (repeat until both are empty) Not tied to any one phase — not animated here. 1 Timers sticky notes — fire when due 2 Pending Callbacks rare, housekeeping 3 Idle / Prepare internal to libuv 4 Poll the only gate to both kitchens 5 Check setImmediate callbacks 6 Close Callbacks cleanup, socket close out: dispatched during any callback in: collected only here, at poll Kitchen One the order board (OS sockets, epoll) network calls — HTTP, Postgres, fetch, Redis active: 0 No threads — waiting costs nothing. Kitchen Two four chefs (libuv thread pool) fs.*, dns.lookup, crypto, zlib (gzip, deflate...) chefs busy: 0/4 · queue: 0 Pool size 4 by default. Why timing here matters Both kitchens finish work on their own schedule — the loop doesn't wait for either. But results only get handed back to your code when the loop's circuit reaches poll. A busy loop delays every callback — even ones whose work finished long ago.
Normal traffic — everything on its own clock
the loop keeps circling · kitchens handle a few requests
red dot = the JS thread  ·  teal/amber = requests waiting on a kitchen  ·  poll flashes on delivery  ·  Step ▶ jumps to the next event