2

Imagine you want to stream multiple protobuf message types from a server to the same client. There are different ways to design the streaming service, e.g. assuming I want to stream 3 different types of messages, for example notifications, states and events:

Option 1 - One stream per type

rpc StreamingService {
   rpc NotificationStream(NotificationStreamingRequest) returns (stream Notification);
   rpc StateStream(StateStreamingRequest) returns (stream State);
   rpc EventStream(EventStreamingRequest) returns (stream Event);
}

Option 2 - One stream for all types

rpc StreamingService {
   rpc Stream(Request) returns (stream Message);
}

message Message {
   oneof type {
      Notification notification = 1;
      State state = 2;
      Event event = 3;
   }
}

While Option 1 would offer a cleaner implementation for the services in the code, Option 2 seems like the better option for communication systems. But is there any actual overhead in Option 1 other than the additional header and trailer metadata that now gets send multiple times due to multiple streams?

In the Performance Best Practices of the official gRPC website it is only mentioned to use streaming RPCs for long-lived data flow to avoid continuous RPC initiation, and to create a separate channel for each area of high load, which would actually favor Option 1 if each stream has a high load, because then each stream could use its own gRPC channel.

There is also nothing mentioned in the Performance best practices with gRPC from the MS Docs that really speaks against Option 1, other than the maximum limit of concurrent streams on servers.

Does anything really speak against Option 1 and using multiple streams in the same client-server connection? Is there any real performance disadvantadge on a technical level when having multiple streams?

dan-kli
  • 568
  • 2
  • 13
  • 1
    I'd go with the option that's cleaner from the design perspective. The actual behavior/performance of your system would greatly depend on the characteristics of your load, so the only way to know which options works better is by thorough benchmarking. I think in practice for most systems, the overhead caused by 1 or 2 would be completely negligible, unless you are doing something really extreme (in which case you'd really need to do extensive benchmarking). But chances are both options will be very similar in terms of performance.So I'd go for clean design rather than (premature) optimization. – Jan Tattermusch Jun 07 '22 at 14:05
  • Good to know, I just wasn't sure if there is an overhead created somewhere on a level that I wouldn't know about when using multiple streams (like somewhere in the TCP layer or something like that). Then I will probably just go with the option that offers the cleaner implementation... – dan-kli Jun 07 '22 at 14:20

0 Answers0