Vec<T> in Depth

capacity()

The .capacity() method on Vec<T> returns the total number of elements of type T that the vector's current heap allocation can hold without reallocating.

Signature and Invariants

pub const fn capacity(&self) -> usize

Every Vec<T> upholds the invariant:

$$0 \le \text{v.len()} \le \text{v.capacity()}$$

  • The difference v.capacity() - v.len() is the spare capacity (uninitialized slots available for immediate .push() calls in $O(1)$ time without calling the allocator).
  • You can inspect the spare uninitialized slice directly as &mut [MaybeUninit<T>] via v.spare_capacity_mut().
|<─────────────── v.capacity() = 6 ───────────────>|
+--------+--------+--------+--------+-------+-------+
|  e[0]  |  e[1]  |  e[2]  |  e[3]  | uninit| uninit|
+--------+--------+--------+--------+-------+-------+
|<────────── v.len() = 4 ──────────>|<─ spare (2) ─>|

Observing Geometric Capacity Growth

When pushing elements one by one into an empty Vec::new(), Vec<T> jumps from 0 to a small initial capacity (4 for most types, 8 for 1-byte types) and doubles thereafter:

fn main() {
    let mut v: Vec<i32> = Vec::new();
    println!("Start: len={:>2}, cap={:>2}", v.len(), v.capacity());

    let mut last_cap = v.capacity();
    for i in 1..=17 {
        v.push(i);
        if v.capacity() != last_cap {
            last_cap = v.capacity();
            println!("At len={:>2} -> capacity grew to {:>2}", v.len(), last_cap);
        }
    }
}
Start: len= 0, cap= 0
At len= 1 -> capacity grew to  4
At len= 5 -> capacity grew to  8
At len= 9 -> capacity grew to 16
At len=17 -> capacity grew to 32

Special Case: Capacity of Zero-Sized Types (Vec<()>)

When the element type T is a Zero-Sized Type (ZST) (size_of::<T>() == 0, such as () or struct Marker;), storing elements requires 0 bytes of memory regardless of how many elements are pushed. Consequently, Vec<ZST> never allocates on the heap, and v.capacity() always returns usize::MAX:

fn main() {
    let zst_vec: Vec<()> = Vec::new();
    println!("Vec<()> capacity: {}", zst_vec.capacity());
    println!("usize::MAX:       {}", usize::MAX);
}
Vec<()> capacity: 18446744073709551615
usize::MAX:       18446744073709551615