How to Reduce Instance Memory with __slots__ in Python

Demonstrates that classes with __slots__ use less memory per instance than regular classes because they skip the instance __dict__.

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

Python code

25 lines
Python 3.9+
class SlottedPoint:
    __slots__ = ('x', 'y', 'z')

    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z


class RegularPoint:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z


if __name__ == "__main__":
    regular = RegularPoint(1, 2, 3)
    slotted = SlottedPoint(1, 2, 3)

    print(f"RegularPoint instance size: {regular.__sizeof__()} bytes")
    print(f"SlottedPoint instance size: {slotted.__sizeof__()} bytes")
    print(f"Memory saved: {regular.__sizeof__() - slotted.__sizeof__()} bytes")
    print(f"RegularPoint has __dict__: {hasattr(regular, '__dict__')}")
    print(f"SlottedPoint has __dict__: {hasattr(slotted, '__dict__')}")

Output

stdout
RegularPoint instance size: 56 bytes
SlottedPoint instance size: 48 bytes
Memory saved: 8 bytes
RegularPoint has __dict__: True
SlottedPoint has __dict__: False

How it works

The __slots__ declaration tells Python to pre-allocate a fixed set of attributes for each instance, replacing the per-instance __dict__ dictionary with a more compact descriptor-based storage. That's why the slotted instance reports no __dict__ and consistently returns the same sizeof value, while regular instances each carry their own dict overhead. The savings scale with the number of instances — for millions of objects, a few dozen bytes each can dramatically shrink memory usage. Note that __slots__ also prevents adding new attributes not listed, which enforces a stricter, more predictable object model.

Common mistakes

  • Forgetting that __slots__ must be an iterable of strings, not a single string
  • Expecting slotted instances to have __dict__ or be picklable without extra effort
  • Overlooking that inheritance requires redeclaring __slots__ in every subclass

Variations

  1. Use `__slots__ = 'x y z'.split()` for a more readable declaration when there are many fields
  2. Add `__weakref__` to __slots__ if you need weak references to your instances

Real-world use cases

  • Storing millions of lightweight vector points or coordinates in a scientific simulation.
  • Representing large datasets of record-like objects in memory‑constrained analytics pipelines.
  • Caching many small, fixed‑shape objects (like API responses or config entries) in a production service.

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.