Socket per Thread in Tokio

tokio::spawn does not create a thread; it creates a Tokio task, which is a co-operatively scheduled entity that Tokio knows how to schedule on the Tokio runtime (in turn, the Tokio runtime can have as many worker threads as you want - from 1 upwards).

By using tokio::spawn, you allow the Tokio runtime to switch to another task at points in the task where it has a .await, and only those points. Your alternative, if you don't want multiple tasks, is to use things like select!, join! and functions with select or join in their name to have concurrent I/O in a single task.

The point of spawning in Tokio is twofold:

  1. If your runtime has multiple threads, then two tasks can execute in parallel on different threads, reducing latency.
  2. It is almost always easier to understand a complex program in terms of different tasks doing their work, than in terms of a single large task doing lots of work concurrently (e.g. using select to wait for one of many options, or join to wait for all options to finish).