Python
object size
memory management
sys module
programming tips

How do I determine the size of an object in Python?

Master System Design with Codemia

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

Introduction

In Python, "size of an object" can mean at least two different things: the shallow size of the object itself, or the total memory consumed by the object plus everything it refers to. The built-in answer is sys.getsizeof(), but that only tells part of the story. To measure memory accurately, you need to choose the right level of detail for the question you are asking.

Use sys.getsizeof() for Shallow Size

The standard starting point is sys.getsizeof().

python
1import sys
2
3number = 42
4items = [1, 2, 3]
5
6print(sys.getsizeof(number))
7print(sys.getsizeof(items))

This reports the memory footprint of the object itself in bytes. For a list, that includes the list container, not the full size of the elements stored inside it.

That distinction is why this result often surprises people:

python
1import sys
2
3a = [1, 2, 3]
4b = list(range(1000))
5
6print(sys.getsizeof(a))
7print(sys.getsizeof(b))

The container grows as it stores more references, but getsizeof is still not recursively summing the memory of nested Python objects.

Container Size Is Not Deep Size

Consider a nested structure:

python
1import sys
2
3data = {
4    "users": ["alice", "bob", "cara"],
5    "active": True
6}
7
8print(sys.getsizeof(data))

That output does not include the deep cost of the strings inside the list in the way many people expect. It measures the dictionary object itself, plus implementation-specific overhead.

So the right mental model is:

  • 'sys.getsizeof(obj) tells you the shallow size'
  • it does not automatically walk the object graph

Compute a Deep Size Recursively

If you want a rough total for nested built-in containers, you can recursively traverse them and keep track of objects you have already seen.

python
1import sys
2
3def deep_getsizeof(obj, seen=None):
4    if seen is None:
5        seen = set()
6
7    obj_id = id(obj)
8    if obj_id in seen:
9        return 0
10    seen.add(obj_id)
11
12    size = sys.getsizeof(obj)
13
14    if isinstance(obj, dict):
15        size += sum(
16            deep_getsizeof(k, seen) + deep_getsizeof(v, seen)
17            for k, v in obj.items()
18        )
19    elif isinstance(obj, (list, tuple, set, frozenset)):
20        size += sum(deep_getsizeof(item, seen) for item in obj)
21
22    return size
23
24data = {"users": ["alice", "bob", "cara"], "active": True}
25print(deep_getsizeof(data))

This is not perfect for every object type, but it is often good enough for application-level debugging.

Use a Library for Better Deep Measurement

For more robust deep-size inspection, a library such as pympler is easier than maintaining your own recursive logic.

bash
pip install pympler
python
1from pympler import asizeof
2
3data = {"users": ["alice", "bob", "cara"], "active": True}
4print(asizeof.asizeof(data))

This is a practical option when you are investigating memory-heavy objects or comparing several data structures.

Sometimes You Really Want Allocation Tracking

If the question is not "How big is this object?" but "Where is my Python process allocating memory?", tools such as tracemalloc are often more useful than object-size inspection.

python
1import tracemalloc
2
3tracemalloc.start()
4
5data = [str(i) for i in range(10000)]
6
7current, peak = tracemalloc.get_traced_memory()
8print(f"current={current} peak={peak}")

That measures tracked allocations over time, which is a different but often more useful diagnostic view.

Common Pitfalls

The biggest pitfall is treating sys.getsizeof() as a deep measurement. It is not.

Another issue is double-counting shared references when writing a recursive size function. If two containers point at the same inner object, that inner object should only be counted once. That is why the seen set matters.

Implementation differences also matter. Memory size details depend on the Python implementation and platform, so values from CPython on a 64-bit machine may differ from other interpreters or architectures.

Finally, some libraries manage memory outside normal Python object storage. For example, a NumPy array’s data buffer has its own size properties, so library-specific APIs may be more accurate than generic Python inspection.

Summary

  • 'sys.getsizeof() reports shallow object size, not full recursive size.'
  • Container objects usually do not include the deep size of nested elements.
  • For nested structures, use a recursive traversal or a tool such as pympler.
  • For broader memory diagnostics, use allocation tools such as tracemalloc.
  • Always match the measurement technique to the actual question you are trying to answer.

Course illustration
Course illustration

All Rights Reserved.