{"id":18820870,"url":"https://github.com/hashrocket/websocket-shootout","last_synced_at":"2025-04-05T13:05:41.091Z","repository":{"id":66302497,"uuid":"61897176","full_name":"hashrocket/websocket-shootout","owner":"hashrocket","description":"A comparison of websocket servers in multiple languages and frameworks","archived":false,"fork":false,"pushed_at":"2019-12-07T20:31:54.000Z","size":1149,"stargazers_count":431,"open_issues_count":9,"forks_count":76,"subscribers_count":29,"default_branch":"master","last_synced_at":"2025-03-29T12:04:57.875Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hashrocket.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-06-24T16:19:36.000Z","updated_at":"2025-03-10T01:27:02.000Z","dependencies_parsed_at":"2023-02-20T21:00:34.112Z","dependency_job_id":null,"html_url":"https://github.com/hashrocket/websocket-shootout","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashrocket%2Fwebsocket-shootout","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashrocket%2Fwebsocket-shootout/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashrocket%2Fwebsocket-shootout/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashrocket%2Fwebsocket-shootout/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hashrocket","download_url":"https://codeload.github.com/hashrocket/websocket-shootout/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247339155,"owners_count":20923014,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T00:31:12.372Z","updated_at":"2025-04-05T13:05:41.076Z","avatar_url":"https://github.com/hashrocket.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# websocket-shootout\n\nThis project is designed to compare websocket servers in multiple languages and frameworks and has a [companion blog post][post]. The servers all implement an extremely simple protocol with only two messages: `echo` and `broadcast`. An echo is returned to the sending client. A broadcast is sent to all connected clients. Both messages take a payload value that should be delivered to the appropriate destination.\n\n[post]: https://hashrocket.com/blog/posts/websocket-shootout\n\nExample broadcast message:\n\n```\n{\"type\":\"broadcast\",\"payload\":{\"foo\": \"bar\"}}\n```\n\nFor the platforms with low level websocket implementations the above message would work directly. For platforms with higher level abstractions such as Phoenix and Rails the message must be encoded to be compatible with their message standards.\n\n## Platforms\n\nThe following platforms currently have servers implemented.\n\n* Clojure\n* C++\n* Elixir / Phoenix\n* Go\n* Haskell\n* Java\n* Javascript / NodeJS\n* Ruby / EventMachine\n* Ruby / Rails\n* Rust\n\n### Build Instructions\n\nSome dependencies are tracked via git submodules. First step is to pull them down.\n\n```\ngit submodule init\ngit submodule update\n```\n\nLook for a README.md in each projects directory for instructions on building and running the servers.\n\n## Benchmark\n\nAs part of this comparison a benchmark tool `websocket-bench` was built to test the performance of these websocket servers. `websocket-bench` is designed to find how many connections a server can handle while providing an acceptable level of performance. For example, given the requirement that 4 broadcast requests are served concurrently and 95% of broadcasts be completed within 500ms, how many connections can the server handle?\n\nHere is an example benchmark run:\n\n```\n% % bin/websocket-bench broadcast ws://earth.local:3334/ws --concurrent 10 --sample-size 100 --step-size 1000 --limit-percentile 95 --limit-rtt 250ms\nclients:  1000    95per-rtt:  47ms    min-rtt:   9ms    median-rtt:  20ms    max-rtt:  66ms\nclients:  2000    95per-rtt:  87ms    min-rtt:   9ms    median-rtt:  43ms    max-rtt: 105ms\nclients:  3000    95per-rtt: 121ms    min-rtt:  21ms    median-rtt:  58ms    max-rtt: 201ms\nclients:  4000    95per-rtt: 163ms    min-rtt:  30ms    median-rtt:  76ms    max-rtt: 325ms\nclients:  5000    95per-rtt: 184ms    min-rtt:  37ms    median-rtt:  95ms    max-rtt: 298ms\n\n```\n\nThe above benchmark starts by connecting 1000 websocket clients to ws://earth.local:3334/ws. Then it sends 100 broadcast requests with a concurrency of 10. It increases by 1000 clients at a time until the 95th percentile round-trip time exceeds 250ms.\n\nRun `make` to build the benchmark tool. Ensure you have previously initialized git submodules or the build will fail. The benchmark tool will be built to `bin/websocket-bench`.\n\n## Open file limits\n\nMost servers have sufficient performance to encounter OS level open file limits. Here is how to increase those limits.\n\n### Ubuntu 16.04\n\nAdd the following to `/etc/sysctl.conf`:\n\n```\nfs.file-max = 2097152\n```\n\nAdd the following to `/etc/security/limits.conf`:\n\n```\n*    soft nofile 1048576\n*    hard nofile 1048576\n```\n\nIn the shell run (or put in .profile or the like):\n\n```\nulimit -n 1048576\n```\n\n## Running Benchmarks\n\nIt is *highly* recommended that `websocket-bench` and the server be run on separate machines connected with at least GB ethernet.\n\nRun `websocket-bench` with the `--help` parameter for detailed info.\n\n```\n% bin/websocket-bench --help\n```\n\n## Outbound connection limits\n\nA host can only establish a few ten-thousands of outbound connections before it suffer port exhaustion. To be more accurate that limit is per IP address. `websocket-bench` can use multiple IP addresses to establish more connections.\n\n```\nbin/websocket-bench broadcast ws://earth.local:3334/ws -c 4 -s 40 -l 192.168.50.5 -l 192.168.50.246 -l 192.168.50.247 --step-size 1000\n```\n\nThe above command would use addresses 192.168.50.5, 192.168.50.246, and 192.168.50.247.\n\nOf course, this requires that the host _have_ multiple IP addresses. On Ubuntu 16.04 additional addresses can be bound to an interface by adding configuration to /etc/network/interfaces (this may require disabling network-manager if the machine is a desktop installation).\n\nExample /etc/network/interfaces snippet:\n\n```\n...\nup /sbin/ip addr add 192.168.50.246/24 dev eth0\nup /sbin/ip addr add 192.168.50.247/24 dev eth0\n\ndown /sbin/ip addr del 192.168.50.246/24 dev eth0\ndown /sbin/ip addr del 192.168.50.247/24 dev eth0\n...\n```\n\n## Results\n\nResults are in the results directory.\n\n## Contributing\n\nThis project is complete and is no longer actively maintained. We'll leave pull\nrequests demonstrating other implementations open for educational purposes.\n\n## About\n\n[![Hashrocket logo](https://hashrocket.com/hashrocket_logo.svg)](https://hashrocket.com)\n\nwebsocket-shootout is supported by the team at [Hashrocket, a multidisciplinary design and development consultancy](https://hashrocket.com). If you'd like to [work with us](https://hashrocket.com/contact-us/hire-us) or [join our team](https://hashrocket.com/contact-us/jobs), don't hesitate to get in touch.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhashrocket%2Fwebsocket-shootout","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhashrocket%2Fwebsocket-shootout","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhashrocket%2Fwebsocket-shootout/lists"}