The bytes Crate

How BytesMut and Bytes manage memory without copying

Section 1 of 8

The Problem

Why Vec<u8> copies are expensive

In Rust, the natural way to hold a buffer of bytes is Vec<u8>. It owns its memory, grows when needed, and gets freed when dropped. Simple.

But what happens when you need to split a buffer into parts, or share it across tasks?

Vec<u8> copy behavior
let data: Vec<u8> = b"Hello World".to_vec();

We have a buffer with 11 bytes of data. One allocation, no copies.

Stack
Vec<u8> data
ptr
len 11
cap 11
Heap
alloc 11 bytes
H0
e1
l2
l3
o4
5
W6
o7
r8
l9
d10
0
memcpy calls
11
bytes allocated
0
bytes duplicated

The cost of copying

Every to_vec() or clone() on a Vec<u8> triggers a heap allocation + memcpy. In network code that processes thousands of messages per second, this is a serious bottleneck. The data is already in memory -- why copy it?

Key Insight

What if multiple handles could point into the same underlying allocation, each seeing only their own slice? No copies. No extra allocations. Just pointer arithmetic and a reference count to know when to free.

That's exactly what the bytes crate does. Let's see how BytesMut works under the hood.