Socket.IO server performance and bandwidth usage

Joe Boris picture Joe Boris · Sep 20, 2013 · Viewed 28k times · Source

I'm about to host a small socket server on a local computer and I'd like to know what kind of bandwidth it's going to use. On most days it will have no more than 50 clients connected at once, but once or twice a week it could have as many as 5,000+ clients at once. However, the only messages sent will be an occasional single message to all connected clients at once with no extra data or anything.

Will the server cause a significant drop in performance on the computer it's hosted on or slow down my internet speeds at all?

Server.js:

var app = require('http').createServer(handler)
   , io = require('socket.io').listen(app)
   , fs = require('fs')

 app.listen(8001);

function handler (req, res) {
fs.readFile(__dirname + '/index.html',
  function (err, data) {
    if (err) {
      res.writeHead(500);
      return res.end('Error loading index.html');
    }

    res.writeHead(200);
    res.end(data);
  });
}

io.sockets.on('connection', function (socket) {
  socket.on('SendDefault', function(data) {
    socket.broadcast.emit('GetDefault');
  });
});

Client.js:

setTimeout( function( ){ 
  socket = io.connect('[IP Address]:8001');
  socket.on('GetDefault', function(data) {
    DoStuff( );
  );
} ); }, 10000 );

Answer

hexacyanide picture hexacyanide · Sep 20, 2013

The amount of bandwidth will depend heavily on the amount of data you're going to send from the server, and how much data the client will send. The bandwidth usage will also depend on which Socket.IO transport you're using, and the heartbeat interval of your application.

The performance impact of the application also varies on the type of application you're running and the performance capability of your machine and/or network. However, 5000+ clients will have a considerable impact on performance, regardless of your computer's capabilities unless you are scaling the application across multiple cores.

I've taken some measurements using a proxy. Here are the results:

Emitting from a client: socket.emit(event, args)

  • If event and args are not supplied, 12 bytes are sent to the server.
  • If args is omitted but event is supplied, the total size is 22 bytes and the length of event.
  • If args and event are supplied, the same rules are followed, but the results may vary depending on the data type of args.

Emitting from the server: same format as from client

  • If event and args are not supplied, 8 bytes are sent to the client.
  • If args is omitted but event is supplied, the total size is 17 bytes and the length of event.
  • If args and event are supplied, the same rules are followed, but the results may vary depending on the data type of args.

Server to client heartbeat: every 25 seconds per client

  • 5 bytes from server
  • 9 bytes client response

Handshaking: once per client

  • 216 bytes from server
  • 431 bytes response from client
  • 129 bytes follow up from server

Therefore with a load of 5000+ clients, expect at least 3.7MB for handshaking, 3KB/s for heartbeats, and at least 107KB bandwidth for a socket.emit(). These are not exact figures, as clients can lose data, drop connections, need to reconnect, etc.

Conclusively, your network will probably hold up, but the main concern should be the amount of concurrent connections your network will have to handle. Many concurrent connections can also be CPU intensive, so you should think about clustering across cores. Also keep in mind the amount of heartbeats the Socket.IO server will have to handle. With 50 concurrent users, that's an average of 2 heartbeats per second. At 5000+ concurrent users, that's 200+ heartbeats per second, which I'd imagine is more CPU intensive than network intensive (2.8KB/s).