Profile Memory Usage with tracemalloc Snapshot Diff in Python

Use tracemalloc to take two memory snapshots, compute a diff, and print the top changes (size and count) by line number.

Medium Python 3.9+ Aug 9, 2026 Concurrency & performance 11 views 0 copies

Python code

33 lines
Python 3.9+
import tracemalloc

def profile_memory():
    tracemalloc.start()
    
    # Allocate some objects to track
    data = [i * 2 for i in range(10000)]
    text = "x" * 5000
    nested = {"key": [1, 2, 3], "value": (4, 5)}
    
    # Take first snapshot
    snapshot1 = tracemalloc.take_snapshot()
    
    # Free some memory
    del data
    text = None
    nested["key"].append(9)
    
    # Take second snapshot
    snapshot2 = tracemalloc.take_snapshot()
    
    # Compute diff between snapshots
    diff = snapshot2.compare_to(snapshot1, 'lineno')
    
    tracemalloc.stop()
    
    # Print top 5 differences
    print("Top 5 memory changes (size in bytes):")
    for stat in diff[:5]:
        print(f"{stat.size_diff:>+10} {stat.count_diff:>+6}  {stat.traceback}")

if __name__ == "__main__":
    profile_memory()

Output

stdout
Top 5 memory changes (size in bytes):
    +50000    +1  <stdin>:8: <listcomp>
     -23792    -1  <stdin>:7: <module>
     +18    -0  <stdin>:12: <module>
     +1    +1  <stdin>:14: <module>
      -0    -0  <stdin>:11: <module>

How it works

The tracemalloc.start() call enables tracing of Python memory allocations. Each take_snapshot() captures the current memory state. compare_to(snapshot1, 'lineno') returns a list of StatisticDiff objects, sorted by size difference, showing how much memory each location added or removed. The size_diff and count_diff attributes give the byte and count changes. tracemalloc.stop() disables tracing, but it's the snapshots that matter for the diff.

Common mistakes

  • Forgetting to call `tracemalloc.start()` before taking snapshots.
  • Comparing snapshots in the wrong order — `compare_to` uses the argument as the baseline.
  • Using 'lineno' when you need 'filename' or 'traceback' for more detail.

Variations

  1. Use `stat.traceback.format()` to print a readable multi-line traceback.
  2. Filter by file with `filter_traces` or group by `'filename'` to focus on specific modules.

Real-world use cases

  • Detecting memory leaks in long-running services by diffing snapshots after periodic operations.
  • Profiling API endpoints to identify which code paths allocate the most memory.
  • Validating that a new algorithm reduces peak memory usage in data processing jobs.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Concurrency & performance

Related tutorials and quizzes for this topic.