Serialisation options with ASP.NET Core

I have been taking a look at the serialisation options available to a .NET Core app in order to see if it is worth us trying something new. Our current app uses ASP.NET web api and serialises as JSON over HTTP using the default built-in formatters.

Test application

I tried a little test serialising various amounts of data over the wire

  • A ~8Mb string containing serialised market data (spots, vols, holiday calendars)
  • A complex type representing a deal containing ~20 fields and nested types

I span up a few little servers, each serving this data over a different format

  • JSON from an ASP.NET Core app running Kestrel
  • As above but compressed using GZIP, with “Optimal” and “Fastest” compression level
  • ServiceStack using proto-buf
  • gRPC

I ran each test with client and server on the same machine then again with the client on a remote box.

Results

I ran each test 100 times, the result is the average time per call in ms.

localhost

Running client and server locally

Test gRPC ASP.NET Core / JSON (Uncompressed) ASP.NET Core / JSON (Compressed Optimal) ASP.NET Core / JSON (Compressed Fastest) ServiceStack / proto-buf
8Mb string 57 412 330 218 294
10 deals <1 29 29 30 28
100 deals 5 31 30 28 36
1000 deals 48 108 91 80 119

remote

Running client remotely, servers locally

Test gRPC ASP.NET Core / JSON (Uncompressed) ASP.NET Core / JSON (Compressed Optimal) ASP.NET Core / JSON (Compressed Fastest) ServiceStack / proto-buf
8Mb string 798 913 344   238 827
10 deals 14 29 49   28 46
100 deals 15 45 50    29 88
1000 deals 60 186 96    88 172

gRPC Compression

These results imply that proto-buffer format (gRPC and ServiceStack here) does not compress payloads: over-the-wire time is comparable to uncompressed JSON. I believe it is possible for both formats to compress data, I just can’t work out how! I opened a StackOverflow question to try and find the answer: gRPC compression in C#.
I suspect that gRPC will be by far the quickest format, if I can get compression enabled.

Conclusions

This is too simplistic a test to draw firm conclusions, but I can raise a few suggestions and explore them further later.

  • gRPC is very fast but suffers when fields have a large amount of data. If I can get compression enabled I suspect this will be the clear winner
  • Proto-buf on ServiceStack is very fast but again suffers with large fields (compression would help here too)
  • ASP.NET Core’s JSON serialisation is very fast, and using gzip compression makes this the fastest format at the moment
  • With the type of payloads we have higher levels of compression hamper performance (for gzip-ed JSON). Setting the compression level to “fastest” costs little in over-the-wire latency but gives a significant speed improvement

So given the lack of compression in gRPC I don’t think it is that usable for us, yet. We also lose the transparency and hackable ease that JSON over HTTP gives (i.e. being able to view an endpoint in the browser).

Written on March 1, 2018

misc (3) netcoreapp (10)