C#
Stack Capacity
Programming
Data Structures
Memory Management

Stack capacity in C

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Despite the title, this topic is really about Stack<T> in C#, not the call stack in the C language. For System.Collections.Generic.Stack<T>, capacity means the size of the internal storage array before the stack needs to grow, and understanding that matters when you push many items or want to reduce reallocations.

Stack<T> Grows Automatically

A Stack<T> does not have a fixed capacity limit unless you run out of memory. It resizes its internal storage as needed when you push more elements.

csharp
1using System;
2using System.Collections.Generic;
3
4class Program
5{
6    static void Main()
7    {
8        var stack = new Stack<int>();
9        stack.Push(1);
10        stack.Push(2);
11        stack.Push(3);
12
13        Console.WriteLine(stack.Count);
14    }
15}

From a correctness perspective, this is convenient. From a performance perspective, repeated growth can mean repeated allocations and copies.

Set an Initial Capacity When You Know the Size

If you have a rough idea how many items the stack will hold, give it an initial capacity to reduce resize churn.

csharp
using System.Collections.Generic;

var stack = new Stack<int>(capacity: 10_000);

This does not populate the stack with items. It only reserves enough internal storage to hold that many pushes before another resize is needed.

This is useful in algorithms such as:

  • depth-first search
  • expression evaluation
  • parser backtracking
  • custom traversal logic

where the stack size may be predictable.

Count Is Not the Same as Capacity

Count tells you how many elements are currently in the stack. Capacity is about how much internal space is available before resizing.

csharp
1using System;
2using System.Collections.Generic;
3
4var stack = new Stack<string>(100);
5stack.Push("A");
6stack.Push("B");
7
8Console.WriteLine(stack.Count); // 2

There is no public Capacity property on Stack<T> like there is on List<T>, so you typically control capacity only through the constructor and cleanup helpers such as TrimExcess.

Use TrimExcess When a Large Stack Shrinks Permanently

If the stack once grew large and will now stay much smaller, TrimExcess can reduce its internal memory footprint.

csharp
1using System.Collections.Generic;
2
3var stack = new Stack<int>(1000);
4for (int i = 0; i < 1000; i++)
5{
6    stack.Push(i);
7}
8
9for (int i = 0; i < 990; i++)
10{
11    stack.Pop();
12}
13
14stack.TrimExcess();

This is useful when a temporary spike created a much larger internal buffer than the steady-state workload really needs.

Do not overuse it in hot paths. Trimming and then regrowing repeatedly can create the same churn you were trying to avoid.

Think About Algorithmic Intent

If you are asking about stack capacity because an algorithm pushes large amounts of data, the deeper question may be whether the data structure is the right one. For example:

  • a queue may fit the access pattern better
  • recursion may be causing call-stack growth instead of Stack<T> growth
  • a streaming algorithm may avoid storing everything at once

So while initial capacity tuning helps, it should come after the broader algorithm choice is already sound.

Common Pitfalls

  • Confusing Stack<T> capacity with the process call stack leads to the wrong kind of performance discussion.
  • Expecting a fixed hard capacity limit misunderstands how Stack<T> dynamically resizes.
  • Ignoring initial capacity in large known workloads can create avoidable allocation and copy overhead.
  • Calling TrimExcess aggressively in frequently changing workloads can produce unnecessary churn.
  • Using Count as if it described reserved storage rather than actual element count mixes two different concepts.

Summary

  • 'Stack<T> in C# grows dynamically as you push more items.'
  • Capacity is internal storage size, while Count is the number of actual elements.
  • Use the constructor with an initial capacity when the expected stack size is known.
  • Use TrimExcess only when a large temporary stack should shrink for the long term.
  • Optimize stack capacity only after confirming the overall algorithm and data structure choice make sense.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.