I have found a number of benchmark reports that cover the request rate that can be handled by Tornado, but haven't seen anything that deals with the total data rate capacity - ie bytes per second that can be read in or written out. I am interested in both websockets and http as we use both.
I ran some tests using a simple websocket handler (below) as the server.
The client simulates the approximate size and timing of messages that we will have in our actual service:it sends 200kbytes every 10 seconds on each websocket, staggered so not all connections are sending at once.
At about 5 mbits/sec total (each way) the python process CPU time hits 75% on my freebsd 3.2GHz system. There are 30 websocket connections. CPU usage grows proportionately with data throughput so I believe this is headed toward a CPU bottleneck.
(The same test on my Windows 2.8GHz shows python at 30% CPU.)
We have another server (written in c++ using kqueue) that can handle much higher throughput on the same hardware.
My question is: am I getting expected throughput, or is something wrong? I am pretty sure tornado is using kqueue and not select, as "top" shows the server in "kqread" when idle.
The server:
import tornado.ioloop
import tornado.web
import tornado.websocket
import settings
class WSHandler(tornado.websocket.WebSocketHandler):
def open(self):
print ("WebSocket opened " + self.get_websocket_scheme())
def on_message(self, message):
self.write_message(u"You said: " + message)
def on_close(self):
print ("WebSocket closed")
appsettings = {
"debug" : True,
"static_path" : "./",
}
application = tornado.web.Application([
(r"/ws", WSHandler)
],
**appsettings)
if __name__ == "__main__":
application.listen(7780)
ssloptions = {"certfile": settings.SSL_CERT_FILE, "keyfile": settings.SSL_KEY_FILE }
application.listen(7443, ssl_options = ssloptions)
tornado.ioloop.IOLoop.instance().start()
Thank you for any insight.