Why can JSON become a problem?

JSON is everywhere. I probably use it every day, whether to exchange data with an API, temporarily or permanently store information, configure an application, or transfer data between different services.
It is simple, readable, and supported by virtually every programming language. But that simplicity can sometimes be misleading.
A small JSON file of a few kilobytes is usually not a problem. But as volumes grow, certain limitations start to appear: file size, memory consumption, parsing time, network transfer, and deeply nested structures.
And as is often the case, what works perfectly with 100 items can become much less enjoyable with 10 million. Let's see why.
JSON Is simple... Up to a certain size
Let's start with a very simple example:
{
"id": 123,
"name": "Cyril",
"email": "cyril@example.com"
}It is hard to make it any simpler. A program can load this JSON, parse it, and quickly access the different properties.
Now imagine exactly the same thing with several million records. The problem is no longer really the JSON format itself. It is the amount of data we are trying to push through that format.
A file of a few megabytes may be perfectly acceptable. A file of several gigabytes is a different story.
Parsing can consume a lot of memory
This is probably one of the most important issues. When we do something like:
$data = json_decode(file_get_contents('data.json'), true);we are asking PHP to read the file and build a usable representation of its contents. That representation can take up much more space than the original file.
Imagine a 500 MB JSON file. That absolutely does not mean our application will only need 500 MB of memory.
Depending on the structure of the data and the language being used, memory consumption can quickly become much higher.
And that is when we may encounter the famous "Allowed memory size exhausted" error. That kind of message is not particularly pleasant to see. It is a good example of a problem that may never appear with 10,000 items but becomes obvious when we move to several million.
Complex structures do not help
A JSON document can easily become deeply nested:
{
"users": [
{
"id": 1,
"name": "Cyril",
"orders": [
{
"id": 100,
"items": [
{
"product": {
"id": 50,
"name": "Keyboard"
}
}
]
}
]
}
]
}This structure may be perfectly justified.
But the more complex the document becomes, the harder it is to work with. Accessing a piece of information may require navigating through multiple levels of objects or arrays.
And with thousands or millions of elements, that complexity also affects file size and the amount of memory required to process the data.
JSON can contain a lot of repetition
Another issue comes from the nature of the format itself.
Consider:
[
{
"id": 1,
"first_name": "Cyril",
"last_name": "Smith",
"country": "France"
},
{
"id": 2,
"first_name": "Jane",
"last_name": "Smith",
"country": "France"
}
]Property names are repeated for every object. With a few dozen or even a few hundred elements, this is obviously not a problem. But with millions of objects, those repetitions represent a significant amount of data.
This is one of the reasons why other formats can become attractive as volumes grow.
Network transfers can become expensive
A large JSON document also has to be transferred. Imagine an API returning 100 MB of JSON for a single request.
Even if the server generates the response quickly, the client still has to download it, potentially decompress it, and then parse it.
And 100 MB is not exactly the same as 100 KB.
We therefore have several stages:
Database
↓
Application
↓
JSON Generation
↓
Network Transfer
↓
Download
↓
Client-Side Parsing
↓
Data UsageOptimizing only one part of the chain does not necessarily solve the overall problem. Compression such as gzip (or another method) can significantly reduce the amount of transferred data, but it does not eliminate parsing costs or client-side processing costs.
Processing large JSON files is not always easy with streaming
This is a particularly interesting point.
With a large file, we might want to do something like:
read some data
↓
process it
↓
discard it
↓
read the next chunkinstead of:
load the entire file
↓
parse the entire file
↓
process all contentsThe problem is that we often treat JSON as a complete document:
[
{"id": 1},
{"id": 2},
{"id": 3},
{"id": 4}
]Processing such a document incrementally is possible with some parsers, but it can be more complicated than using a format designed to handle independent records.
This is where JSON Lines, or JSONL, becomes interesting.
JSONL: A simple solution for large volumes
Imagine a file containing 10 million users.
With a large JSON array, we might have:
[
{"id":1,"name":"Cyril"},
{"id":2,"name":"Jane"}
]With JSONL:
{"id":1,"name":"Cyril"}
{"id":2,"name":"Jane"}We can then read the file line by line.
In PHP, something as simple as:
$handle = fopen('users.jsonl', 'r');
while (($line = fgets($handle)) !== false) {
$user = json_decode($line, true);
// Process the user
}
fclose($handle);allows us to process data progressively. We no longer need to load all 10 million users into memory at once. We can read and process data incrementally without loading the entire file or stream into memory.
This is particularly useful for imports, exports, and large-scale data processing.
Of course, that does not mean JSONL is always better. It depends entirely on the use case. If you work with JSON and JSONL, you can find some useful tools at https://jsoning.com/.
Large JSON files can also be difficult to debug
Another issue appears when a file becomes huge.
Finding an error in `data.json` with a few hundred lines is relatively easy.
Doing the same in a file that is several gigabytes in size is much less enjoyable.
And if the JSON is invalid because of a missing character somewhere in the middle of the file, finding the exact source of the problem can be difficult.
Tools capable of handling large files become especially useful in those situations.
And while AI can help analyze a small JSON file, sending several gigabytes of data to find an error is obviously not a very realistic solution.
Compression still matters
JSON can be quite verbose.
The good news is that it usually compresses very well.
A JSON response containing many repeated property names can shrink significantly with gzip or Brotli.
For example, an API may return several hundred kilobytes of uncompressed JSON but much less once compressed.
For network transfers, that can make a significant difference.
But compression obviously does not solve everything. The client still has to decompress and parse the data.
Should we stop using JSON?
Of course not.
JSON remains extremely practical. For an API, a configuration file, a small data file, or data exchange between applications, it is often difficult to find something simpler.
The problem begins when we try to make it do something it is no longer particularly suited for.
A small 10 KB JSON document usually raises no questions.
A 10 GB document should probably make us think a little more.
And between those two extremes, there are obviously many intermediate cases.
Conclusion
I love JSON. I find it simple and easy to read once formatted. For small volumes, it is often an excellent choice.
But as data grows, we need to start asking the right questions: memory, parsing, transfer costs, streaming, and processing.
The problem is not JSON itself, but sometimes the scale at which we use it. And when requirements evolve, moving to JSONL is often very simple to implement.