Computer Science Fundamentals · Foundations

Space Complexity

Want it in plain words first? Jump to Eli explains — the same idea, no jargon.
On this page 9 sections
  1. In 30 seconds
  2. Why this matters
  3. The college version
  4. Eli explains
  5. Worked example
  6. Key takeaway
  7. Quick check
  8. Study tools
  9. Sources & references

In 30 seconds

measures how much memory an algorithm needs as its input grows, written in Big-O just like running time. The number that usually matters is : the extra working memory beyond the input itself. An uses only O(1) auxiliary space; copying data into a new array costs O(n); and each pending recursive call adds a frame to the , so recursion to depth d costs O(d) stack space.

Why this matters

Memory is finite, and an algorithm that looks fast on paper can still fail if it needs more working memory than the machine has. Choosing an in-place method can be the difference between processing a large dataset and running out of memory. Space analysis also exposes hidden costs: a recursive routine that seems lightweight can exhaust the call stack and crash the program. And because memory and time can often be traded against each other, reasoning about space lets you decide when spending extra memory to save time is worth it and when it is not. These judgments recur throughout data structures, systems programming, and algorithm design.

The college version

What space complexity measures

Space complexity describes how the memory an algorithm needs grows as a function of the input size, usually written n. It is expressed in , the same asymptotic upper bound used for running time; the time-complexity topic owns how that notation works, so here the focus is strictly on memory. NIST's Dictionary of Algorithms and Data Structures defines complexity broadly as the minimum resources needed to solve a problem, and explicitly lists memory alongside time as one of those resources, so Big-O applies to space just as naturally as it does to speed.

has two parts: the input space (the memory already occupied by the data you were handed) plus the auxiliary space (any extra working memory the algorithm allocates while it runs). Because every algorithm must at least hold its input, the input term is often the same across competing methods and tells you little about which is more efficient. So when people compare algorithms by 'space,' they almost always mean auxiliary space: the extra beyond the input. An algorithm that reads a list of n numbers and keeps just a running total uses O(1) auxiliary space, even though the input itself occupies O(n).

In-place algorithms and O(1) auxiliary space

An in-place algorithm transforms its input using only a constant amount of auxiliary memory, no matter how large the input is. NIST describes an in-place sort as one in which the sorted items occupy the same storage as the original ones, keeping at most a constant number of items in auxiliary memory at any time. Reversing an array by swapping the two ends and working inward is the canonical example: it needs only a couple of index variables and one temporary slot for each swap, so its auxiliary space is O(1) regardless of length.

The contrast is an approach that builds a brand-new structure. Reversing by copying elements into a freshly allocated array of the same length uses O(n) auxiliary space, because the extra memory grows in step with the input. Both versions are O(n) in time, but they differ sharply in memory, and on a large or memory-constrained input that difference decides whether the program completes. In-place methods trade a little algorithmic convenience for a large saving in memory; the cost is that they overwrite (mutate) the original data, which is not always acceptable.

Common space costs and recursion

A few patterns cover most cases. O(1) auxiliary space means a fixed handful of variables whose count does not depend on n. O(n) auxiliary space means allocating a copy, a lookup table, or another structure that scales with the input. Recursion introduces a subtler cost. Each call that has not yet returned occupies a frame on the call stack, storing that call's local variables and the address to return to. A recursion that reaches depth d therefore holds up to d frames at once, giving O(d) auxiliary space even if each individual call does almost nothing. For a simple linear recursion over n items, d is proportional to n, so the stack cost is O(n).

This space is real and bounded. Python, for instance, caps the interpreter stack; its documentation notes the limit exists to prevent infinite recursion from overflowing the underlying C stack and crashing the interpreter. Exceed it and the program raises a RecursionError rather than silently corrupting memory. An iterative loop over the same data usually keeps only a few variables, so converting deep recursion to iteration is a standard way to cut O(n) stack space down to O(1).

The time-space trade-off

Time and space are often exchangeable, and recognizing the trade-off is a core design skill. Spending memory can buy speed: to test whether any two values in a list add up to a target, storing the values already seen in a hash set uses O(n) auxiliary space but finishes in about O(n) time, whereas a nested-loop scan uses O(1) auxiliary space but takes O(n squared) time. Lookup tables, caches, and precomputed indexes all follow the same logic, trading memory to avoid repeated work. The trade also runs the other way: an in-place algorithm gives up scratch space to stay within a tight memory budget, sometimes accepting more complex logic or a constant-factor slowdown in return. There is no universally correct choice. The right decision depends on which resource is scarce for your problem: the size of the data, the memory available on the target machine, and how often the operation runs. Analyzing both dimensions, rather than time alone, is what lets you make that call deliberately instead of by accident.

Eli, the EliExplains learning guide

Eli explains

The same idea, in plain words

Explain it like I’m 10

Space complexity asks a simple question: as the pile of data gets bigger, how much extra scratch space does your method need? Some methods need only a tiny fixed amount of scratch space no matter how big the pile gets, so we call that O(1). Others need a second pile just as big as the first, which is O(n). And when a method calls itself over and over before finishing, every unfinished call has to be remembered on a stack, so a chain that goes d deep needs room to remember d things at once.

Picture it like this

Think of solving a jigsaw puzzle on a table. The finished picture is the input. Working in-place is rearranging pieces right on top of the picture area, needing almost no extra table. Making a copy is clearing a whole second table the same size to build the answer separately. Deep recursion is like pausing puzzle A to start puzzle B, then pausing B for C: every paused puzzle stays spread out on its own table until you come back, so the tables pile up with the depth.

Where the picture stops working

