DEV Community

Alex Pliutau
Alex Pliutau

Posted on • Updated on

Benchmarks comparing gRPC+Protobuf vs JSON+HTTP in Go

grpc-json.png

Simplest possible solution for communication between services is to use JSON over HTTP. Though JSON has many obvious advantages - it’s human readable, well understood, and typically performs well - it also has its issues. In the case of internal services the structured formats, such as Google’s Protocol Buffers, are a better choice than JSON for encoding data.

gRPC uses protobuf by default, and it's faster because it's binary and it's type-safe. I coded a demonstration project to benchmark classic REST API using JSON over HTTP vs same API in gRPC using Go.

This repository contains 2 equal APIs: gRPC using Protobuf and JSON over HTTP. The goal is to run benchmarks for 2 approaches and compare them. APIs have 1 endpoint to create user, containing validation of request. Request, validation and response are the same in 2 packages, so we're benchmarking only mechanism itself. Benchmarks also include response parsing.

I use Go 1.9 and results show that gRPC is 10 times faster for my API:

BenchmarkGRPCProtobuf-8        10000        197919 ns/op
BenchmarkJSONHTTP-8             1000       1720124 ns/op
Enter fullscreen mode Exit fullscreen mode

CPU usage comparison

Restart applications, then use profiling tool pprof during 30 sec when the client is talking to the server with these commands:

go tool pprof http://localhost:6060/debug/pprof/profile
go tool pprof http://localhost:6061/debug/pprof/profile
Enter fullscreen mode Exit fullscreen mode

Run tests to get client connections. Then in each pprof run top to see CPU usage.
My results show that Protobuf consumes less ressources, 30% less.

Test it by your own

If you want to test it by yourself you can clone this repository and run the following commands:

glide i
go run grpc/main.go
go run json/main.go
go test -bench=.
Enter fullscreen mode Exit fullscreen mode

Conclusion

It's totally clear that for internal-only communication it's better to use gRPC, your client calls will be much cleaner, you don't have to mess with types and serialization, because gRPC does it for you.

Original post in my Blog

Top comments (10)

Collapse
 
hoodaajay1 profile image
hoodaajay1 • Edited

Hey
I cloned your github repository & ran the test on my machine (windows) I got the results similar to what you have posted in your Readme.md file, which is in contrast to what you have posted here in the blog.
For me the http+json response was bit faster. Could you please share your views.

goos: windows
goarch: amd64
pkg: benchmark-grpc-protobuf-vs-http-json-master
BenchmarkGRPCProtobuf-4 2000 624248 ns/op 10354 B/op 201 allocs/op
BenchmarkHTTPJSON-4 5000 307458 ns/op 8809 B/op 120 allocs/op
PASS
ok benchmark-grpc-protobuf-vs-http-json-master 6.106s

As per your README.md

Results
goos: darwin
goarch: amd64
BenchmarkGRPCProtobuf-8 10000 117649 ns/op 7686 B/op 154 allocs/op
BenchmarkHTTPJSON-8 10000 105837 ns/op 8932 B/op 116 allocs/op
PASS
ok github.com/plutov/benchmark-grpc-protobuf-vs-http-json 4.340s

They are almost the same, HTTP+JSON is a bit faster and has less allocs/op.

Collapse
 
kayis profile image
K • Edited

Is the type safety really needed? Would this also be faster with MessagePack, which doesn't need pre-defined schema?

Also, how does the story look on the client? Does parsing protocol buffers outperform JSON.parse()?

Collapse
 
plutov profile image
Alex Pliutau

Personally I prefer type-safe protocols when I use type-safe languages like Go, where you call server function (RPC) and have a struct returned with correct types, so you don't need to validate types, only values.

MessagePack is nice, it can be used without gRPC, so more flexible.

Can't answer question with JSON.parse() :)

Collapse
 
jamesmalvi profile image
Jaimie Malvi

Love to suggest few tools which work well with JSON data.

jsonformatter.org/json-editor
codebeautify.org/jsonviewer

Collapse
 
frosnerd profile image
Frank Rosner

Thanks for the comparison! To me this makes a lot of sense as binary protocols are usually faster than text based protocols like JSON. However what you are comparing is really a JSON API vs a ProtoBuf API, using an HTTP server and a gRPC server, respectively.

REST on the other hand is not about the actual implementation. REST cannot be slow or fast. It requires a stateless protocol and some defined standard operations to manipulate resources. It gives you some basic principles that help you to make your API interoperable, extensible and easy to understand.

Originally, REST was more of a generalization of HTTP: ics.uci.edu/~fielding/pubs/dissert...

Collapse
 
plutov profile image
Alex Pliutau

Agree here, let me change it in the repository and later in article here.

Collapse
 
adsouza profile image
Antonio D'souza

Go's JSON handling is notoriously slow so it's hardly surprising that protos would be faster.

Collapse
 
krutikkhatri profile image
krutikkhatri

Hii
You can also use onlinejsontools.org/ for json validator,beautify,minify,xml,yaml,CSV,bson,plain text,base64,tsv.
Do checkout this site!

Collapse
 
wangkuiyi profile image
Yi Wang

If the point is to compare RPC performance, shouldn't it be between gRPC+protobuf and Go RPC+gob? Why is JSON+Go's http package here?

Collapse
 
nalani profile image
nalani5210 • Edited

If the JSON string is very long, the format is really a mess. I usually use this online website to format .
jsonformatting.com/