AI & Machine Learning

The 10GB CSV Problem

Python Machine Learning Linux SQL Pandas NumPy Data Science Vector Search Semantic Search
1,077 words Includes Code

Key Takeaway: A 16GB RAM laptop is not a limitation—it's an invitation to write better code. By optimizing data types, selecting only needed columns, processing in chunks, using efficient file formats like Parquet, and querying with DuckDB, you can handle datasets far larger than naive approaches would suggest.

Optimize Python Data Science for 16GB RAM laptops with Pandas, Parquet, and DuckDB

The 10GB CSV Problem

You download a 10GB CSV file. Your laptop has 16GB of RAM. You run:

df = pd.read_csv("huge_file.csv")

And your system starts swapping to disk. Everything slows to a crawl. Eventually, the process is killed—or your entire laptop becomes unresponsive.

The instinct is to upgrade hardware. But the smarter move is to optimize your workflow. As this article demonstrates, the same 10GB file can often be processed on 16GB RAM with the right techniques.

Memory usage before and after optimization showing 83% reduction

Why a 10GB File Can Require Much More Than 10GB RAM

A common misconception: file size equals memory size. It doesn't.

When Pandas reads a CSV, it must:

  • Parse text into Python objects
  • Create NumPy arrays for numeric columns
  • Build an Index
  • Allocate temporary buffers for parsing
  • Store intermediate results during operations

A 10GB CSV can easily consume 12-15GB in memory depending on the schema, string lengths, and operations performed. Add the operating system, browser, and other applications, and your 16GB laptop runs out of headroom.

Understand Your 16GB Machine

A "16GB RAM laptop" does not mean Python gets 16GB. Check what's actually available:

# Windows
tasklist /FI "USERNAME eq %USERNAME%" | findstr python

# Linux/macOS
ps aux | grep python

In practice, after the OS, browser, and background processes, Python may have only 10-12GB available. This makes optimization essential, not optional.

Measure Memory Before Optimizing

Never optimize blind. Measure first:

# Check DataFrame memory
df.info(memory_usage="deep")

# Per-column memory
df.memory_usage(deep=True) / 1024**2  # in MB

# Total in MB
df.memory_usage(deep=True).sum() / 1024**2

This tells you exactly where memory is going. Often, one or two columns dominate usage.

Use Only the Columns You Need

# BAD: loads everything
df = pd.read_csv("data.csv")

# BETTER: load only needed columns
df = pd.read_csv("data.csv", usecols=["id", "category", "value"])

If your analysis needs 3 columns out of 50, loading all 50 wastes 94% of the memory.

Optimize Data Types

Default data types are conservative. You can often reduce memory significantly:

# Before: default dtypes
df["id"] = df["id"].astype("int64")       # 8 bytes per value
df["category"] = df["category"].astype("object")  # variable, high overhead
df["value"] = df["value"].astype("float64")  # 8 bytes per value

# After: optimized dtypes
df["id"] = df["id"].astype("int32")       # 4 bytes per value
df["category"] = df["category"].astype("category")  # compact encoding
df["value"] = df["value"].astype("float32")  # 4 bytes per value

Warning: Don't blindly downcast. Verify that the smaller dtype preserves your data semantics—check for overflow, precision loss, and missing value handling.

DtypeBytes/ValueUse When
int648Large integers, default
int324Values fit in ±2 billion
float648High-precision floats
float324ML features, acceptable precision
categoryvariableLow-cardinality strings
stringvariableVariable-length text

Process Data in Chunks

One of the most powerful techniques for large files:

chunk_size = 100_000
total_sum = 0
total_count = 0

for chunk in pd.read_csv("huge.csv", chunksize=chunk_size):
    total_sum += chunk["value"].sum()
    total_count += len(chunk)

mean_value = total_sum / total_count

Instead of loading 10GB at once, you process 100MB at a time. Peak memory stays low regardless of file size.

Optimization pipeline showing memory reduction at each step

Streaming with Generators

Python generators produce values lazily instead of loading everything into memory:

# List: loads everything
# results = [process(x) for x in huge_dataset]

# Generator: produces values on demand
def process_large(n):
    for i in range(n):
        yield expensive_computation(i)

