Performance testing and profiling

Load testing

The venueless source tree includes a small load testing tool that opens up many websocket connections to a venueless server, sends messages and measures response times. To use it, open up the folder and install the dependencies:

$ cd load-test
$ npm install

Then, you can use it like this:

$ npm start ws://localhost:8375/ws/world/sample/

To modify the load testing parameters, you can adjust the following command line options:

--clients

The number of clients to simulate that connect to the websocket.

--rampup

The wait time in milliseconds between the creation of two new clients.

--msgs

The total number of chat messages per second to emulate (once all clients are connected).

Note that the regular development webserver started by our docker compose setup is a single-threaded, non-optimized setup. To run a more production-like setting, you can run the following commands:

$ docker-compose stop server
$ docker-compose run -p 8375:8375 \
    --entrypoint "gunicorn -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8375 --max-requests 1200 --max-requests-jitter 200 -w 12 venueless.asgi:application" \
    server

Replace 12 with two times the number of CPU cores you have. Note: With these settings, the server will not automatically reload when you change the code.

Profiling

To find out which part of the server code is eating your CPU, you can start a profiled server. To do so with our standard setup, execute the following commands:

$ docker-compose stop server
$ docker-compose run -p 8375:8375 \
    --entrypoint "python manage.py runserver_profiled 0.0.0.0:8375" \
    server

Then, apply your load, e.g. run the load testing tool from above or use venueless manually. Once you hit Ctrl+C, the console will show a list of all called functions and the time the CPU spent on them. The output is generated by yappi, so please read there documentation for in-depth guidance what it means.

You can also trigger statistical output without stopping the server by running the following command in a separate shell:

$ docker-compose kill -s SIGUSR1 server

Note: With these settings, the server will not automatically reload when you change the code.