Streaming JSONL Parser Without Loading the File

When the file is 8GB you cannot json.load it. Here is the generator-based JSONL reader I ship in every data pipeline, plus the malformed-line policy that has saved me twice.

Python
Compiler
3 snippets
py-generators
stream-processing
data-pipeline
clarachoi

By @clarachoi

December 21, 2025

·

Updated August 11, 2026

1,158 views

5

Rate

from __future__ import annotations
import io
import json
from typing import Iterable, Iterator

# JSONL = one JSON object per line. The whole point of the format is that you
# never need the full file in memory. So: open, iterate, json.loads each line.

def iter_jsonl(stream: Iterable[str]) -> Iterator[dict]:
    for line in stream:
        line = line.strip()
        if not line:
            continue
        yield json.loads(line)

# Demo with an in-memory file. In real code: open('events.jsonl', 'r').
sample = '\n'.join([
    '{"id": 1, "event": "login",  "user": "alice"}',
    '{"id": 2, "event": "click",  "user": "alice", "path": "/home"}',
    '',  # blank line, valid in JSONL streams
    '{"id": 3, "event": "logout", "user": "alice"}',
])

for row in iter_jsonl(io.StringIO(sample)):
    print(row)

The shape is a generator over a line iterator, which keeps memory at O(1) regardless of file size. I take Iterable[str] rather than a path because that lets me feed the same parser a real file, an io.StringIO, a network stream, or a gzip.open handle. Skipping blank lines is required by the loose JSONL format used in the wild; producers like Cloud Logging emit trailing blank lines all the time. The eight lines here are enough for a clean dataset.