Skip to content
PHP2Shell: The PHP Bug
Akshay Thakare

Python Generators for Memory-Safe Data Pipelines

Process files far bigger than RAM by streaming records through small generator stages instead of loading lists.

PythonBeginner3 min readUpdated 11 Oct 2026

The problem with lists

Python.py
rows = [json.loads(line) for line in open("events.jsonl")]   # whole file in memory
valid = [r for r in rows if r.get("user_id")]

Each step materialises a full list. A 20 GB file needs well over 20 GB of RAM before anything is written.

Stream instead: one record at a time

A generator yields one value, pauses, and resumes when the next value is requested. Chaining generators gives you a pipeline where only one record is in flight per stage.

Lazy pipeline — one record in flight
read_linesyield line
parseyield dict
validateyield valid row
batchyield 1,000 rows
writebulk insert
Python.py
import json
from itertools import islice
from typing import Iterator
 
def read_lines(path: str) -> Iterator[str]:
    with open(path, encoding="utf-8") as f:
        for line in f:
            yield line
 
def parse(lines: Iterator[str]) -> Iterator[dict]:
    for line in lines:
        yield json.loads(line)
 
def valid(rows: Iterator[dict]) -> Iterator[dict]:
    for r in rows:
        if r.get("user_id") and r.get("ts"):
            yield r
 
def batched(rows: Iterator[dict], size: int = 1000) -> Iterator[list[dict]]:
    while chunk := list(islice(rows, size)):
        yield chunk
 
for chunk in batched(valid(parse(read_lines("events.jsonl")))):
    insert_many(chunk)          # memory stays flat regardless of file size

Why it works

  1. 1

    Nothing runs until you iterate

    Calling parse(...) builds a generator object; no file is read yet.
  2. 2

    The loop pulls one record

    for chunk in ... asks batched, which asks valid, which asks parse, which asks read_lines for one line.
  3. 3

    Each stage holds one item

    Only the current line, dict and the batch buffer exist in memory.
  4. 4

    Bulk writes stay efficient

    Batching restores throughput for the database while keeping memory bounded.

Finished this note?

Share