모든 스레드에는 고정된 메모리로서 자체 호출 스택이 있다. 전통적으로 스택은 프로세스 메모리 공간에서 위에서 아래로 늘어나며, 맨 위는 메모리 공간의 끝을 의미하고 맨 아래는 누구나 아는 널 포인터(null pointer), 주소 0을 의미한다. 항목을 호출 스택에 푸시하는 것은 항목을 거기에 놓고 스택 포인터를 줄이는 것을 의미한다.
모든 좋은 것이 그렇듯, 스택에도 끝이 있다. 크기가 고정되며, 크기를 초과하면 CPU가 StackOverflowException을 발생시킨다. 일을 하다 보면 자기가 만든 함수를 호출할 때 자주 만나게 될 것이다. 스택은 꽤 크기 때문에 일반적인 경우, 한계까지 도달할 염려가 없다.
호출 스택은 반환 주소뿐만 아니라 함수의 매개변수와 로컬 변수도 포함한다. 로컬 변수는 메모리를 거의 차지하지 않으므로 할당 및 할당 해제와 같은 추가적인 메모리 관리 단계가 필요하지 않다. 따라서 스택을 사용하는 것이 매우 효율적이다. 스택은 빠르지만 크기가 고정되고, 사용하는 함수와 그 수명이 같다. 함수를 반환할 때 스택 공간이 반환된다. 그렇기 때문에 소량의 로컬 데이터를 저장하는 것이 이상적이다. 따라서 C#이나 자바와 같은 관리되는 런타임은 클래스 데이터를 스택에 저장하지 않고 대신 참조만 저장한다.
이것이 바로 특정 경우에 값 타입이 참조 타입보다 더 나은 성능을 가질 수 있는 또 다른 이유다. 값 타입은 복사로 전달되지만 로컬로 선언된 경우에만 스택에 존재한다.