Rust’s asynchronous system is fast, safe, and powerful—but understanding the difference between Future
and Stream
can be confusing when you’re just getting started.
In this post, we’ll break it down clearly and simply, with examples, use cases, and SEO-friendly insights that will help you write scalable async Rust applications.
What Is a Future
in Rust?
A Future
in Rust represents a single asynchronous computation that will eventually produce a single result (or error). You can think of it like a promise in JavaScript or a one-time callback.
Example of a Rust Future
async fn fetch_user_id() -> u32 {
42
}
#[tokio::main]
async fn main() {
let user_id = fetch_user_id().await;
println!("User ID: {}", user_id);
}
Here, .await
tells Rust to “pause” and wait for the future to complete.
What Is a Stream
in Rust?
A Stream
is like an async iterator — it produces multiple values over time. Think of a stream as a series of Future
s that yield values one-by-one.
Example of a Rust Stream
use tokio_stream::StreamExt;
#[tokio::main]
async fn main() {
let numbers = tokio_stream::iter(vec![1, 2, 3]);
tokio::pin!(numbers);
while let Some(num) = numbers.next().await {
println!("Received: {}", num);
}
}
Each call to .next().await
gives you one item from the stream.
Future vs Stream in Rust
Feature | Future | Stream |
---|---|---|
Yields | One value | Many values over time |
Async API | .await | .next().await |
Trait | Future | Stream (from futures crate) |
Example use | HTTP request, sleep | WebSocket, file lines, events |
Similar to | Promise or Result<T> | Iterator<Item> |
When to Use a Future
- You only need one result
- You’re performing a single async operation
Examples:
- Fetching a web page
- Writing to a file
- Connecting to a server
- Sleeping for a delay (
tokio::time::sleep
)
When to Use a Stream
Use Stream
when:
- You want to handle a sequence of async values
- Data arrives over time
- Examples:
- Receiving messages over a WebSocket
- Reading lines from a file or socket
- Handling a real-time event stream
- Streaming data from a database or API
Libraries for Async in Rust
Library | Purpose |
---|---|
tokio | Async runtime for Rust (event loop) |
tokio-stream | Stream utilities for use with Tokio |
futures | Core traits and utilities for async Rust |
async-stream | Macro-based streams (generator-like) |
Summary
Question | Future | Stream |
---|---|---|
How many values does it produce? | One | Many |
How to consume it? | .await | .next().await |
Used for | Single async result | Async sequence |
Synchronous analogy | Result<T> | Iterator<Item> |
Rust module | std::future::Future | futures::stream::Stream |