Exploring Alternatives: Are There Better Options Than JSON?
Tags: webdev, protobuf, messagepack, opensource
Published: 2024-02-16 16:43:13

A while back, I stumbled upon a captivating article titled “[JSON is incredibly slow: Here’s What’s Faster!](https://medium.com/data-science-community-srm/json-is-incredibly-slow-heres-what-s-faster-ca35d5aaf9e8)” It almost immediately caught my attention because, let’s face it, who doesn’t like shiny trinkets that make their apps run faster? But as I dug deeper, something felt off. So, I decided to not only take another look at these alternatives but also put them to the test.

Here are the key points I’d like to focus on and discuss: JSON has serialization overhead,  offers a limited set of data types, and is bloated and too verbose, so there are at least four supposedly faster alternative exchange formats to use.

Let’s kick things off with the basics. No format can eliminate serialization overhead, given the internet’s reliance on various transfer protocols for serialized data. We can try to optimize whatever we want, but unless there’s an alternative to HTTP itself, we’ll be serializing data back and forth.

Now, onto the alternatives mentioned in the article: Protocol Buffers (protobuf), MessagePack (msgpack), BSON, and Apache Avro. I would exclude BSON and Avro from this experiment as they cater to more niche use cases, so applying them to a typical client-server exchange might prove challenging even for a simple playground app.

One thing mentioned is JSON’s lack of binary data and functions support. Here’s where all the alternatives shine, as they are binary. However, none of the suggested formats still offer functions. Don’t get me wrong, but why overcomplicate things and pass functions? Doing so will not only disperse the business logic of an application but also introduce unnecessary complexity because the receiving end, whether it’s a client-side part running on JavaScript or another service created in a different language, might be unable to execute such functions either way, the sender will be responsible for creating a function in a language foreign to itself.

Next up is verbosity. With most applications split into backend and frontend components, each can and has its own bugs. Consider what an experienced QA engineer familiar with the project enough and aware of some technical details does when they find a problem and need to file a Jira issue: they open DevTools, look through the data received from the backend, and assign the corresponding label. Swapping out JSON, or XML for that matter, for a binary format will make it harder for both QA engineers and developers to trace issues. So developers will have to use breakpoints to investigate even the tiniest issue, which wouldn’t take much time, but you know how problems sometimes pile up.

{% collapsible A side-by-side comparison of JSON, msgpack, and protobuf responses %}
![A JSON response](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y5uy9jbkmmmy175jl8i9.png)
![A msgpack response](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/al7d7iz6o17hsmpg9d4a.png)
![A protobuf response](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qnmcy00t554j72e9j5a8.png)
{% endcollapsible %}

Let’s imagine that we weighed all the risks and prepared automated tests of all sorts, but the question remains: do we truly need an alternative to JSON, or is it doing just fine? I take software benchmarks with a grain of salt, often seeing them as a part of marketing, just like the battery life in fancy smartphone presentations. That’s why if I can’t get some good reviews, I roll up my sleeves, set up playgrounds, and try to replicate real-life conditions. Who cares how fast a protocol can serialize data if the roundtrip time is still the same?

Here are the results:
{% embed https://gist.github.com/GinMitch/c9114f7df089d6578d7045f5222a73b4 %}
(lower numbers are better)

Evidently, protobuf is a winner regarding medium-sized requests, at least in transfer size, which is crucial for clients with poor internet connection. But if you’ve noticed the gaps in the table, you got to the juiciest part – missing measurements. But why so?

Countless times, I’ve encountered a nice piece of software that either had no examples whatsoever or the ones provided were so unhelpful that I spent hours trying to make things work. The same goes for protobuf and msgpack – both lack solid working examples. Sure, Spring supports protobuf [out of the box](https://spring.io/blog/2015/03/22/using-google-protocol-buffers-with-spring-mvc-based-rest-services), and there are indeed [good examples](https://github.com/thomasdarimont/spring-boot-protobuf-example/blob/master/src/main/java/demo/CustomerRestController.java) and [even guides](https://www.baeldung.com/spring-rest-api-with-protocol-buffers) on how to start using [either of them](https://github.com/making/spring-mvc-msgpack-sample/blob/master/src/main/java/com/example/App.java), but a closer look at the table reveals a significant issue – the absence of POST requests. It’s not that Spring can’t handle them; it’s just incredibly tedious to implement. Even though Java is not my primary skill, I’ve spent about 20 hours trying to crack that nut.

Yet I’m grateful for the open-source software we already have and that there are potential alternatives to JSON, but if you’re putting something out there and expecting others to use it, please at least provide some basic and, most importantly, working examples.

How do companies like Okta and LinkedIn make it all tick? One might assume they’ve got deep pockets to throw at such challenges, but unfortunately, not all of us can afford that luxury. That’s why I invite you to take part in building a one-stop collection of working examples, making these technologies more accessible to those with fewer resources. If you can contribute, you’re more than welcome to the repo: [https://github.com/GinMitch/better-than-json](https://github.com/GinMitch/better-than-json).