The Problem with Large JSON
JSON.parse() loads the entire file into memory, builds a complete object tree, and only then returns. For a 500 MB file, this means ~2 GB of RAM used:
| File Size | Parse Time (Node.js) | Memory Used | Approach |
|---|---|---|---|
| 1 MB | ~8 ms | ~4 MB | JSON.parse() — fine |
| 10 MB | ~80 ms | ~40 MB | JSON.parse() — acceptable |
| 100 MB | ~800 ms | ~400 MB | Consider streaming |
| 500 MB | ~4 s | ~2 GB | Must stream |
| 1 GB+ | Crashes (OOM) | N/A | Must stream or use JSON Lines |
JSON Lines (NDJSON)
The simplest solution for large datasets: one JSON object per line, separated by newlines.
Standard JSON Array
[ {"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}, {"id": 3, "name": "Charlie"}]Must read entire file to validate. Can't append without rewriting.
JSON Lines (.jsonl)
{"id": 1, "name": "Alice"}{"id": 2, "name": "Bob"}{"id": 3, "name": "Charlie"}Process line by line. Append with a single write. Stream-friendly.
| Feature | JSON Array | JSON Lines |
|---|---|---|
| Stream processing | ✗ (need full file) | ✓ (line by line) |
| Append data | ✗ (rewrite file) | ✓ (append line) |
| Parallel processing | ✗ | ✓ (split by lines) |
| File validity | All-or-nothing | Per-line validity |
| Concatenation | Complex | Just cat files together |
| Tool support | Universal | jq, ndjson-cli, most DBs |
Streaming Parsers
Node.js — JSONStream
1import { createReadStream } from 'fs';2import JSONStream from 'JSONStream';34const stream = createReadStream('users.json', 'utf-8');5const parser = JSONStream.parse('*'); // each array item67let count = 0;8parser.on('data', (user) => {9 count++;10 // Process one user at a time — constant memory11 processUser(user);12});1314parser.on('end', () => {15 console.log(`Processed ${count} users`);16});1718stream.pipe(parser);Node.js — Process JSON Lines
1import { createReadStream } from 'fs';2import { createInterface } from 'readline';34const rl = createInterface({5 input: createReadStream('events.jsonl', 'utf-8'),6 crlfDelay: Infinity,7});89for await (const line of rl) {10 if (line.trim()) {11 const event = JSON.parse(line);12 processEvent(event);13 }14}Python — ijson
1import ijson23with open('huge_data.json', 'rb') as f:4 # Stream each item in the "users" array5 for user in ijson.items(f, 'users.item'):6 process_user(user)7 # Memory stays constant regardless of file sizeCommand Line — jq
1# Stream array items2jq -c '.users[]' huge_data.json | while read -r user; do3 echo "$user" | jq '.name'4done56# Convert JSON array to JSON Lines7jq -c '.[]' array.json > output.jsonl89# Filter JSON Lines10cat events.jsonl | jq -c 'select(.type == "error")'Browser Strategies
Web Workers for Large JSON
Parsing large JSON blocks the main thread, freezing the UI. Move parsing to a Web Worker:
1// In the Web Worker2self.onmessage = async ({ data: { url } }) => {3 const res = await fetch(url);4 const json = await res.json(); // parse off main thread5 self.postMessage({ result: json });6};Fetch with Streaming
1const response = await fetch('/api/export');2const reader = response.body.getReader();3const decoder = new TextDecoder();4let buffer = '';56while (true) {7 const { done, value } = await reader.read();8 if (done) break;910 buffer += decoder.decode(value, { stream: true });11 const lines = buffer.split('\n');12 buffer = lines.pop() || ''; // keep incomplete line1314 for (const line of lines) {15 if (line.trim()) {16 const item = JSON.parse(line);17 renderItem(item); // process incrementally18 }19 }20}Optimization Techniques
| Technique | When to Use | Memory Savings |
|---|---|---|
| JSON Lines | Log files, data exports, ETL | ~95% |
| Streaming parser | Processing arrays item-by-item | ~90% |
| Chunked splitting | Parallel processing | Per-chunk limit |
| JSON.parse with reviver | Filter during parse | Moderate |
| Binary formats (MessagePack) | High-performance IPC | 30-50% file size |
| Compression (gzip) | Network transfer | 70-90% transfer size |
Quick Win
?format=jsonl option that returns JSON Lines instead. This lets clients stream the response and reduces memory on both sides.Try These Tools
Try It Yourself
This is a small JSON array. Imagine it with 10 million items — that's when you need streaming.
Try It Yourself
Validate this JSON — then think about how JSON Lines would look