How to Stream Large CSV Files in Python
Process a large CSV file in memory-efficient chunks using Python's csv module, yielding batches of rows instead of loading everything at once.
Python code
33 linesimport csv
from pathlib import Path
def process_csv_in_chunks(file_path, chunk_size=1000):
"""Yield rows from a large CSV file in chunks without loading all into memory."""
with open(file_path, 'r', newline='') as f:
reader = csv.DictReader(f)
chunk = []
for row in reader:
chunk.append(row)
if len(chunk) == chunk_size:
yield chunk
chunk = []
if chunk:
yield chunk
if __name__ == "__main__":
# Create a sample large CSV file
sample_file = Path("large_data.csv")
with open(sample_file, 'w', newline='') as f:
writer = csv.DictWriter(f, fieldnames=["id", "value"])
writer.writeheader()
for i in range(2500):
writer.writerow({"id": i, "value": f"item_{i}"})
# Process it in chunks
total_rows = 0
for i, chunk in enumerate(process_csv_in_chunks(sample_file)):
print(f"Chunk {i}: {len(chunk)} rows (first ID: {chunk[0]['id']})")
total_rows += len(chunk)
print(f"Total rows processed: {total_rows}")
sample_file.unlink() # Clean up test file
Output
Chunk 0: 1000 rows (first ID: 0)
Chunk 1: 1000 rows (first ID: 1000)
Chunk 2: 500 rows (first ID: 2000)
Total rows processed: 2500
How it works
The csv.DictReader reads one row at a time from the file handle, and the generator accumulates rows into a chunk list. When the chunk reaches chunk_size, it yields the list and resets, so only one chunk is ever held in memory. The final if chunk block catches any remaining rows after the loop. This works because open() returns a lazy file object and DictReader iterates over it line by line.
Common mistakes
- Using `csv.reader` instead of `csv.DictReader` so rows come back as lists, not dicts keyed by header
- Forgetting `newline=''` when opening the file, which can cause extra blank lines on Windows
- Not handling the final partial chunk after the loop ends
- Calling `list(reader)` which loads every row into memory and defeats the purpose of chunking
Variations
- Use `pandas.read_csv(..., chunksize=1000)` if you need DataFrame operations per chunk
- Yield a single row's dict instead of a chunk for row-by-row streaming
Real-world use cases
- ETL jobs that must transform hundreds of MB to GB-sized CSVs without exhausting RAM on a worker.
- Batch-uploading rows from a nightly export file to a database or API while keeping memory flat.
- Feeding model training data from a large CSV in minibatches without preloading the entire dataset.
Sponsored
More from Files & data
- Append a Line to a Log File in Python easy
- Audit File Permissions Across a Project in Python easy
- Automatically Detect Corrupted Files Using SHA-256 Checksums in Python easy
- Automatically Highlight Data Validation Errors Inside Excel Files in Python easy
- Build a Command-Line To-Do List Application with Data Persistence in Python easy
- Build a File Index by Relative Path Hash Map in Python easy
Keep learning
Related tutorials and quizzes for this topic.