title: TCP vs. UDP socket latency benchmark
body: <p>I have implemented a small benchmark for socket communication via TCP and UDP in Python. Surprisingly, TCP is almost exactly double as fast as UDP. </p>
  
  <p>To avoid routing effects, server and client are running on the same Unix machine, but on different threads. </p>
  
  <p>Maybe the code is useful. Here is the server code:</p>
  
  <pre><code>import socket
  import sys
  
  host = 'localhost'  
  port = 8888
  buffersize = 8
  server_address = (host, port) 
  
  def start_UDP_server():
      socket_UDP = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
      socket_UDP.bind(server_address)
  
      print("UDP server is running...")
  
      while True:
          data, from_address = socket_UDP.recvfrom(buffersize)
          if not data: break
          socket_UDP.sendto(data, from_address)
      socket_UDP.close()
  
  
  def start_TCP_server():
      socket_TCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      socket_TCP.bind(server_address)
      socket_TCP.listen(1)
  
      print("TCP server is running...")
  
      while True:    
          client, client_address = socket_TCP.accept()
  
          while True:
              data = client.recv(buffersize)
              if not data: break
              client.sendall(data)
  
          client.close()
  </code></pre>
  
  <p>So you can run either <code>start_TCP_server()</code> or <code>start_UDP_server()</code>. </p>
  
  <p>On client side the code is:</p>
  
  <pre><code>import socket
  import sys
  import time
  
  host = 'localhost'  
  port = 8888
  buffersize = 8
  server_address = (host, port) 
  client_address = (host, port+1)
  N = 1000000
  
  
  def benchmark_UDP():
      socket_UDP = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
      socket_UDP.bind(client_address)
  
      print("Benchmark UDP...")
  
      duration = 0.0
      for i in range(0, N):
          b = bytes("a"*buffersize, "utf-8")
          start = time.time()
          socket_UDP.sendto(b, server_address)
          data, from_address = socket_UDP.recvfrom(buffersize)
          duration += time.time() - start
  
          if data != b:
              print("Error: Sent and received data are bot the same")
  
      print(duration*pow(10, 6)/N, "µs for UDP") 
  
  
  def benchmark_TCP():
      socket_TCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      socket_TCP.connect(server_address)
  
      print("Benchmark TCP...")
  
      duration = 0.0
      for i in range(0, N):
          b = bytes("a"*buffersize, "utf-8")
          start = time.time()
          socket_TCP.sendall(b)
          data = socket_TCP.recv(buffersize)
          duration += time.time() - start
  
          if data != b:
              print("Error: Sent and received data are bot the same")
  
      print(duration*pow(10, 6)/N, "µs for TCP")
      socket_TCP.close()
  </code></pre>
  
  <p>Like for the server you can start the benchmark by <code>benchmark_TCP()</code> or <code>benchmark_UDP()</code>.</p>
  
  <p>The results are about <strong>25 µs for TCP</strong>, and about <strong>54 µs for UDP</strong> on Unix and even worse for Windows (about 30 µs for TCP and more than 200 µs for UDP). Why? I would expect a minimal advantage for UDP.</p>