# Memory: O(1) regardless of n
total = sum(process_large(10_000_000))

Avoid Unnecessary DataFrame Copies

Every operation that creates a copy doubles memory usage temporarily:

# Creates a copy (memory spike)
df_filtered = df[df["value"] > 0].copy()

# Better: use inplace or reassign
df = df[df["value"] > 0]  # original can be garbage collected

Use Efficient File Formats

CSV is text-based and slow to parse. Columnar formats are dramatically better:

FormatRead SpeedCompressionSchemaBest Use
CSVSlowText onlyNoData exchange
ParquetFastExcellentYesAnalytics, columnar
FeatherVery fastGoodNoRapid I/O
ORCFastExcellentYesHive ecosystem
# Convert CSV to Parquet
df.to_parquet("data.parquet", index=False)

# Read Parquet (much faster, smaller file)
df = pd.read_parquet("data.parquet")

Query Without Loading: DuckDB

DuckDB lets you run SQL directly on CSV/Parquet files without loading them into Pandas:

import duckdb

# Query a 10GB CSV without loading it
result = duckdb.sql("""
    SELECT category, COUNT(*) as cnt, AVG(value) as avg_val
    FROM read_csv_auto('huge.csv')
    GROUP BY category
    ORDER BY cnt DESC
""").fetchdf()  # Only the small result goes to Pandas

DuckDB streams data from disk, processes it in memory-efficient batches, and only materializes the result. A 10GB file can produce a 1KB result without ever loading the full file.

Tool Comparison

Python data science tools comparison: Pandas, Polars, DuckDB, PyArrow, Dask

Machine Learning on 16GB RAM

For ML workloads, additional strategies help:

  • Sample data — Train on a representative subset first
  • Incremental learning — Use partial_fit where supported
  • Sparse matrices — For high-dimensional, sparse features
  • Feature selection — Reduce dimensionality before training
  • Batch processing — Process data in batches, not all at once

Notebook Memory Management

Jupyter notebooks hide memory issues. Common problems:

  • Variables persist between cells
  • Output caches large objects
  • Multiple copies of DataFrames accumulate
  • Re-running cells without clearing old state

Tip: Restart the kernel periodically and monitor memory with %memit or df.info().

Common Mistakes

#MistakeBetter Approach
1Loading entire datasetsUse chunks or DuckDB
2Keeping unused columnsUse usecols
3Using object dtype everywhereUse category, string
4Creating unnecessary copiesReassign, avoid .copy()
5Ignoring profilingMeasure before optimizing

What Can 16GB Realistically Handle?

Workload16GB RAM Feasibility
Small/medium tabular MLExcellent
Large CSV with chunkingOften practical
Large Parquet analyticsOften practical
SQL aggregations (DuckDB)Practical
Image datasetsDepends on preprocessing
Large NLP datasetsRequires careful batching
Huge in-memory DataFramesPoor fit

Key insight: Dataset size alone does not determine feasibility. Schema, algorithm, file format, and processing strategy matter more.

Optimization Checklist

  1. ✅ Profile memory before optimizing
  2. ✅ Select only required columns
  3. ✅ Optimize data types (int32, float32, category)
  4. ✅ Convert CSV to Parquet
  5. ✅ Process large files in chunks
  6. ✅ Use DuckDB for large queries
  7. ✅ Avoid unnecessary DataFrame copies
  8. ✅ Use generators for streaming
  9. ✅ Use efficient algorithms
  10. ✅ Monitor memory during execution
  11. ✅ Restart notebook kernels when needed

Key Takeaways

  • A 10GB CSV can consume more than 10GB in memory due to parsing overhead
  • Profile first—measure before optimizing
  • Select only needed columns and optimize data types
  • Process in chunks to keep peak memory low
  • Use Parquet instead of CSV for analytical workloads
  • DuckDB can query large files without loading them into Pandas
  • 16GB RAM is enough for most data science work with the right techniques

Related BestWordz Articles

Further Reading

💬 Discuss on BestWordz Community

Join the conversation about Python, Machine Learning, Linux on the BestWordz Community forum.

Visit Forum →