Skip to content
Performance

Is There a JSON File Size Limit? Browser, Node, Python, and API Limits

·7 min read
Is There a JSON File Size Limit? Browser, Node, Python, and API Limits - Performance guide from JSON Prettifier

Short answer: The JSON specification has no size limit. Every real limit comes from somewhere else: the memory available to the parser, V8's string cap of roughly 512 MB, and the body-size settings of whatever is in front of your code (Express defaults to 100kb, Nginx to 1 MB, AWS API Gateway to 10 MB). As a rule of thumb, single-digit megabytes work everywhere, tens of megabytes need the right settings, and hundreds of megabytes need streaming, pagination, or JSON Lines instead of one giant document.

The nightly export worked for a year. Then the customer table crossed some threshold, the file hit a few hundred megabytes, and the import script started dying with an out-of-memory error at 3 a.m. Nothing in the JSON changed. What changed is that the file crossed a limit nobody knew was there. This post lists those limits, the exact error each one produces, and what to do when you hit them.

Explore a manageable sample in the JSON Viewer. For large inputs, check the file limit and your browser memory before loading the full payload.

The Spec Has No Limit, Which Is the Problem

RFC 8259 section 9 says it plainly: an implementation may set limits on the size of texts it accepts, on nesting depth, on the range of numbers, and on string length. The standard itself sets none. That is deliberate; JSON is a grammar, not a transport. But it means "is this file too big?" has no universal answer. The answer is always "too big for what?"

There are three distinct kinds of limit, and they fail differently:

  1. Parser and runtime limits: string length caps and heap size. These crash the process.
  2. Transport limits: HTTP body-size settings in frameworks, proxies, and cloud gateways. These return 413.
  3. Storage limits: maximum document size in a database or browser storage. These reject the write.

Where the Limits Actually Live

The figures below are defaults as documented by each project at the time of writing. Treat them as approximate and check the current docs before relying on one.

LayerDefault limitWhat you see
V8 string length (Chrome, Node)~512 MB of characters on 64-bitCannot create a string longer than 0x1fffffe8 characters / Invalid string length
Node.js default heapA few GB, version dependentFATAL ERROR: Reached heap limit / JavaScript heap out of memory
Browser localStorage~5 MB per origin (approx.)QuotaExceededError
Express express.json()100kb413 PayloadTooLargeError: request entity too large
Nginx client_max_body_size1m413 Request Entity Too Large
AWS API Gateway (REST)10 MB payload413 Request Entity Too Large
AWS Lambda synchronous invoke6 MB request and responseRequestEntityTooLargeException
MongoDB document16 MB (BSON)BSONObjectTooLarge / document is larger than the maximum size
Elasticsearch http.max_content_length100mb413 / entity content is too long
JSON Prettifier upload5 MBUpload rejected in the browser

JSON Size Limits in the Browser

JSON.parse operates on a string, so the first ceiling is the engine's maximum string length. In V8 (Chrome, Edge, Node) that is 0x1fffffe8 characters, a little under 512 MB on 64-bit builds; older versions were lower. Long before you reach it, two softer limits apply:

  • The parsed object graph takes several times more memory than the source text, because every key, string, and number becomes a separate heap allocation. A 200 MB file can easily need over a gigabyte to hold as objects.
  • JSON.parse is synchronous and blocks the main thread. Parsing even 50 MB freezes the UI for a noticeable moment. Move large parses to a Web Worker.

Browser storage has its own numbers: localStorage is around 5 MB per origin in most browsers, so caching a large API response there throws QuotaExceededError. IndexedDB allows far more but stores structured data, not strings, so the memory point above still applies.

Online formatters have the same constraint plus rendering cost: syntax-highlighting a hundred-megabyte document is slower than parsing it. JSON Prettifier caps uploads at 5 MB for this reason, which covers nearly every API response and config file. For bigger files, the validating large JSON in the browser post explains what works and what does not, and best formatters for large responses compares the options.

JSON Size Limits in Node.js

Node shares V8's string cap, and you hit it earlier than you expect because reading a file with an encoding builds the string in one go:

const text = fs.readFileSync("huge.json", "utf8");
// Error: Cannot create a string longer than 0x1fffffe8 characters
//   code: 'ERR_STRING_TOO_LONG'

Below that cap, the heap limit takes over. Node's default old-space size is a few gigabytes on 64-bit systems (the exact figure depends on the version and available memory), and a parse that needs more ends with:

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory

You can raise it with node --max-old-space-size=8192 script.js, and sometimes that is the pragmatic fix for a one-off import. It is not a fix for a pipeline that grows. For that, stream.

Streaming with stream-json

stream-json parses the file as it is read and emits each top-level array element as a separate object, so memory stays flat no matter how large the file is:

npm install stream-json stream-chain
const fs = require("fs");
const { chain } = require("stream-chain");
const { parser } = require("stream-json");
const { streamArray } = require("stream-json/streamers/StreamArray");

const pipeline = chain([
  fs.createReadStream("orders.json"),   // [ {...}, {...}, ... ]
  parser(),
  streamArray(),
]);

let total = 0;
pipeline.on("data", ({ value }) => {
  total += value.amount;
});
pipeline.on("end", () => console.log("total:", total));

The trade-off is that you lose random access. You see each record once, in order, and you have to decide what to keep. For most imports and aggregations that is exactly the shape you want anyway.

JSON Size Limits in Python

