Search code examples
pythonsocketsubuntu-18.04

TCP Socket Maximum Bandwidth


I want to know if there is a limit to socket speed, I have a server that services multiple clients(each client is running on a thread), each client send an image and the server does some analysis and returns the results.

I have the clients calculate the fps to monitor the speed, after the bandwidth on the server reaches 110 MiB/s, the bandwidth does not seem to increase no matter how many more clients are connected, this results in slowing the clients (which I assume is because the clients cannot use more bandwidth and are waiting for the socket to free up after the sever returns a request for another client).

I tried reducing the dimensions of the sent image, this allowed me to increase the number of clients (which means that the CPU can handle more clients at the same time), but I reached the same limitation when the the received data reached 110 MiB/s.

I tried checking the network speed between the server and client using iperf, the result was 850-1000 Mbits/sec (using multiple devices as a client), so the network connection is fast enough and it can handle more bandwidth.

I also tried opening another instance of the serve listening on another port, the receiving bandwidth was still stuck at 110 MiB/s.

In all cases when I open a new client on the same machine as the server, that client would be more than 10X faster than the other clients. Which once again means that the server can handle more clients.

Which leaves the question of why is the bandwidth stopping at 110 MiB/s, is there a maximum speed allowed per socket?

I know that python has GIL which simulates multi-threading, can the CPU only decode/handle (not sure what the right term is) 110 MiB/s of incoming data? if so then why did it not increase when I added another server instance with new clients connected to the new server? And why was it able to handle the client n the same machine?

I tried looking if there is a maximum socket bandwidth limit, I could only find how to limit(reduce) the socket bandwidth, which is the opposite of what I want to do.

Here is some info which might be related:

  • Intel i7-10700 on the server.
  • Ubuntu 18.04 on the server.
  • server and clients are connected on the local Network on the same switch.
  • the server and clients are runnning python 3.6.9
  • The CPU was running at 50% on all cores
  • Bandwidth was monitored using the gnome-system-monitor
  • clients are running Ubntu18.04 and 20.04

Solution

  • There is no fixed limit to the performance of a "socket." There are several possible limits to the performance of a TCP connection being accessed via a socket. One of those is:

    Throughput <= WindowSize / RoundTripTime

    Another is:

    Throughput <= LinkRate * (DataPerPacket / DataPlusHeadersPerPacket)

    Also, a TCP connection will, in broad terms, make use of no more than one CPU. So it can go no faster than that CPU can execute the networking stack code.

    But more to the current point, 110 MiB/s is 110 * 1048576 or 115343360 Bytes per second. At 8 bits per byte that is 922746880 bits per second, or 922 Mbit/s which is in the middle of the range you reported for your iperf results.

    It sounds like you have a 1 Gbit/s physical network and are essentially saturating it.