Runtime Configuration
Worker Threads
By default, Tokio spawns one worker thread per CPU core. You can customize this:Choosing the Right Scheduler
Current-Thread Scheduler
Single-threaded, runs all tasks on the current thread:- You have a small number of tasks
- Tasks are primarily I/O-bound
- You want minimal overhead
- Your application is single-threaded
Multi-Thread Scheduler
Work-stealing scheduler that distributes tasks across multiple threads:- You have many concurrent tasks
- You want to utilize multiple CPU cores
- Tasks have varying execution times
- Building a high-throughput server
The multi-thread scheduler is required for
block_in_place. The current-thread scheduler will panic if you call block_in_place.Task Spawning Optimization
Minimize Task Creation Overhead
Spawning tasks has overhead. Batch operations when possible:Use spawn_local for !Send Types
When tasks don’t need to move between threads:
I/O Optimization
Buffer Sizes
Use appropriate buffer sizes for your workload:Vectored I/O
Use vectored I/O for scatter/gather operations:Split Sockets
Split sockets for concurrent reads and writes:Channel Selection and Tuning
Choosing the Right Channel
Bounded vs Unbounded Channels
Channel Capacity Sizing
Blocking Operations
Thread Pool Configuration
Configure the blocking thread pool size:Blocking threads are spawned on-demand and kept alive for the configured duration when idle.
Limit Concurrent Blocking Operations
Use a semaphore to limit concurrent blocking operations:Consider Dedicated Thread Pools
For CPU-bound work, use a dedicated thread pool like rayon:Memory Management
Reuse Buffers
Use object pools for frequently allocated buffers:Use bytes Crate
The bytes crate provides efficient buffer types:
Time and Timers
Batch Timers
Avoid creating too many individual timers:Timer Resolution
Tokio’s timer resolution is typically 1ms:Monitoring and Metrics
Enable Runtime Metrics
Poll Count Histogram (Unstable)
.cargo/config.toml
Event Loop Configuration
Event Interval
Control how often I/O events are processed:Lower values increase responsiveness but may reduce throughput. Higher values batch more work but increase latency.
Global Queue Interval
Control work-stealing behavior:Profiling and Debugging
Using tokio-console
Enable console subscriber for task debugging:
Cargo.toml
tokio-console to visualize task execution.
Trace Events (Unstable)
Cargo.toml
.cargo/config.toml
Performance Checklist
- Use the multi-thread scheduler for high-throughput applications
- Configure appropriate buffer sizes (4-64 KB)
- Use bounded channels with appropriate capacity
- Limit concurrent blocking operations with semaphores
- Reuse buffers instead of allocating new ones
- Use
spawn_blockingfor blocking I/O, not CPU-bound work - Consider dedicated thread pools (rayon) for CPU-intensive tasks
- Batch timer operations with
interval - Profile with
tokio-consoleto identify bottlenecks - Use
bytescrate for efficient buffer management - Split sockets for concurrent read/write operations
- Apply backpressure with bounded channels and semaphores