The DX for JSON things is much better. The UX for protobufs is much better (faster, less data over the wire, etc). Which you optimize for is up to you, but there isn't a straightforward "Use this tech because it's the best one."
The DX for JSON things is much better. The UX for protobufs is much better (faster, less data over the wire, etc). Which you optimize for is up to you, but there isn't a straightforward "Use this tech because it's the best one."
I've always wondered about this. Firstly, I'm fairly sure clientside JSON parsing is significantly faster than protobuf decoding but even data over the wire: JSON can be pretty compressible so surely the gains here are going to be marginal. Surely never enough benefits to UX to warrant the DX trade off, right?
It also shows a difference of 388ms (protobuf) vs 396ms (JSON) which is pretty negligible. Certainly not orders of magnitude.
Do you have other sources?
[0] https://auth0.com/blog/beating-json-performance-with-protobu...
Third link is also server-side, but since it's NodeJS it's at least close enough / more relevant to client-side perf.
Here's the benchmark from the third link:
benchmark time (avg) (min … max)
---------------------------------------------------
encode-JSON 342.37 µs/iter (311.93 µs … 1.19 ms)
decode-JSON 435.9 µs/iter (384.44 µs … 1.41 ms)
encode-PB 946.43 µs/iter (777.38 µs … 3.13 ms)
decode-PB 770.79 µs/iter (688.99 µs … 1.78 ms)
encode-PBJS 696.75 µs/iter (618.43 µs … 2.43 ms)
decode-PBJS 455.36 µs/iter (413.66 µs … 1.09 ms)
showing JSON to be significantly fasterin any case, that's the only time i've ever seen it used in production. the first link is a go benchmark that i felt represented why someone would use it for those purposes, the second was linked to show that despite numerous (successful!) attempts to make deserializing/serializing data faster and smaller, JSON is still the most heavily used and i would wager it's mostly due to how easy it is to use as far as browsers are concerned. the third was a link to justify that claim and show that js-land is much, much different than go-land as far as proto's and JSON encoding/decoding are concerned!
So yeah not a whole order of magnitude. I was using my experience as a guide where JSON parsing is a huge compute hog and Protobuf is not.
I've never experimented w/ Javascript or compression or any of the other things in that article, I guess YMMV.
Clientside is always going to be the pertinent metric for UX since it's processed on the user's device.
I feel like I'm having to repeat myself a lot here as noone seems to have read the original comment correctly: we're talking about one specific language in one specific known environment here. Noone is claiming that JSON outperforms PB in general: only that it does in browsers, where it's actually relevant for UX.
Where I’m working now, we have a REST API for users to interact with and every call behind the scenes is proto. As we deal with quite large objects, the benefits of avoiding repeated serialization and deserialization add up quickly.
From the user’s perspective we have a performant app, and much of this is possible due to proto.
So it sounds like the trade-off can be worthwhile in some cases: particularly for large objects where serialisation is a significant serverside bottleneck.
I'm curious: you say PB helps avoid "repeated serialisation/deserialisation": how? In my mind, architecting an app that uses JSON/PB on the wire serialisation happens once on output & deserialisation happens once on input. For both transfer formats. Surely you wouldn't be passing massive json strings around your app in memory?
Also curious which is the bigger bottleneck for your large objects: input or output. How large is large?
It id also not only the speed but also size is usually a magnitude off (and no, compression doesn't cut it and trades size again for computation).
Sure, if size and speed do not matter it is strange that you had considered protobuf at all.. but claiming they are never needed just means you have never been to resource constrained systems?
What you cite there, I assume most of that 400ms has nothing to do with the message encoding at all btw..
(b) I'm talking about a narrow & specific case. PB may outperform JSON in most cases but I'm very specifically referring to browsers where JSON is native (& highly optimised) whereas PB is provided by a selection of open source libraries written in javascript. So that domain heavily favours JSON perf-wise.
No, not at all... coming from embedded where apeed, memory size and also bandwidth did count, json was actually.not just worse, but just wouldn't have been feasible (because our protobufs already barely fit memory and MTU constraints).
I'm sure given two implementations of equal quality protobuf would easily outperform JSON, but I can also believe the JSON implementation in (for example) v8 is very, very hard to beat.
Of course, I might use protobuf because I prefer it in my code to JSON, and it certainly is faster (if only twice).
Json parsing is also a lot of special cases, error testing, but the v8 team has spent a huge amount of time optimising json parsing (theres a few blog posts on it). Im not assuming either way, but it's definitely as cut and dry as one would assume.
However, "packed" fields are exactly a length followed by a byte array of the typed data. This was an oversight in original proto2 which is unlikely to be corrected, but packed the default in proto3.
a few months ago i tested https://github.com/mapbox/pbf and while it was faster for deep/complex structs vs an unoptimized/repetative JSON blob, it was much slower at shallow structs and flat arrays of stuff. if you spend a bit of time to encode stuff as flat arrays to avoid mem alloc, JSON parsing wins by a lot since it goes through highly optimized C or assembly, while decoding protobuf in the JS JIT does not.
of course it's not always feasible to make optimized over-the-wire JSON structs if you have a huge/complex API that can return many shapes of complex structs.
we were streaming a few hundred float datapoints spread across a dozen(ish) flat arrays over websocket at 20-40hz and needed to decode the payload eagerly. plain JSON was a multi-factor speedup over pbf for this case. but it's fully possible i was holding it wrong, too!
even when your "bottleneck" is rendering/rasterization (10ms), but your data pipe takes 3ms instead of 1ms, it's a big effect on framerate, battery, thermals, etc.
i'm a big fan of your work! while i have you here, would you mind reviewing this sometime soon? ;)
PB can always be decoded to a text representation if you need to inspect it.
I once doing a mixing of two buffers that contains PCM. A simple task that take two number, average and put into another buffer. The native implementation is about 10x fast than the one I wrote with JS (Or consume 10X less cpu time).
A native Protobuf is definitely going to beat a native JSON implementation. A JS Protobuf if also likely to beat a JS JSON implementation.
But a JS Protobuf to native JSON? I doubt.
There's nothing in your comment that hadn't already been said before by sibling commenters but as far as I've seen in the real world JSON appears to be faster in practice. Which is all that counts.
Yours and the many other commenters making the same assumption (it's binary ergo it must be fast) make a really good case for PB's adoption being rooted in theoretical assumptions rather than real-world benefit.
I get it. It makes sense that it should be faster. Nothing is self evident though. You gotta measure it.
https://auth0.com/blog/beating-json-performance-with-protobu...
This thread is about protobuf vs JSON in a JavaScript environment.
The article you linked _does_ talk about JavaScript environments, too, but the numbers are much less impressive.
I'm saying that computer science and hardware dictate that protocol buffers are faster for a wide range of reasons. That part's not in question- smaller data encodings have better cache use, and require far fewer dictionary (hash table) lookups at parse time, as well as far length work parsing strings. If you want to argue against my point there I don't know what to say.
If it was a priority to write a blindingly fast protocol buffer parser in JS, it's almost certain than an expert could write a faster one than a similar JSON parser.
My attitude here is that I made a specific observation: JSON is likely to be faster or at least negligibly slower in browsers in practice.
Everyone is replying either with theoretical speed comparisons or server-to-server non-JavaScript benchmarks, which don't seem relevant to my very specific observation I made up top...
This is doable with JSON, but I've never seen a JSON based setup actually work well at catching these kind of regressions.
More features is not a measure of better UX. In many cases (most cases!?) it's the opposite.
That's mostly been down to having IDE autocompletion for data structures and fields once the protobuf code's been generated.
For many JSON APIs I've worked with there's only been human readable documentation, making them more error prone to work with (e.g. having to either craft JSON manually for requests, or writing a client library if one doesn't already exist).
Backend was with Absinthe+Elixir, so it was great (if I had to do it again today I would instead use Liveview, this was in 2017 where I had to retrofit a React app into something useable).
Public user facing is a different story, the last major one I saw was Tableau, though they are also business facing where they can just ban bad users. Github also has deprecated their GraphQL endpoints[0].
[0] https://github.blog/changelog/2022-08-18-deprecation-notice-...
To be fair, it sounds like that would just make the DX wonderful no matter which stack you were using?
Only if you have a very competent backend team, who, apart from dataloader, will have to figure out caching.
> /less data
Graphql responses tend to be pretty deeply nested.