I am currently working on a Service Fabric microservice, which should have high bandwidth.
I wondered why I cannot receive more than 500 messages 1 KB per second on my workstation using loopback.
I removed all the business logic and plugged in a performance profiler to measure performance to the end.
It seems that 96% of the time spent on resolving the Client, and only ~ 2% fulfill actual Http requests.
I call Submit in a closed loop for the test:
private HttpCommunicationClientFactory factory = new HttpCommunicationClientFactory(); public async Task Send() { var client = new ServicePartitionClient<HttpCommunicationClient>( factory, new Uri("fabric:/MyApp/MyService")); await client.InvokeWithRetryAsync(c => c.HttpClient.GetAsync(c.Url + "/test")); }

Any ideas on this? According to the documentation, what I call Services seems like Fabric Fabric best practice.
UPDATE ServicePartioningClient caching improves performance, but using partioned services, I cannot cache the client, since I donβt know the section for providing PartitionKey.
UPDATE 2 . I'm sorry that I did not include the details in my original question. We noticed the huge overhead of InvokeWithRetry when we initially introduced socket-based communications.
You will not notice this if you use HTTP requests. The HTTP request is already taking ~ 1 ms, so adding 0.5 ms to InvokeWithRetry is not remarkable.
But if you use raw sockets, which in our case take ~ 0.005 ms, adding 0.5 ms overhead for InvokeWithRetry, this is huge!
Here is an example http, with InvokeAndRetry it takes 3 times:
public async Task RunTest() { var factory = new HttpCommunicationClientFactory(); var uri = new Uri("fabric:/MyApp/MyService"); var count = 10000; // Example 1: ~6000ms for (var i = 0; i < count; i++) { var pClient1 = new ServicePartitionClient<HttpCommunicationClient>(factory, uri, new ServicePartitionKey(1)); await pClient1.InvokeWithRetryAsync(c => c.HttpClient.GetAsync(c.Url)); } // Example 2: ~1800ms var pClient2 = new ServicePartitionClient<HttpCommunicationClient>(factory, uri, new ServicePartitionKey(1)); HttpCommunicationClient resolvedClient = null; await pClient2.InvokeWithRetryAsync( c => { resolvedClient = c; return Task.FromResult(true); }); for (var i = 0; i < count; i++) { await resolvedClient.HttpClient.GetAsync(resolvedClient.Url); } }
I know that InvokeWithRetry adds some nice things that I don't want to miss from clients. But do I need to allow partitions on every call?