Just use the sys.getsizeof function defined in the sys module.

sys.getsizeof(object[, default]):

Return the size of an object in bytes. The object can be any type of object. All built-in objects will return correct results, but this does not have to hold true for third-party extensions as it is implementation specific.

Only the memory consumption directly attributed to the object is accounted for, not the memory consumption of objects it refers to.

The default argument allows to define a value which will be returned if the object type does not provide means to retrieve the size and would cause a TypeError.

getsizeof calls the object’s __sizeof__ method and adds an additional garbage collector overhead if the object is managed by the garbage collector.

See recursive sizeof recipe for an example of using getsizeof() recursively to find the size of containers and all their contents.

Usage example, in python 3.0:

>>> import sys
>>> x = 2
>>> sys.getsizeof(x)
24
>>> sys.getsizeof(sys.getsizeof)
32
>>> sys.getsizeof('this')
38
>>> sys.getsizeof('this also')
48

If you are in python < 2.6 and don't have sys.getsizeof you can use this extensive module instead. Never used it though.

Answer from nosklo on Stack Overflow
🌐
GeeksforGeeks
geeksforgeeks.org › python › difference-between-__sizeof__-and-getsizeof-method-python
Difference between __sizeof__() and getsizeof() method - Python - GeeksforGeeks
July 12, 2025 - Let's explore it using an example: ... import sys a = [1, 2] # Small list b = [1, 2, 3, 4] # Medium list d = [2, 3, 1, 4, 66, 54, 45, 89] # Larger list print(sys.getsizeof(a)) print(sys.getsizeof(b)) print(sys.getsizeof(d))
🌐
GeeksforGeeks
geeksforgeeks.org › python › how-to-find-size-of-an-object-in-python
How to find size of an object in Python? - GeeksforGeeks
July 17, 2023 - a = sys.getsizeof(12) print(a) b = sys.getsizeof('geeks') print(b) c = sys.getsizeof(('g', 'e', 'e', 'k', 's')) print(c) d = sys.getsizeof(['g', 'e', 'e', 'k', 's']) print(d) e = sys.getsizeof({1, 2, 3, 4}) print(e) f = sys.getsizeof({1: 'a', ...
Top answer
1 of 16
964

Just use the sys.getsizeof function defined in the sys module.

sys.getsizeof(object[, default]):

Return the size of an object in bytes. The object can be any type of object. All built-in objects will return correct results, but this does not have to hold true for third-party extensions as it is implementation specific.

Only the memory consumption directly attributed to the object is accounted for, not the memory consumption of objects it refers to.

The default argument allows to define a value which will be returned if the object type does not provide means to retrieve the size and would cause a TypeError.

getsizeof calls the object’s __sizeof__ method and adds an additional garbage collector overhead if the object is managed by the garbage collector.

See recursive sizeof recipe for an example of using getsizeof() recursively to find the size of containers and all their contents.

Usage example, in python 3.0:

>>> import sys
>>> x = 2
>>> sys.getsizeof(x)
24
>>> sys.getsizeof(sys.getsizeof)
32
>>> sys.getsizeof('this')
38
>>> sys.getsizeof('this also')
48

If you are in python < 2.6 and don't have sys.getsizeof you can use this extensive module instead. Never used it though.

2 of 16
659

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

The answer, "Just use sys.getsizeof", is not a complete answer.

That answer does work for builtin objects directly, but it does not account for what those objects may contain, specifically, what types, such as custom objects, tuples, lists, dicts, and sets contain. They can contain instances each other, as well as numbers, strings and other objects.

A More Complete Answer

Using 64-bit Python 3.6 from the Anaconda distribution, with sys.getsizeof, I have determined the minimum size of the following objects, and note that sets and dicts preallocate space so empty ones don't grow again until after a set amount (which may vary by implementation of the language):

Python 3:

Empty
Bytes  type        scaling notes
28     int         +4 bytes about every 30 powers of 2
37     bytes       +1 byte per additional byte
49     str         +1-4 per additional character (depending on max width)
48     tuple       +8 per additional item
64     list        +8 for each additional
224    set         5th increases to 736; 21nd, 2272; 85th, 8416; 341, 32992
240    dict        6th increases to 368; 22nd, 1184; 43rd, 2280; 86th, 4704; 171st, 9320
136    func def    does not include default args and other attrs
1056   class def   no slots 
56     class inst  has a __dict__ attr, same scaling as dict above
888    class def   with slots
16     __slots__   seems to store in mutable tuple-like structure
                   first slot grows to 48, and so on.

How do you interpret this? Well say you have a set with 10 items in it. If each item is 100 bytes each, how big is the whole data structure? The set is 736 itself because it has sized up one time to 736 bytes. Then you add the size of the items, so that's 1736 bytes in total

Some caveats for function and class definitions:

Note each class definition has a proxy __dict__ (48 bytes) structure for class attrs. Each slot has a descriptor (like a property) in the class definition.

Slotted instances start out with 48 bytes on their first element, and increase by 8 each additional. Only empty slotted objects have 16 bytes, and an instance with no data makes very little sense.

Also, each function definition has code objects, maybe docstrings, and other possible attributes, even a __dict__.

Also note that we use sys.getsizeof() because we care about the marginal space usage, which includes the garbage collection overhead for the object, from the docs:

getsizeof() calls the object’s __sizeof__ method and adds an additional garbage collector overhead if the object is managed by the garbage collector.

Also note that resizing lists (e.g. repetitively appending to them) causes them to preallocate space, similarly to sets and dicts. From the listobj.c source code:

    /* This over-allocates proportional to the list size, making room
     * for additional growth.  The over-allocation is mild, but is
     * enough to give linear-time amortized behavior over a long
     * sequence of appends() in the presence of a poorly-performing
     * system realloc().
     * The growth pattern is:  0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
     * Note: new_allocated won't overflow because the largest possible value
     *       is PY_SSIZE_T_MAX * (9 / 8) + 6 which always fits in a size_t.
     */
    new_allocated = (size_t)newsize + (newsize >> 3) + (newsize < 9 ? 3 : 6);

Historical data

Python 2.7 analysis, confirmed with guppy.hpy and sys.getsizeof:

Bytes  type        empty + scaling notes
24     int         NA
28     long        NA
37     str         + 1 byte per additional character
52     unicode     + 4 bytes per additional character
56     tuple       + 8 bytes per additional item
72     list        + 32 for first, 8 for each additional
232    set         sixth item increases to 744; 22nd, 2280; 86th, 8424
280    dict        sixth item increases to 1048; 22nd, 3352; 86th, 12568 *
120    func def    does not include default args and other attrs
64     class inst  has a __dict__ attr, same scaling as dict above
16     __slots__   class with slots has no dict, seems to store in 
                    mutable tuple-like structure.
904    class def   has a proxy __dict__ structure for class attrs
104    old class   makes sense, less stuff, has real dict though.

Note that dictionaries (but not sets) got a more compact representation in Python 3.6

I think 8 bytes per additional item to reference makes a lot of sense on a 64 bit machine. Those 8 bytes point to the place in memory the contained item is at. The 4 bytes are fixed width for unicode in Python 2, if I recall correctly, but in Python 3, str becomes a unicode of width equal to the max width of the characters.

And for more on slots, see this answer.

A More Complete Function

We want a function that searches the elements in lists, tuples, sets, dicts, obj.__dict__'s, and obj.__slots__, as well as other things we may not have yet thought of.

We want to rely on gc.get_referents to do this search because it works at the C level (making it very fast). The downside is that get_referents can return redundant members, so we need to ensure we don't double count.

Classes, modules, and functions are singletons - they exist one time in memory. We're not so interested in their size, as there's not much we can do about them - they're a part of the program. So we'll avoid counting them if they happen to be referenced.

We're going to use a blacklist of types so we don't include the entire program in our size count.

import sys
from types import ModuleType, FunctionType
from gc import get_referents

# Custom objects know their class.
# Function objects seem to know way too much, including modules.
# Exclude modules as well.
BLACKLIST = type, ModuleType, FunctionType


def getsize(obj):
    """sum size of object & members."""
    if isinstance(obj, BLACKLIST):
        raise TypeError('getsize() does not take argument of type: '+ str(type(obj)))
    seen_ids = set()
    size = 0
    objects = [obj]
    while objects:
        need_referents = []
        for obj in objects:
            if not isinstance(obj, BLACKLIST) and id(obj) not in seen_ids:
                seen_ids.add(id(obj))
                size += sys.getsizeof(obj)
                need_referents.append(obj)
        objects = get_referents(*need_referents)
    return size

To contrast this with the following whitelisted function, most objects know how to traverse themselves for the purposes of garbage collection (which is approximately what we're looking for when we want to know how expensive in memory certain objects are. This functionality is used by gc.get_referents.) However, this measure is going to be much more expansive in scope than we intended if we are not careful.

For example, functions know quite a lot about the modules they are created in.

Another point of contrast is that strings that are keys in dictionaries are usually interned so they are not duplicated. Checking for id(key) will also allow us to avoid counting duplicates, which we do in the next section. The blacklist solution skips counting keys that are strings altogether.

Whitelisted Types, Recursive visitor

To cover most of these types myself, instead of relying on the gc module, I wrote this recursive function to try to estimate the size of most Python objects, including most builtins, types in the collections module, and custom types (slotted and otherwise).

This sort of function gives much more fine-grained control over the types we're going to count for memory usage, but has the danger of leaving important types out:

import sys
from numbers import Number
from collections import deque
from collections.abc import Set, Mapping


ZERO_DEPTH_BASES = (str, bytes, Number, range, bytearray)


def getsize(obj_0):
    """Recursively iterate to sum size of object & members."""
    _seen_ids = set()
    def inner(obj):
        obj_id = id(obj)
        if obj_id in _seen_ids:
            return 0
        _seen_ids.add(obj_id)
        size = sys.getsizeof(obj)
        if isinstance(obj, ZERO_DEPTH_BASES):
            pass # bypass remaining control flow and return
        elif isinstance(obj, (tuple, list, Set, deque)):
            size += sum(inner(i) for i in obj)
        elif isinstance(obj, Mapping) or hasattr(obj, 'items'):
            size += sum(inner(k) + inner(v) for k, v in getattr(obj, 'items')())
        # Check for custom object instances - may subclass above too
        if hasattr(obj, '__dict__'):
            size += inner(vars(obj))
        if hasattr(obj, '__slots__'): # can have __slots__ with __dict__
            size += sum(inner(getattr(obj, s)) for s in obj.__slots__ if hasattr(obj, s))
        return size
    return inner(obj_0)

And I tested it rather casually (I should unittest it):

>>> getsize(['a', tuple('bcd'), Foo()])
344
>>> getsize(Foo())
16
>>> getsize(tuple('bcd'))
194
>>> getsize(['a', tuple('bcd'), Foo(), {'foo': 'bar', 'baz': 'bar'}])
752
>>> getsize({'foo': 'bar', 'baz': 'bar'})
400
>>> getsize({})
280
>>> getsize({'foo':'bar'})
360
>>> getsize('foo')
40
>>> class Bar():
...     def baz():
...         pass
>>> getsize(Bar())
352
>>> getsize(Bar().__dict__)
280
>>> sys.getsizeof(Bar())
72
>>> getsize(Bar.__dict__)
872
>>> sys.getsizeof(Bar.__dict__)
280

This implementation breaks down on class definitions and function definitions because we don't go after all of their attributes, but since they should only exist once in memory for the process, their size really doesn't matter too much.

🌐
Python
docs.python.org › 3 › library › sys.html
sys — System-specific parameters and functions
getsizeof() calls the object’s __sizeof__ method and adds an additional garbage collector overhead if the object is managed by the garbage collector. See recursive sizeof recipe for an example of using getsizeof() recursively to find the size of containers and all their contents.
🌐
Tutorialspoint
tutorialspoint.com › python › python_sys_getsizeof_method.htm
Python sys.getsizeof() method
import sys lst = [1, 2, 3, 4, 5] print(sys.getsizeof(lst)) # Adding element to list lst.append(6) print(sys.getsizeof(lst)) ... This example shows the size of a custom object.
🌐
TutorialsPoint
tutorialspoint.com › difference-between-sizeof-and-getsizeof-method-in-python
Difference between __sizeof__() and getsizeof() method in Python
April 17, 2023 - import sys empty_list=[] a =[34, 22] b =[45, 56, 5, 60] c =[23, 28, 38, 40] d =[2, 3, 1, 4, 66, 54, 45, 89] print(sys.getsizeof(empty_list)) print(sys.getsizeof(a)) print(sys.getsizeof(b)) print(sys.getsizeof(c)) print(sys.getsizeof(d)) ... In the above example, we define a list with lengths ...
🌐
Stack Abuse
stackabuse.com › bytes › determining-the-size-of-an-object-in-python
Determining the Size of an Object in Python
September 8, 2023 - For example, if you have a list ... the list is {size} bytes.") When you run this code, you'll see an output like this: $ python3 size.py The size of the list is 80 bytes....
Find elsewhere
Top answer
1 of 2
85

They are not the same thing at all.

len() queries for the number of items contained in a container. For a string that's the number of characters:

Return the length (the number of items) of an object. The argument may be a sequence (string, tuple or list) or a mapping (dictionary).

sys.getsizeof() on the other hand returns the memory size of the object:

Return the size of an object in bytes. The object can be any type of object. All built-in objects will return correct results, but this does not have to hold true for third-party extensions as it is implementation specific.

Python string objects are not simple sequences of characters, 1 byte per character.

Specifically, the sys.getsizeof() function includes the garbage collector overhead if any:

getsizeof() calls the object’s __sizeof__ method and adds an additional garbage collector overhead if the object is managed by the garbage collector.

String objects do not need to be tracked (they cannot create circular references), but string objects do need more memory than just the bytes per character. In Python 2, __sizeof__ method returns (in C code):

Py_ssize_t res;
res = PyStringObject_SIZE + PyString_GET_SIZE(v) * Py_TYPE(v)->tp_itemsize;
return PyInt_FromSsize_t(res);

where PyStringObject_SIZE is the C struct header size for the type, PyString_GET_SIZE basically is the same as len() and Py_TYPE(v)->tp_itemsize is the per-character size. In Python 2.7, for byte strings, the size per character is 1, but it's PyStringObject_SIZE that is confusing you; on my Mac that size is 37 bytes:

>>> sys.getsizeof('')
37

For unicode strings the per-character size goes up to 2 or 4 (depending on compilation options). On Python 3.3 and newer, Unicode strings take up between 1 and 4 bytes per character, depending on the contents of the string.

For containers such as dictionaries or lists that reference other objects, the memory size given covers only the memory used by the container and the pointer values used to reference those other objects. There is no straightforward method of including the memory size of the ‘contained’ objects because those same objects could have many more references elsewhere and are not necessarily owned by a single container.

The documentation states it like this:

Only the memory consumption directly attributed to the object is accounted for, not the memory consumption of objects it refers to.

If you need to calculate the memory footprint of a container and anything referenced by that container you’ll have to use some method of traversing to those contained objects and get their size; the documentation points to a recursive recipe.

2 of 2
2

key difference is that len() will give actual length of elements in container , Whereas sys.getsizeof() will give it's memory size which it occupy

for more information read docs of python which is available at https://docs.python.org/3/library/sys.html#module-sys

🌐
Codedamn
codedamn.com › news › python
How to Determine the Size of Objects in Python
July 2, 2023 - Q: Does the size of the object affect the performance of my Python script? Yes, larger objects take up more memory, which can slow down your script if memory becomes scarce. Q: Why does sys.getsizeof() not include the size of the contents of compound objects?
🌐
Ned Batchelder
nedbatchelder.com › blog › 202002 › sysgetsizeof_is_not_what_you_want
sys.getsizeof is not what you want | Ned Batchelder
February 9, 2020 - This week at work, an engineer mentioned that they were looking at the sizes of data returned by an API, and it was always coming out the same, which seemed strange. It turned out the data was a dict, and they were looking at the size with sys.getsizeof.
Top answer
1 of 2
11

I will attempt to answer your question from a broader point of view. You're referring to two functions and comparing their outputs. Let's take a look at their documentation first:

  • len():

Return the length (the number of items) of an object. The argument may be a sequence (such as a string, bytes, tuple, list, or range) or a collection (such as a dictionary, set, or frozen set).

So in case of string, you can expect len() to return the number of characters.

  • sys.getsizeof():

Return the size of an object in bytes. The object can be any type of object. All built-in objects will return correct results, but this does not have to hold true for third-party extensions as it is implementation specific.

So in case of string (as with many other objects) you can expect sys.getsizeof() the size of the object in bytes. There is no reason to think that it should be the same as the number of characters.

Let's have a look at some examples:

>>> first = "First"
>>> len(first)
5
>>> sys.getsizeof(first)
42

This example confirms that the size is not the same as the number of characters.

>>> second = "Second"
>>> len(second)
6
>>> sys.getsizeof(second)
43

We can notice that if we look at a string one character longer, its size is one byte bigger as well. We don't know if it's a coincidence or not though.

>>> together = first + second
>>> print(together)
FirstSecond
>>> len(together)
11

If we concatenate the two strings, their combined length is equal to the sum of their lengths, which makes sense.

>>> sys.getsizeof(together)
48

Contrary to what someone might expect though, the size of the combined string is not equal to the sum of their individual sizes. But it still seems to be the length plus something. In particular, something worth 37 bytes. Now you need to realize that it's 37 bytes in this particular case, using this particular Python implementation etc. You should not rely on that at all. Still, we can take a look why it's 37 bytes what they are (approximately) used for.

String objects are in CPython (probably the most widely used implementation of Python) implemented as PyStringObject. This is the C source code (I use the 2.7.9 version):

typedef struct {
    PyObject_VAR_HEAD
    long ob_shash;
    int ob_sstate;
    char ob_sval[1];

    /* Invariants:
     *     ob_sval contains space for 'ob_size+1' elements.
     *     ob_sval[ob_size] == 0.
     *     ob_shash is the hash of the string or -1 if not computed yet.
     *     ob_sstate != 0 iff the string object is in stringobject.c's
     *       'interned' dictionary; in this case the two references
     *       from 'interned' to this object are *not counted* in ob_refcnt.
     */
} PyStringObject;

You can see that there is something called PyObject_VAR_HEAD, one int, one long and a char array. The char array will always contain one more character to store the '\0' at the end of the string. This, along with the int, long and PyObject_VAR_HEAD take the additional 37 bytes. PyObject_VAR_HEAD is defined in another C source file and it refers to other implementation-specific stuff, you need to explore if you want to find out where exactly are the 37 bytes. Plus, the documentation mentions that sys.getsizeof()

adds an additional garbage collector overhead if the object is managed by the garbage collector.

Overall, you don't need to know what exactly takes the something (the 37 bytes here) but this answer should give you a certain idea why the numbers differ and where to find more information should you really need it.

2 of 2
2

To quote the documentation:

Return the size of an object in bytes. The object can be any type of object. All built-in objects will return correct results, but this does not have to hold true for third-party extensions as it is implementation specific.

Built in strings are not simple character sequences - they are full fledged objects, with garbage collection overhead, which probably explains the size discrepancy you're noticing.

🌐
Codingem
codingem.com › home › how to get the size of a python object (examples & theory)
How to Get the Size of a Python Object (Examples & Theory)
December 12, 2022 - For example, to build an empty list with an empty list inside, you already need 120 bytes of memory. from pympler import asizeof print(asizeof.asizeof([[]])) # Output: 120 · Then the rest of the memory consumption is based on what values you ...
🌐
Towards Data Science
towardsdatascience.com › home › latest › unexpected size of python objects in memory
Unexpected Size of Python Objects in Memory | Towards Data Science
March 5, 2025 - When we create an object, Python stores all this information in memory. Therefore, we have an overhead even for an empty string. Let’s check the same thing for a list. >>> sys.getsizeof([]) 64 >>> sys.getsizeof([1]) 72 >>> sys.getsizeof([1, 2]) 80 · We see the same story here. A list object has 64 bytes of overhead. For each additional item, its size grows by 8 bytes. Okay, it was strange first, but it makes sense now. Let’s see another example (I promise you, this one is more interesting).
🌐
Reddit
reddit.com › r/learnpython › size of python objects different? [real memory vs sys.getsizeof()]
r/learnpython on Reddit: Size of python objects different? [Real memory vs sys.getsizeof()]
November 11, 2016 -

Hi Pyople!

Yesterday I learned about sys.getsizeof() function and try some code. More specifically:

lst = [i for i in range(1000000000)]  # one mld numbers, creating for about a minute

When I use sys.getsizeof(lst), it returns: 8058558880. Which is correct. But when I look at my system resources in Linux Centos7 IPython (Python 3.4) I see: ipython Memory: 39592564 K Shared Mem: 5176 K - That's freaking 40GB.

I don't understand why, if a object is 8 GB in size, takes 40 KGB system memory. I tried it in list that had around 400 MB and system took 400 * 5 (approx) = 2 GB (approx)

Why is it taking 5-times more memory than it should? Or is the problem only because I tried it in iPython / Konsole? And in program it wouldn't be a problem?

🌐
KooR.fr
koor.fr › Python › API › python › sys › getsizeof.wp
KooR.fr - Fonction getsizeof - module sys - Description de quelques librairies Python
RAG (Retrieval-Augmented Generation)et Fine Tuning d'un LLM Voir le programme détaillé Module « sys » Python 3.13.2 · getsizeof(object [, default]) -> int Return the size of object in bytes.
🌐
Delft Stack
delftstack.com › home › howto › python › difference between len and getsizeof in python
The Difference Between len() and sys.getsizeof() in Python | Delft Stack
October 10, 2023 - The sys module in Python provides a sys.getsizeof() function, which essentially returns the memory size of an object that is passed to it in the unit of bytes. The object’s memory consumption is what is accounted for instead of the memory consumption the object refers to.
🌐
Java Guides
javaguides.net › 2024 › 12 › python-sys-getsizeof-function.html
Python sys getsizeof() Function
December 15, 2024 - import sys # Function to profile memory usage of a list def profile_memory_usage(): list_data = [i for i in range(1000)] size = sys.getsizeof(list_data) print(f"Memory usage of list_data: {size} bytes") # Adding more elements to the list ...
🌐
GoShippo
goshippo.com › blog › measure-real-size-any-python-object
How to Measure the Real Size of Any Object in Python
April 14, 2025 - It uses sys.getsizeof internally and it turned out to be pretty easy to write once I figured out enough of the edge cases. I hope it helps the next time you need to accurately measure the size of an object! By the way, we’re hiring at Shippo! We work with Python, EmberJS, and PostgreSQL.
🌐
w3resource
w3resource.com › python-exercises › python-basic-exercise-79.php
Python: Get the size of an object in bytes - w3resource
May 17, 2025 - ... import sys # Import the sys ... to them str1 = "one" str2 = "four" str3 = "three" x = 0 y = 112 z = 122.56 # Print the size in bytes of each variable print("Size of ", str1, "=", str(sys.getsizeof(str1)) + " bytes") print("Size ...
🌐
ZetCode
zetcode.com › python › dunder-sizeof
Python __sizeof__ Method - Complete Guide
For accurate measurements, we use sys.getsizeof() on each element. This accounts for Python's object overhead on each contained item. Classes using __slots__ have different memory characteristics. This example shows how to implement __sizeof__ for such classes.