Futures that do nothing alone
In a Tokio style async runtime, an async task is a future: a value describing work that is not yet done. A future is lazy. On its own it makes no progress; something must repeatedly poll it to push it forward.
The executor and the reactor
Two cooperating parts drive futures:
- The executor owns the task queue and calls poll on ready tasks, running their code until they next await.
- The reactor watches the OS for events such as a socket becoming readable, then wakes the tasks waiting on those events.
When a future cannot progress, it returns pending and registers a waker. The reactor later fires that waker, which moves the task back to the executor's ready queue.
Why it scales
Because tasks suspend at await points instead of blocking a thread, one OS thread can interleave thousands of tasks. The runtime usually runs a small pool of worker threads, each pulling ready tasks, so the design uses every core without one thread per connection.
Key idea
An async runtime drives lazy futures with an executor that polls ready tasks and a reactor that wakes them on OS events, interleaving thousands of tasks over a few threads.