Prerequisites
Before starting, make sure you have:- Rust 1.71 or later installed
- Basic familiarity with Rust syntax
- Tokio added to your project (see Installation)
Hello, async world
Let’s start with the simplest possible Tokio program:1
The #[tokio::main] macro
The
#[tokio::main] macro sets up the async runtime and allows your main function to be async. This is the entry point for all Tokio applications.2
Async/await syntax
The
await keyword pauses execution until an async operation completes. Operations like connect() and write_all() return futures that must be awaited.3
Asynchronous I/O
TcpStream is Tokio’s non-blocking TCP socket. All I/O operations are asynchronous and won’t block other tasks.Building a TCP echo server
Now let’s build something more practical: a TCP echo server that handles multiple concurrent connections.Accepting connections
accept() call waits asynchronously for a new connection.
Spawning tasks
tokio::spawn function creates a new task that runs concurrently on the Tokio runtime. This allows the server to handle multiple clients simultaneously without blocking.
Each spawned task is lightweight (only a few hundred bytes) and can run on any thread in the runtime’s thread pool.
Reading and writing
Testing the server
1
Run the server
2
Connect with telnet
In another terminal:
3
Send messages
Type any message and press Enter. The server will echo it back to you.
Working with channels
Tokio provides several channel types for communication between tasks. Here’s an example using thempsc (multi-producer, single-consumer) channel:
- Sending messages between tasks
- Coordinating work across multiple async operations
- Implementing producer-consumer patterns
oneshot
Single-value channel for sending one message
mpsc
Multi-producer, single-consumer channel
broadcast
Multi-producer, multi-consumer with message cloning
Timeouts and intervals
Tokio’stime module provides utilities for working with time:
Timeouts
Intervals
Common patterns
Handling blocking operations
Sometimes you need to run CPU-intensive or blocking code. Usespawn_blocking to avoid blocking the async runtime:
Graceful shutdown
Usetokio::select! to handle cancellation and graceful shutdown:
Next steps
You now have the fundamentals to build async applications with Tokio. Here are some resources to continue learning:API documentation
Complete API reference with detailed examples
Tokio tutorial
In-depth guide covering advanced topics
Examples
Real-world examples from the Tokio repository
Discord community
Get help and connect with other Tokio users
Key takeaways
- Use
#[tokio::main]to set up the async runtime - Spawn tasks with
tokio::spawnfor concurrent execution - Use async I/O operations instead of blocking ones
- Leverage channels for task communication
- Use
spawn_blockingfor CPU-intensive work - Handle graceful shutdown with
tokio::select!