Python has no practical string-length cap on 64-bit systems, so json.load is limited only by RAM. The memory multiplier is similar to Node: a parsed dict-and-list tree is several times larger than the text, and Python objects carry more overhead per item than V8 objects. When json.load is killed by the OS or raises MemoryError, switch to ijson, which walks the file incrementally:

pip install ijson
import ijson

total = 0
with open("orders.json", "rb") as f:
    for order in ijson.items(f, "item"):   # "item" = each element of the top-level array
        total += order["amount"]
print(total)

The second argument is a path prefix. "item" means each element of a top-level array; "results.item" would iterate the array under a results key. Open the file in binary mode; ijson handles the UTF-8 decoding itself.

HTTP Body Limits: Why You Get 413

A 413 means a layer in front of your handler refused the body. Work outward from the app, because each layer has its own default and the smallest one wins.

Express

// default is "100kb"; a 2 MB POST fails with:
// PayloadTooLargeError: request entity too large

app.use(express.json({ limit: "10mb" }));

Nginx

# nginx.conf, inside http, server, or location
client_max_body_size 20m;   # default is 1m

After editing, nginx -t then reload. If the 413 page is Nginx's own HTML rather than your app's JSON error, this is the layer.

Cloud gateways

Managed gateways generally cannot be raised. AWS API Gateway REST APIs reject payloads over 10 MB, and a synchronous Lambda invocation is limited to 6 MB in each direction, as documented by AWS. The standard workaround is to upload large bodies directly to object storage (a pre-signed S3 URL, for example) and send the API a reference, not the data.

The JSON in REST APIs guide covers the response side, where the same limits apply and pagination is the usual answer.

Strategies for Large JSON

Pick by whether you control the producer, the consumer, or both.

  1. Paginate. If the data comes from an API, ask for it in pages of a few hundred or thousand records. It is the cheapest fix and the one every consumer can handle.
  2. Switch to JSON Lines. One JSON object per line, no outer array. Any line reader can process it with constant memory, it appends cleanly, and it splits across files with split -l. See JSON Lines explained for the format and converters.
  3. Stream the parse. When the file is already a single giant document and you cannot change it, use stream-json, ijson, Jackson's streaming API, Go's json.Decoder with Token(), or jq --stream.
  4. Compress in transit. Repeated keys can make JSON compress well, but measure your payloads rather than assuming a saving. Negotiate response compression separately from compressed uploads, and enforce decoded-size limits as well as wire-size limits. Use these six JSON API compression checks to test headers, decoder ownership, resource budgets, and streaming delivery before enabling it.
  5. Minify and trim. Removing whitespace, as covered in how to minify JSON, typically shaves a modest percentage; dropping null fields and shortening repeated keys can shave more. Useful at the margin, not a substitute for the options above.
  6. Consider a binary format. If both ends are yours and the volume is sustained, Protocol Buffers or MessagePack cut size and parse time substantially. The JSON vs Protobuf comparison lays out when that is worth the loss of readability.

Common Mistakes

  • Raising the limit instead of asking why. Bumping express.json to 50mb works until it is 60. Limits exist partly as a denial-of-service guard; a huge limit lets any client make your server allocate hundreds of megabytes per request.
  • Reading the whole file to count records. JSON.parse(text).length on a multi-gigabyte array is the classic 3 a.m. crash. Stream it, or if it is JSON Lines, wc -l.
  • Pretty-printing large exports. Indentation can add 20 to 40 percent to file size for deeply nested data and buys nothing for a file no human will read. Write compact; format a sample when you need to inspect it.
  • Assuming the 413 came from your app. It often came from the proxy. Check the response body and Server header before touching application config.
  • Storing arrays-of-everything in one MongoDB document. The 16 MB BSON cap is per document. Growing a single document with an ever-expanding array hits it eventually; model the items as separate documents.

Frequently Asked Questions

What is the maximum size of a JSON file?
There is no maximum defined by the JSON specification. RFC 8259 places no limit on the length of a JSON text, the nesting depth, or the size of a string or number. Real limits come from the memory of the machine parsing it and from the servers, gateways, and libraries the file passes through.
How large a JSON file can JavaScript parse?
JSON.parse takes a string, and V8 caps string length at roughly 512 MB of characters on 64-bit builds, so that is a hard ceiling in Chrome and Node. In practice you hit memory pressure well before that, because the parsed object tree takes several times more memory than the text. For anything over a few hundred megabytes, use a streaming parser.
Why does my API return 413 for a JSON request?
Something between the client and your handler has a body-size limit smaller than your payload. Common defaults are 100kb in Express's express.json(), 1 MB in Nginx's client_max_body_size, and 10 MB on AWS API Gateway. Find which layer sent the 413 by checking the response headers and server logs, then raise that limit or shrink the payload.
How do I handle a JSON file that is too large to load into memory?
Use a streaming parser that emits one record at a time instead of building the whole tree: stream-json in Node, ijson in Python, Jackson's streaming API in Java, or jq --stream on the command line. If you control the producer, switch to JSON Lines so each line is an independent document you can read with a plain line reader.
Does compressing JSON help with size limits?
It helps with transfer and storage limits, since JSON's repeated keys and whitespace compress very well with gzip or Brotli, often by several times. It does not help with parser or memory limits, because the file is decompressed before it is parsed. Minifying helps a little with both but is no substitute for streaming or pagination.

Format and Validate Files Up to 5 MB

Upload or paste your JSON, format it, minify it, or check it for errors. It all runs in your browser, so nothing is sent to a server.

Open JSON Prettifier