Socket.IO server performance and bandwidth usage
Asked Answered
B

2

30

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 );
Bakery answered 20/9, 2013 at 1:33 Comment(1)
C
74

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).

Clausius answered 20/9, 2013 at 1:42 Comment(3)
Well I'm going to be sending one packet to the server then one packet out to every client immediately after. And that will only happen probably one to three times per day. I'm not adding any data into the packet so I'm assuming that it's the smallest amount of data possible - whatever that isBakery
"If event and args are not supplied, 12 bytes are sent to the server." Wait, isn't the Ethernet/IP/TCP overhead going to dominate here? You'd expect at least 64 bytes for a single Ethernet frame.Report
Yes, you are correct. In my calculations, I did not account for anything below the application layer.Clausius
N
2

WebSockets can stay open for a very long time, so handling a large number of concurrent connections usually means you'll need to scale out that service to accommodate for the increased load. This is the same for almost any technology, but there's usually a limit to the max number of open connections a server can handle before things go downhill quickly. If you're likely to have such peaks in traffic, I'd consider looking into a 3rd party service like pusher or kaazing (disclaimer: I haven't tried either yet.)

You've posted a pretty vague question (we know nothing about your application, architecture, etc. - just expected traffic), but hopefully that helps point you in the right direction. That being said... based upon your use case (broadcasting one or two small messages, occasionally), my gut is telling me that WebSockets are not the right technology for you.

(Note that bandwidth probably shouldn't be a concern - generally speaking if you were to send many messages over WebSockets vs. REST you'll be sending less data due to headers, cookies, etc.)

Natividad answered 20/9, 2013 at 1:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.