{"id":15713575,"url":"https://github.com/costajob/app-servers","last_synced_at":"2025-04-09T23:21:11.896Z","repository":{"id":59506177,"uuid":"48120103","full_name":"costajob/app-servers","owner":"costajob","description":"App Servers benchmarked for: Ruby, Python, JavaScript, Dart, Elixir, Java, Crystal, Nim, GO, Rust","archived":false,"fork":false,"pushed_at":"2020-12-26T13:33:55.000Z","size":43378,"stargazers_count":256,"open_issues_count":2,"forks_count":27,"subscribers_count":18,"default_branch":"master","last_synced_at":"2025-04-02T16:50:17.667Z","etag":null,"topics":["benchmark","crystal","dart","elixir","golang","http-server","java","nim","nodejs","python","ruby","rust","wrk"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/costajob.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-12-16T15:55:51.000Z","updated_at":"2025-03-21T21:03:31.000Z","dependencies_parsed_at":"2022-09-18T07:35:41.997Z","dependency_job_id":null,"html_url":"https://github.com/costajob/app-servers","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/costajob%2Fapp-servers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/costajob%2Fapp-servers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/costajob%2Fapp-servers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/costajob%2Fapp-servers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/costajob","download_url":"https://codeload.github.com/costajob/app-servers/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248126362,"owners_count":21051909,"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":["benchmark","crystal","dart","elixir","golang","http-server","java","nim","nodejs","python","ruby","rust","wrk"],"created_at":"2024-10-03T21:32:12.594Z","updated_at":"2025-04-09T23:21:11.872Z","avatar_url":"https://github.com/costajob.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Table of Contents\n\n* [Scope](#scope)\n  * [Hello World](#hello-world)\n  * [Disclaimer](#disclaimer)\n* [Languages](#languages)\n  * [Ruby](#ruby)\n  * [Python](#python)\n  * [JavaScript](#javascript)\n  * [Dart](#dart)\n  * [Elixir](#elixir)\n  * [Crystal](#crystal)\n  * [Nim](#nim)\n  * [GO](#go)\n* [Tools](#tools)\n  * [Wrk](#wrk)\n  * [Platform](#platform)\n  * [RAM and CPU](#ram-and-cpu)\n* [Benchmarks](#benchmarks)\n  * [Results](#results)\n  * [Puma](#puma)\n  * [Gunicorn with Meinheld](#gunicorn-with-meinheld)\n  * [Node Cluster](#node-cluster)\n  * [Dart HttpServer](#dart-httpserver)\n  * [Plug with Cowboy](#plug-with-cowboy)\n  * [Crystal HTTP](#crystal-http)\n  * [httpbeast](#httpbeast)\n  * [GO ServeMux](#go-servermux)\n  * [Hyper](#hyper)\n\n## Scope\nThe idea behind this repository is to benchmark different languages implementation of HTTP server.\n\n### Hello World\nThe *application* i tested is minimal: the HTTP version of the *Hello World* example.  \nThis approach allows including languages i barely know, since it is pretty easy to find such implementation online.  \nIf you're looking for more complex examples, you will have better luck with the [TechEmpower benchmarks](https://www.techempower.com/benchmarks/).\n\n### Disclaimer\nPlease do take the following numbers with a grain of salt: it is not my intention to promote one language over another basing on micro-benchmarks.  \nIndeed you should never pick a language just basing on its presumed performance.\n\n## Languages\nI have became lazy with years and just adopt languages i can install via `homebrew`, sorry Oracle/MS. This also allows me to benchmark them in a single session, thus trying to use an environment as neutral as possible.\nWhere possible i just relied on the standard library, but when it is not production-ready (i.e. Ruby, Python).\n\n### Ruby\n[Ruby](https://www.ruby-lang.org/en/) 3.0.0 is used. \nRuby is a general-purpose, interpreted, dynamic programming language, focused on simplicity and productivity. \n\n### Python\n[Python](https://www.python.org/) 3.9.1 is used.\nPython is a widely used high-level, general-purpose, interpreted, dynamic programming language.  \n\n### JavaScript\n[Node.js](https://nodejs.org/en/) version 15.5.0 is used.\nNode.js is based on the V8 JavaScript engine, optimized by Google and supporting most of the new language's features.   \n\n### Dart\n[Dart](https://www.dartlang.org/) version 2.10.4 is used.\nDart is a VM based, object-oriented, sound typed language using a C-style syntax that transcompiles optionally into JavaScript.\n\n### Elixir\n[Elixir](http://elixir-lang.org/) 1.11.2 is used.\nElixir is a purely functional language that runs on the [Erlang](https://www.erlang.org/) VM and is strongly influenced by the Ruby syntax.\n\n### Crystal\n[Crystal](http://crystal-lang.org/) 0.35.1 is used.\nCrystal has a syntax very close to Ruby, but brings some desirable features such as statically typing and ahead of time (AOT) compilation.  \n\n### Nim\n[Nim](http://nim-lang.org/) 1.4.2 is used.\nNim is an AOT, Python inspired, statically typed language that comes with an ambitious compiler aimed to produce code in C, C++, JavaScript or ObjectiveC.\n\n### GO\n[GO](https://golang.org/) 1.15.6 is used.\nGO is an AOT language that focuses on simplicity and offers a broad standard library with [CSP](https://en.wikipedia.org/wiki/Communicating_sequential_processes) constructs built in.\n\n## Tools\n\n### Wrk\nI used [wrk](https://github.com/wg/wrk) as the loading tool.  \nI measured each application server six times, picking the best lap (but for VM based languages demanding longer warm-up).  \n```shell\nwrk -t 4 -c 100 -d30s --timeout 2000 http://0.0.0.0:9292\n```\n\n### Platform\nThese benchmarks are recorded on a MacBook PRO 13 2019 having these specs:\n* macOS Catalina\n* 1.4 GHz Quad-Core Intel Core i5\n* 8 GB 2133 MHz LPDDR3\n\n### RAM and CPU\nI measured RAM and CPU consumption by using macOS Activity Monitor dashboard and recording max consumption peak.  \nFor the languages relying on pre-forking parallelism i reported the average consumption by taking a snapshot during the stress period.\n\n## Benchmarks\n\n### Results\n| Language                  | App Server                                        | Requests/sec      | RAM (MB)  | CPU (%)  |\n| :------------------------ | :------------------------------------------------ | ----------------: |---------: |--------: |\n| [Ruby+MJIT](#ruby)        | [Puma](#puma)                                     |         36455.88  |    \u003e 100  |   \u003e 580  |\n| [Elixir](#elixir)         | [Plug with Cowboy](#plug-with-cowboy)             |         46416.25  |     50.5  |   583.8  |\n| [Ruby](#ruby)             | [Puma](#puma)                                     |         47975.36  |    \u003e 100  |   \u003e 580  |\n| [Dart](#dart)             | [Dart HttpServer](#dart-httpserver)               |         59335.33  |    193.2  |   429.1  |\n| [JavaScript](#javascript) | [Node Cluster](#node-cluster)                     |         87208.47  |    \u003e 200  |   \u003e 240  |\n| [GO](#go)                 | [GO ServeMux](#go-servemux)                       |        103847.10  |     10.0  |   429.1  |\n| [Python](#python)         | [Gunicorn with Meinheld](#gunicorn-with-meinheld) |        120105.65  |     \u003e 40  |   \u003e 380  |\n| [Nim](#nim)               | [httpbeast](#httpbeast)                           |        128257.98  |     11.4  |    99.6  |\n| [Crystal](#crystal)       | [Crystal HTTP](#crystal-http)                     |        132699.78  |      8.5  |   246.7  |\n\n                                                                                                   \n### Puma\nI tested Ruby by using a plain [Rack](http://rack.github.io/) application served by [Puma](http://puma.io).  \n\n#### Bootstrap\n```shell\nRUBYOPT='--jit' puma -w 8 -t 2 --preload servers/rack_server.ru\n```\n\n\n### Gunicorn with Meinheld\nI tested Python by using [Gunicorn](http://gunicorn.org/) spawning [Meinheld](http://meinheld.org/) workers with a plain WSGI compliant server.\n\n#### Bootstrap\n```shell\ncd servers\ngunicorn -w 4 -k meinheld.gmeinheld.MeinheldWorker -b :9292 wsgi_server:app\n```\n\n\n### Node Cluster\nI used the cluster module included into Node's standard library.\n\n#### Bootstrap\n```shell\nnode servers/node_server.js\n```\n\n\n### Dart HttpServer\nI used the async HTTP server embedded into the Dart standard library and compiled it with `dart2native` AOT compiler.\n\n#### Bootstrap\n```shell\ndart2native servers/dart_server.dart -k aot\ndartaotruntime servers/dart_server.aot\n```\n\n\n### Plug with Cowboy\nI tested Elixir by using [Plug](https://github.com/elixir-lang/plug) library that provides a [Cowboy](https://github.com/ninenines/cowboy) adapter.\n\n#### Bootstrap\n```shell\ncd servers/plug_server\nMIX_ENV=prod mix compile\nMIX_ENV=prod mix run --no-halt\n```\n\n\n### Crystal HTTP\nI used Crystal HTTP server standard library, enabling parallelism by using the `preview_mt` flag.  \n\n#### Bootstrap\n```shell\ncrystal build -Dpreview_mt --release servers/crystal_server.cr\n./crystal_server\n```\n\n\n### httpbeast\nTo test Nim i opted for the [httpbeast](https://github.com/dom96/httpbeast) library: an asynchronous server relying on Nim HTTP standard library.\n\n#### Bootstrap\n```shell\nnim c -d:release --threads:on servers/httpbeast_server.nim\n./servers/httpbeast_server\n```\n\n\n### GO ServeMux\nI used the [HTTP ServeMux](https://golang.org/pkg/net/http/) GO standard library.\n\n#### Bootstrap\n```shell\ngo run servers/servemux_server.go\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcostajob%2Fapp-servers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcostajob%2Fapp-servers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcostajob%2Fapp-servers/lists"}