Bytes to human-readable size in Python

def format_bytes(n, i=0): return format_bytes(n / 1024, i + 1) if n >= 1023.95 and i < 5 else f"{n:.1f} " + ("B", "KiB", "MiB", "GiB", "TiB", "PiB")[i]

format_bytes(123456789) returns '117.7 MiB' with the one-liner above. It divides by 1,024 until the number would print below 1024.0, then formats it with one decimal. It works on any Python 3.6 or later, and on the int that os.path.getsize() or Path.stat().st_size gives you.

def format_bytes(n, i=0): return format_bytes(n / 1024, i + 1) if n >= 1023.95 and i < 5 else f"{n:.1f} " + ("B", "KiB", "MiB", "GiB", "TiB", "PiB")[i]

print(format_bytes(123456789), format_bytes(1536), format_bytes(500))
117.7 MiB 1.5 KiB 500.0 B

The tool below starts on 123456789 B: exactly 117.73756885528564453125 MiB, or 123.456789 MB.

A readable version, binary or decimal

def format_bytes(n, binary=True):
    k = 1024 if binary else 1000
    units = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'] if binary else ['B', 'kB', 'MB', 'GB', 'TB', 'PB']
    for unit in units[:-1]:
        if round(n, 1) < k:
            return f'{n} B' if unit == 'B' else f'{n:.1f} {unit}'
        n /= k
    return f'{n:.1f} {units[-1]}'

print(format_bytes(123456789))
print(format_bytes(123456789, binary=False))
print(format_bytes(1048575), format_bytes(500), format_bytes(0))
117.7 MiB
123.5 MB
1.0 MiB 500 B 0 B

Use binary=False to match macOS Finder and disk labels, and the 1,024 default to match ls -lh and du -h. Dividing by 1,024 and writing MB, as Windows does, is the mix that confuses people.

The 1024.0 KiB bug

The function most people copy checks the size before it rounds:

def sizeof_fmt(num, suffix='B'):
    for unit in ('', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi'):
        if abs(num) < 1024.0:
            return f'{num:3.1f}{unit}{suffix}'
        num /= 1024.0
    return f'{num:.1f}Yi{suffix}'

print(sizeof_fmt(1048575))   # 1024.0KiB

1,048,575 bytes is 1023.999 KiB, which is below 1,024, so it stays in KiB, and then :.1f rounds it up to 1024.0. Comparing round(n, 1) instead, or n >= 1023.95 as the one-liner does, moves it to 1.0 MiB.

f-string formats

:.1f fixes one decimal and :, groups thousands, handy for the exact count next to the short one:

n = 123456789
print(f'{format_bytes(n)} ({n:,} bytes)')   # 117.7 MiB (123,456,789 bytes)
print(f'{n / 1000**2:.2f} MB')              # 123.46 MB

humanize

pip install humanize adds naturalsize, which defaults to decimal units:

import humanize

humanize.naturalsize(123456789)                # '123.5 MB'
humanize.naturalsize(123456789, binary=True)   # '117.7 MiB'
humanize.naturalsize(123456789, gnu=True)      # '117.7M'
humanize.naturalsize(1048575, binary=True)     # '1.0 MiB'
humanize.naturalsize(500)                      # '500 Bytes'

gnu=True uses 1,024 with the single letters ls -h prints. That’s humanize 4.16.0 on Python 3.14.

Try it in the Data Size Converter

A number with a unit: 1.5 GB, 700 MiB, 8 Gb. Typed all lowercase, mb or kib reads as bytes; mixed, as in Mb, it reads as bits.

123456789 B is 123,456,789 bytes

UnitValueIn words
Bytes, decimal (SI) — each step ×1,000
B123,456,789bytes
kB123,456.789kilobytes
MB123.456789megabytes
GB0.123456789gigabytes
TB0.000123456789terabytes
PB0.000000123456789petabytes
Bytes, binary (IEC) — each step ×1,024
KiB120,563.2705078125kibibytes
MiB117.73756885528564453125mebibytes
GiB0.114978094585239887gibibytes
TiB0.000112283295493398327tebibytes
PiB0.000000109651655755271804pebibytes
Bits — 8 to a byte
bit987,654,312bits
Kb987,654.312kilobits
Mb987.654312megabits
Gb0.987654312gigabits
Tb0.000987654312terabits
Pb0.000000987654312petabits

SI units count by thousands and IEC units by 1,024s: 1 kB is 1,000 bytes, while 1 KiB is 1,024 — 2.4% more. This page reads KB as 1,000 bytes; some systems mean 1,024.

Runs in your browser. Nothing you enter is sent anywhere.