1. The Memory Problem with Standard `json.load()`
When standard `json.load(file)` parses a JSON object, Python creates internal PyObject instances for every key, string, integer, array, and dict node. A 500 MB raw JSON file on disk can consume over 3 GB of active RAM when converted into a native Python dictionary hierarchy due to PyObject pointer overhead.
# ❌ NAIVE APPROACH (Fails on 2 GB File - MemoryError!)
import json
with open("massive_database_dump.json", "r") as f:
data = json.load(f) # Tries to allocate gigabytes of RAM at once
# ✅ STREAMING APPROACH (Uses < 10 MB RAM!)
import ijson
with open("massive_database_dump.json", "rb") as f:
# Iterates over objects in the 'records' array one item at a time
records = ijson.items(f, "records.item")
for record in records:
process_record(record) # Constant low memory consumption2. Streaming JSON Arrays with `ijson`
`ijson` is an iterative JSON parser for Python built on top of YAJL (Yet Another JSON Library). It generates Python generator iterators that yield JSON items on-the-fly as they are read from disk.
import ijson
def extract_errors(file_path):
with open(file_path, "rb") as f:
# Parse objects inside root array
for item in ijson.items(f, "item"):
if item.get("status") == "error":
yield item["message"]
# Efficiently print error logs from a 5 GB file
for error_msg in extract_errors("server_logs.json"):
print(f"CRITICAL ERROR: {error_msg}")Pro Tips
- Install ijson via `pip install ijson`.
- Always open the file in binary read mode (`"rb"`) for optimal ijson performance.
3. Line-Delimited JSON (JSONL) Streaming
For ultra-large datasets (10 GB+), data engineering teams often structure data as JSON Lines (`.jsonl` or `.ndjson`). Each line contains an independent, valid single-line JSON string. Parsing JSONL files requires zero third-party libraries:
import json
# Read 20 GB JSONL file line-by-line using Python standard library
with open("analytics_events.jsonl", "r", encoding="utf-8") as f:
for line_number, line in enumerate(f, 1):
if not line.strip():
continue
event = json.loads(line) # Parse single line
if event.get("event_type") == "purchase":
track_purchase(event)