hardConceptScenarioMidSeniorStaff
A long-running Python service keeps climbing in memory and never comes back down. How do you work out where the memory went?
5 min readUpdated 2026-08-15
Answer
Short answer
CPython frees an object the instant its reference count reaches zero, so steady growth is usually something still holding a reference rather than a leak. The cycle collector reclaims only reference cycles.
Was this answer helpful?
Likely follow-ups
- What kinds of object does the cyclic collector track, and which ones can it ignore entirely?
- How would you find what is still referencing an object you expected to be freed?
- Why might tracemalloc show almost nothing while the process keeps growing?
- When would you tune the generational collector's thresholds, or call gc.freeze before forking workers?
Related questions
- How do you tell whether a value escapes to the heap, and how would you find the allocations that are costing you?hardAlso on profiling and garbage-collection6 min
- Memory keeps climbing in a Go service under load. How do you find out why, and what can you actually tune?hardAlso on garbage-collection and memory6 min
- How does the .NET garbage collector decide what to collect, and how would you make a hot path allocate less?hardAlso on garbage-collection and memory6 min
- A hot path allocates heavily and garbage collection is showing up in your profile. What does Span give you that a substring does not?hardAlso on memory and garbage-collection4 min