The tables are discrete and equal-sized, but real memory is measured in bytes and grows smoothly; auxiliary space can be any function of n, not just 'one more table.' And a paused puzzle physically occupies a table, whereas a paused function call stores only a small frame of variables, which is usually far less memory than a full copy of the data.

Worked example

Reverse an array of n integers two ways. In-place: set i to the front and j to the back, swap the elements at i and j using one temporary variable, then step i forward and j backward until they meet. This touches every element once (O(n) time) but only ever holds two indices and one temporary, so its auxiliary space is O(1). Copy: allocate a new array of length n and fill position k with the element from the far end, leaving the original untouched. This is also O(n) time, but the new array grows with the input, so its auxiliary space is O(n). Measuring peak extra memory confirms it: the in-place version held a constant amount (about 84 bytes) at n = 1,000, 10,000, and 100,000, while the copy version rose from roughly 8 KB to 80 KB to 800 KB, scaling linearly with n. Same time bound, very different memory.

Key takeaway

Space complexity is the Big-O growth of an algorithm's memory use, and the figure that usually matters is auxiliary space, the extra beyond the input: O(1) for in-place work, O(n) for a copy or table, and O(depth) for a recursive call stack, with time often exchangeable for space.

Quick check

3 questions here, of 5 in this lesson’s practice set. Answers stay hidden until you check.

Question 1 of 3foundational

In Big-O terms, an algorithm's space complexity describes:

Choose an answer, then check it.
Question 2 of 3intermediate

When algorithms are compared by 'space,' the figure usually meant is auxiliary space, which is:

Choose an answer, then check it.
Question 3 of 3intermediate

Reversing an array by swapping elements from both ends inward, using two index variables and one temporary, has an auxiliary space complexity of:

Choose an answer, then check it.
Practice all 5

Keep learning

Ready to build on this? Continue to the next lesson.

Practice this lesson
Study tools & related lessonsYou’ll learn to · Common mistakes · Easily confused · Key vocabulary · Related

You’ll learn to

  • Define space complexity and express it in Big-O notation.
  • Distinguish auxiliary space from total space, and identify what counts as the input.
  • Explain why an in-place algorithm uses O(1) auxiliary space.
  • Analyze the call-stack space of a recursive algorithm as O(depth).
  • Evaluate a time-space trade-off and decide when spending memory to save time is justified.

Common mistakes

  • Assuming a good time complexity implies a good space complexity.

    They are independent. Merge sort is O(n log n) in time but needs O(n) auxiliary space, while an in-place sort with the same or worse time can use O(1). Analyze memory separately.

  • Counting the input array as auxiliary space.

    Auxiliary space is the extra memory beyond the input. An algorithm that only scans an existing n-element array while keeping a few variables uses O(1) auxiliary space, not O(n).

  • Believing recursion is free because it uses no explicit extra variables.

    Each pending recursive call occupies a call-stack frame. Recursion to depth d costs O(d) auxiliary space and can overflow the stack, raising an error, if the depth is too large.

  • Treating 'in-place' as meaning 'no extra memory at all.'

    In-place means a constant amount, O(1), of auxiliary memory, such as a few index variables and a temporary for swapping, not literally zero extra memory.

  • Assuming more memory always makes an algorithm slower.

    Often the opposite: a lookup table or hash set spends O(n) memory to cut running time. That deliberate exchange is the time-space trade-off.

Easily confused

Auxiliary space vs. Total space

Auxiliary space counts only the extra working memory beyond the input; total space adds the input space. Comparisons of algorithms usually use auxiliary space because the input term is shared.

In-place reverse (O(1) auxiliary) vs. Copy-into-new-array reverse (O(n) auxiliary)

Both take O(n) time, but the in-place version holds a constant few variables while the copy allocates a second array that grows with n. The copy preserves the original; the in-place version overwrites it.

Recursive traversal (O(depth) stack space) vs. Iterative loop (O(1) space)

The recursive version keeps one call-stack frame per pending call, costing O(depth); an equivalent loop keeps a few variables, costing O(1). Converting recursion to iteration is a common way to reduce stack space.

Key vocabulary

Space complexity
A measure of how much memory an algorithm requires as a function of its input size n, expressed as an asymptotic upper bound in Big-O notation.
Auxiliary space
The extra working memory an algorithm allocates while it runs, not counting the memory already occupied by the input.
Total space
The full memory footprint of an algorithm: the input space plus the auxiliary space.
In-place algorithm
An algorithm that transforms its input using only a constant amount of auxiliary memory, O(1), independent of input size.
Call stack
A region of memory holding one frame for each function call that has started but not yet returned, storing that call's local variables and return address.
Recursion depth
The maximum number of recursive calls that are simultaneously active before the base case is reached and calls begin returning.
Time-space trade-off
The design choice of using more memory to reduce running time, or accepting more running time to reduce memory use.
Big-O notation
An asymptotic upper bound describing how a resource, such as memory or time, grows as the input size grows.

Sources & references

  1. complexity — Dictionary of Algorithms and Data Structures (DADS) — U.S. National Institute of Standards and Technology (NIST)
  2. big-O notation - Dictionary of Algorithms and Data Structures (DADS) — National Institute of Standards and Technology (NIST)
  3. in-place sort — Dictionary of Algorithms and Data Structures (DADS) — U.S. National Institute of Standards and Technology (NIST)
  4. array — Dictionary of Algorithms and Data Structures (DADS) — U.S. National Institute of Standards and Technology (NIST)
  5. sys.setrecursionlimit / sys.getrecursionlimit — Python 3 Standard Library documentation — Python Software Foundation
  6. Space complexity — Wikipedia — Wikimedia Foundation

EliExplains lessons are original prose written from the open, credible references above. See Copyright & Licensing.

Researched 2026-08-19

Educational content only. It is not medical, legal or professional advice. Found an error? Tell us.