# absl::InlinedVector Size Limits: Inline Capacity vs. Maximum Size Explained

> Understand absl::InlinedVector size limits. Learn how inline capacity triggers heap allocation and how exceeding maximum size throws std::length_error. Optimize your C++ code with Abseil.

- Repository: [Abseil/abseil-cpp](https://github.com/abseil/abseil-cpp)
- Tags: deep-dive
- Published: 2026-07-11

---

**`absl::InlinedVector` enforces two distinct size limits: an inline capacity `N` that stores elements in an embedded buffer without heap allocation, and a hard maximum size bounded by allocator limits and `size_type` constraints, with exceeding the former triggering automatic heap allocation and the latter throwing `std::length_error`.**

The `absl::InlinedVector` container in Google's Abseil C++ library provides a hybrid storage model that balances stack performance with heap flexibility. Understanding its size limits is crucial for performance-sensitive applications that rely on this optimization. This article examines the exact boundaries defined in the Abseil source code and the precise behavior when those boundaries are crossed.

## The Two Size Limits of absl::InlinedVector

According to the Abseil C++ implementation, `absl::InlinedVector<T, N, A>` maintains two distinct capacity boundaries that govern its storage lifecycle.

### Inline Capacity (N)

The **inline capacity** represents the number of elements that can be stored in the object's embedded buffer without any heap allocation. This value is computed as `static_cast<size_type>(kOptimalInlinedSize)` inside `Storage::GetInlinedCapacity()`, with the implementation defined in [`absl/container/internal/inlined_vector.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/container/internal/inlined_vector.h) at lines 408-412.

### Maximum Size (max_size())

The **maximum size** is the absolute upper bound on element count, calculated as the smaller of the allocator's `max_size()` and half of `std::numeric_limits<size_type>::max()`. This is implemented in `InlinedVector::max_size()` within [`absl/container/inlined_vector.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/container/inlined_vector.h) (lines 28-34).

## What Happens When Inline Capacity Is Exceeded

When `size()` exceeds the inline capacity `N`, the vector automatically transitions from embedded storage to heap allocation.

In [`absl/container/internal/inlined_vector.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/container/internal/inlined_vector.h) around line 180, the `Storage::Initialize` routine checks `if (new_size > GetInlinedCapacity())`. When this condition triggers:

- The allocator invokes `MallocAdapter::Allocate` to create a new buffer sized via `ComputeCapacity`
- Existing elements are **moved** (or copied if necessary) into the newly allocated storage
- The internal flag `GetIsAllocated()` is set to true
- Subsequent operations behave exactly like `std::vector`

This transition causes a **single allocation**, after which the container operates as a standard dynamic array.

## What Happens When Maximum Size Is Exceeded

Every mutating operation that increases element count validates against `max_size()` using `ABSL_PREDICT_FALSE` guards. If the requested size exceeds the maximum, the library calls `ThrowStdLengthError`, which throws a `std::length_error` with a descriptive message.

Key locations in [`absl/container/inlined_vector.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/container/inlined_vector.h):

- Constructor at line 38: `if (ABSL_PREDICT_FALSE(n > max_size()))`
- `assign`, `resize`, `reserve`, `emplace_back`, and `push_back` use identical guards
- `insert` validates with `if (ABSL_PREDICT_FALSE(s > max_size() - size()))`

Unlike undefined behavior in raw arrays, exceeding the maximum size results in a **catchable exception** with a message like "InlinedVector::reserve failed length check".

## Practical Code Example

```cpp
#include "absl/container/inlined_vector.h"
#include <iostream>

int main() {
  // Inline capacity is 4. No heap allocation occurs.
  absl::InlinedVector<int, 4> v;
  for (int i = 0; i < 4; ++i) v.push_back(i);
  std::cout << "size = " << v.size()
            << ", capacity = " << v.capacity() << '\n';   // → 4 / 4

  // Exceed the inline capacity → heap allocation.
  v.push_back(42);
  std::cout << "size = " << v.size()
            << ", capacity = " << v.capacity() << '\n';   // → 5 / >4

  // Exceed the absolute maximum size → throws.
  try {
    v.reserve(v.max_size() + 1);
  } catch (const std::length_error& e) {
    std::cout << "Caught exception: " << e.what() << '\n';
  }
}

```

Output:

```

size = 4, capacity = 4
size = 5, capacity = 8
Caught exception: InlinedVector::reserve failed length check

```

## Summary

- **Inline capacity** (`N`) is determined by `kOptimalInlinedSize` in `Storage::GetInlinedCapacity()` and triggers a single heap allocation when exceeded
- **Maximum size** is bounded by the allocator and `size_type` limits, enforced by `ABSL_PREDICT_FALSE` guards in `max_size()`
- Exceeding inline capacity causes automatic transition to heap storage via `MallocAdapter::Allocate` in `Storage::Initialize`
- Exceeding maximum size throws `std::length_error` via `ThrowStdLengthError` rather than causing undefined behavior
- All guards are located in [`absl/container/inlined_vector.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/container/inlined_vector.h) with storage logic in [`absl/container/internal/inlined_vector.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/container/internal/inlined_vector.h)

## Frequently Asked Questions

### What is the default inline capacity for absl::InlinedVector?

The default inline capacity is specified by the template parameter `N`, which is passed to `Storage::GetInlinedCapacity()` and computed as `static_cast<size_type>(kOptimalInlinedSize)`. This value is typically optimized for cache line alignment and stored in the internal header at [`absl/container/internal/inlined_vector.h`](https://github.com/abseil/abseil-cpp/blob/main/absl/container/internal/inlined_vector.h) (lines 408-412).

### Does absl::InlinedVector throw exceptions when resizing?

Yes, when the requested size exceeds `max_size()`, the container throws `std::length_error` through the `ThrowStdLengthError` mechanism. This occurs in constructors, `reserve`, `resize`, `insert`, and other growth operations, providing safety bounds checking that raw arrays lack.

### Can I check if absl::InlinedVector has moved to heap storage?

Yes, you can indirectly detect this by comparing `capacity()` against the template parameter `N`. Once `capacity()` exceeds `N`, the vector has transitioned to heap allocation managed by `MallocAdapter::Allocate`, though the public API does not expose the `GetIsAllocated()` flag directly.

### Is there a performance penalty when exceeding inline capacity?

The transition incurs a single allocation cost and element-move overhead when switching from the embedded buffer to heap storage. After this transition, performance characteristics match those of `std::vector`, as subsequent operations work on the heap-allocated buffer referenced by the `Storage` implementation.