How big a JSON file can a browser actually open?
Short answer: about 512 MB in Chrome, about 1 GB in Firefox and Safari. Here is where those numbers come from and how to check them yourself.
Every JavaScript engine caps how long a single string can be. That cap is the real ceiling
for anything that reads a file into a tab, because the usual first step is to decode the
bytes into one string and hand it to JSON.parse. Go past the cap and you get a
RangeError, no matter how much memory the machine has.
The caps are not the same across engines. I measured them:
| Engine | Longest string | Mostly ASCII file |
|---|---|---|
| Chromium (V8) | 536,870,888 | ~512 MB |
| Firefox (SpiderMonkey) | 1,073,741,822 | ~1 GB |
| Safari (JavaScriptCore) | at least 1,073,741,824 | ~1 GB |
Those are 229 − 24 and 230 − 2. In Safari the exact figure sits somewhere between 230 and 231; I only confirmed that 230 works and 231 does not.
Check it yourself
Paste this in a console. It costs nothing when it fails, since the length check happens before anything is allocated.
const fits = (n) => { try { return "a".repeat(n).length === n } catch { return false } }
fits(2 ** 29 - 24) // Chrome: true
fits(2 ** 29 - 23) // Chrome: false, RangeError: Invalid string length
fits(2 ** 30 - 2) // Firefox: true
Binary search from a size you know fails and you will land on the exact number for whatever you are running.
Bytes are not characters
The cap counts characters, not bytes. A UTF-8 file decodes to at most as many characters as it has bytes, and usually fewer. So a 1 GB file made mostly of CJK text or emoji can fit in Chrome, while a 600 MB file of plain ASCII will not. Configuration and log data is nearly always ASCII, which is why the practical Chrome ceiling lands around 512 MB.
A byte order mark does not help either way. It gets stripped during decoding, so it is worth three bytes and nothing else.
The second ceiling nobody mentions
Holding the text is only half of it. JSON.parse then builds an object graph, and
that graph is bigger than the text it came from. Small objects with short keys are the worst
case, because every one of them carries the overhead of a JavaScript object.
In practice this is less of a problem than it sounds, at least up to the string limit. I loaded a 450 MB document with 26 million nodes into a tab and watched it:
read 186 ms
parse 1,933 ms
index 663 ms
search over the whole document 1.4 s
expand all, 3.2 million rows 0.5 s
Nothing there is close to failing. The wall is the string, and it arrives before memory or speed becomes the problem.
What to do when your file is bigger
You have three options, and the first one is often enough.
- Open it in Firefox or Safari. Same file, same page, twice the headroom. This is not a joke answer. If you are 600 MB into a 512 MB limit, switching browsers is faster than anything else on this list.
-
Split it. If the document is one big array,
jq -c '.[]'turns it into newline delimited JSON, which you can cut withsplitand open in pieces. NDJSON also streams, so tools can read it a line at a time. -
Use a terminal tool.
jqfor querying,jlessfor browsing. They index the bytes instead of building an object graph, so they are not bound by any of this. The tradeoff is that you are back in a terminal.
Why not fix it in the browser?
You can, but not cheaply. The fix is to stop holding the document as text at all: keep the
raw bytes in an ArrayBuffer, scan them once, and record a byte offset, a length
and a type per node in typed arrays. Values get decoded only when something needs to display
them. That is roughly how jless works, and it would handle multiple gigabytes.
The cost is that you give up JSON.parse, which is native code and much faster
than anything you can write in JavaScript. For the 99% of files that fit comfortably today,
you would be trading speed for a ceiling most people never reach. That is a different
product, not a patch.
Try it
jsontree.app opens JSON, YAML and XML as a collapsible tree, up to whatever your browser allows. If your file is too big it says so straight away, with the character count, instead of failing after a minute of reading.
Open a file