Python · medium

You need to process a 50GB CSV on a machine with 16GB of RAM. How?

Asked in Data Engineer interviews, in the Python round.

Short answer

Stream it instead of loading it: read_csv with chunksize, or hand it to an engine that spills to disk and reads only the columns you touch (DuckDB, Polars lazy, Spark). If it is a recurring job, convert once to Parquet, columnar plus compression usually cuts both IO and memory by an order of magnitude. The general move is to make the working set fit in memory, not the file.

How to answer it

Definition

Do not load it. The file is larger than memory, so the answer is to stream it, or to hand it to an engine that reads only what it needs and spills to disk.

The options

Example

import pandas as pd

totals = {}
for chunk in pd.read_csv(
    "50gb.csv",
    chunksize=1_000_000,
    usecols=["category", "amount"],       # two columns, not eighty
    dtype={"category": "category", "amount": "float32"},
):
    for k, v in chunk.groupby("category")["amount"].sum().items():
        totals[k] = totals.get(k, 0) + v

Or let an engine do it:

import duckdb
duckdb.sql(
    "SELECT category, SUM(amount) FROM read_csv_auto('50gb.csv') GROUP BY category"
).df()

Why the dtypes matter

usecols and dtype are not micro-optimizations here. Reading two columns instead of eighty is a 40x cut before anything else happens, and float32 against the default float64 halves what is left. A 50GB file often becomes a few GB of working data once you stop reading what you do not need.

Key points

FAQ

The 30-second answer

I would not load it. The first question is what the operation actually is: for a sum, a count or a groupby I can stream the file in chunks with read_csv and a chunksize, keeping only a small accumulator in memory.
Before that I would cut what is read at all, with usecols and explicit dtypes, because reading two of eighty columns is a far bigger win than any tuning, and float32 instead of float64 halves the rest.
In practice I would reach for DuckDB or Polars in lazy mode and let the engine handle spilling and parallelism, and convert the file to Parquet once if it is going to be read more than a couple of times. I would also ask where the file came from, because if it was exported from a warehouse the right fix is to aggregate it there instead.

In the interview

Practice this for real