list capacity
default size
list data structure
programming
computer science

Default Capacity of List

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

When developers ask about the default capacity of List, they are usually talking about C# List<T>, not a generic concept across every language. In .NET, capacity is the size of the internal array backing the list, and it is different from Count, which is the number of elements actually stored.

The Default Capacity in List<T>

For an empty List<T> created with the parameterless constructor, the initial capacity is 0.

csharp
1using System;
2using System.Collections.Generic;
3
4var numbers = new List<int>();
5Console.WriteLine(numbers.Count);     // 0
6Console.WriteLine(numbers.Capacity);  // 0

That often surprises people who expect an immediate allocation of 4, 8, or 16 slots. In current .NET implementations, the list starts with an empty shared array and allocates storage when the first element is added.

What Happens After the First Add

Once you add the first item, List<T> grows its internal storage. A common observed behavior is that capacity jumps to 4, then grows roughly by doubling as needed.

csharp
1var numbers = new List<int>();
2for (int i = 1; i <= 10; i++)
3{
4    numbers.Add(i);
5    Console.WriteLine($"Count={numbers.Count}, Capacity={numbers.Capacity}");
6}

You will typically see capacity grow like this:

  • '0 before any add'
  • '4 after the first allocation'
  • '8'
  • '16'
  • and so on

The exact growth policy is an implementation detail, so you should rely on the fact that capacity grows automatically, not on a specific sequence beyond current runtime behavior.

Capacity Versus Count

This distinction is essential:

  • 'Count is how many elements the list currently holds'
  • 'Capacity is how many elements it can hold before resizing'

A list can have Count = 3 and Capacity = 8. That just means five more elements can be added before another reallocation is needed.

Why Capacity Matters

Resizing a list is not free. When the internal array fills up, the runtime allocates a larger array and copies the existing items into it.

That cost is amortized, which is why Add is still effectively O(1) on average. But if you already know the approximate size of the list, preallocating can reduce copying and improve performance.

csharp
var numbers = new List<int>(1000);
Console.WriteLine(numbers.Capacity);  // 1000

This is useful in hot loops, parsers, batch imports, and other allocation-sensitive paths.

Trimming Excess Capacity

If a list temporarily grew large and now holds far fewer elements, you can shrink the backing array.

csharp
1var items = new List<int>(1000);
2items.AddRange(new[] { 1, 2, 3, 4, 5 });
3items.TrimExcess();
4Console.WriteLine(items.Capacity);

TrimExcess() is helpful when you want to reduce memory footprint after bulk loading.

When Not to Worry About It

For ordinary application code, the default capacity behavior is usually fine. List<T> is designed to grow efficiently without manual tuning.

Only optimize capacity when:

  • profiling shows allocation or copying overhead matters
  • the list size is known in advance
  • you are constructing many large lists repeatedly

Otherwise, readability matters more than micro-managing internal array growth.

A Small Benchmark Pattern

If you want to evaluate whether preallocation helps in your case, compare both versions under realistic workload.

csharp
var a = new List<int>();
var b = new List<int>(100000);

Then fill them the same way and measure allocations or elapsed time with a profiler or BenchmarkDotNet.

Common Pitfalls

A common mistake is assuming default capacity and default count are the same thing. They are not.

Another mistake is relying on a specific growth sequence as if it were part of the public contract. The important guarantee is automatic growth, not the exact multiplier.

Developers also sometimes preallocate huge capacities everywhere "just in case," which can waste memory instead of saving time.

Summary

  • In C# List<T>, the default capacity of a new empty list is 0.
  • Capacity increases automatically when elements are added.
  • 'Count is the number of stored items; Capacity is the size of the backing array.'
  • Preallocating capacity helps when you know list size ahead of time.
  • Treat the exact growth pattern as an implementation detail, not a hard API guarantee.

Course illustration
Course illustration

All Rights Reserved.