Python•September 5, 2026•

Python __slots__: Cut Object Memory Usage by 66%

How __slots__ removes the per-instance __dict__ to significantly reduce memory usage in Python objects, with real measurements using pympler.

One of Python's strengths is its flexibility. Object attributes can be added dynamically at runtime, making classes easy to extend. However, this flexibility comes with additional memory overhead.

If your application creates thousands or even millions of objects, this overhead can become significant. Python provides a feature called __slots__ that helps reduce memory consumption by preventing the creation of an instance dictionary.

Let's see how it works.

Objects Without __slots__

Python
class UserProfile:
 
    # without __slots__
    def __init__(self, name, email, mobile, age):
        self.name = name
        self.email = email
        self.mobile = mobile
        self.age = age
 
 
user_object = UserProfile("Ganesh", "ganesha@example.com", 12345, 25)

The attributes are stored inside an internal dictionary (__dict__).

Python
>>> print(user_object.__dict__)
{'name': 'Ganesh',
 'email': 'ganesha@example.com',
 'mobile': 12345,
 'age': 25}

You can also inspect the available attributes and methods:

Python
>>> print(dir(user_object))
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__',
 '__eq__', '__firstlineno__', '__format__', '__ge__', '__getattribute__',
 '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__',
 '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
 '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
 '__static_attributes__', '__str__', '__subclasshook__',
 '__weakref__', 'age', 'email', 'mobile', 'name']

Notice that __dict__ appears in the list.

Measuring Memory Usage

sys.getsizeof() only reports the size of the object container itself and not the complete memory occupied by nested objects. To calculate the actual memory footprint recursively, we can use the pympler package.

Python
from pympler import asizeof
>>> print(f"Memory Taken: {asizeof.asizeof(user_object)} bytes")
Memory Taken: 712 bytes

The total memory taken by this object is 712 bytes.

Objects With __slots__

Now let's define the same class using __slots__.

Python
class UserProfile:
    # with __slots__
 
    __slots__ = ('name', 'email', 'mobile', 'age')
 
    def __init__(self, name, email, mobile, age):
        self.name = name
        self.email = email
        self.mobile = mobile
        self.age = age
 
user_object = UserProfile("Ganesh", "ganesha@example.com", 12345, 25)

If you inspect the object:

Python
>>> print(dir(user_object))
['__class__', '__delattr__', '__dir__', '__doc__',
 '__eq__', '__firstlineno__', '__format__', '__ge__',
 '__getattribute__', '__getstate__', '__gt__', '__hash__',
 '__init__', '__init_subclass__', '__le__', '__lt__',
 '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',
 '__repr__', '__setattr__', '__sizeof__', '__slots__',
 '__static_attributes__', '__str__', '__subclasshook__',
 'age', 'email', 'mobile', 'name']

You'll notice that __dict__ is no longer present.

Trying to access it raises an error:

Python
>>> print(user_object.__dict__)
Traceback (most recent call last):
  File "<python-input-20>", line 1, in <module>
    print(user_object.__dict__)
          ^^^^^^^^^^^^^^^^^^^
AttributeError: 'UserProfile' object has no attribute '__dict__'. Did you mean: '__dir__'?

Memory Usage with __slots__

Python
>>> print(f"Memory Taken: {asizeof.asizeof(user_object)} bytes")
Memory Taken: 240 bytes

In this example, memory usage dropped from 712 bytes to 240 bytes, which is almost a 66% reduction.

Note: Exact memory numbers may vary depending on your Python version, operating system, and architecture.

Dynamic Attributes Are Not Allowed

Without __slots__, you can add attributes at runtime:

Python
>>> user_object.country = "IN"
>>> user_object.country
'IN'

With __slots__, this raises:

Python
>>> user_object.country = "IN"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    user_object.country = "IN"
    ^^^^^^^^^^^^^^^^^^
AttributeError: 'UserProfile' object has no attribute 'country' and no __dict__ for setting new attributes

This happens because __slots__ removes the per-instance __dict__ and restricts objects to a predefined set of attributes.

Advantages of Using __slots__

  1. Reduced Memory Usage — Objects no longer maintain an instance dictionary, saving memory when many objects are created.
  2. Better Performance — Attribute access may be slightly faster, although the primary benefit of __slots__ is reduced memory usage.
  3. Prevents Accidental Attribute Creation — Typos such as user_object.emal = "abc@example.com" will immediately raise an error instead of silently creating a new attribute.
  4. Useful for Large Data Models — Classes that represent millions of records, cache entries, or data objects can benefit significantly from lower memory consumption.

Disadvantages of Using __slots__

  1. No Dynamic Attributes — You cannot add new attributes unless they are explicitly declared in __slots__.
  2. No __dict__ — Some libraries and debugging tools rely on __dict__, which may cause compatibility issues.
  3. Inheritance Becomes More Complex — Subclasses must define their own __slots__, and mixing slotted and non-slotted classes requires extra care.
  4. Reduced Flexibility — If the class structure changes frequently, maintaining __slots__ can become inconvenient.

When Should You Use __slots__?

Use __slots__ when:

  • You create a large number of objects.
  • The set of attributes is fixed.
  • Memory usage is important.
  • You want to prevent accidental attribute creation.

Avoid using __slots__ when:

  • You need dynamic attributes.
  • Flexibility is more important than memory optimization.
  • The class is small and only a few instances are created.

Conclusion

__slots__ is a simple but powerful optimization in Python. By removing the per-instance dictionary, it can significantly reduce memory usage and slightly improve attribute access speed.

__slots__ is most beneficial when creating a large number of objects with a fixed set of attributes. Although it reduces flexibility, the memory savings can be substantial in memory-sensitive applications.

Spread the word

Enjoyed this post? Share it with your network in a click.

TweetShare

Keep exploring

More posts about Python.