├── .gitignore ├── README-OLD.md ├── README.md └── test4 ├── package.json ├── server.go ├── server.js └── server.php /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /README-OLD.md: -------------------------------------------------------------------------------- 1 | # Node.js vs Nginx-PHP7-FPM vs Go 2 | 3 | **NOTICE: These results are not accurate while using multi-core at the moment, simply 4 | because node.js will utilize only one while nginx and go will utilize all. I will update 5 | results while testing within equally constrained containers shortly** 6 | 7 | ### The Setup 8 | A basic speed test between Node.js, Nginx-PHP7-FPM and golang 9 | 10 | PHP7, with nginx at 4 workers will utilize all cores 11 | Node.js as I started it, is NOT multi-core, yet... 12 | Go v1.5.2 will utilize all cores 13 | 14 | My test VM is an in-house (OpenNebula) Debian Jessie KVM virtual machine with 4GB ram and 4-core...the physical machine 15 | it sits on is a Dell R710, with dual 6-core hyperthreaded Xeons...its a good fast VM. 16 | 17 | Notice its plan old PHP7-FPM, Opcache is of course enabled as default. No Laravel/Lumen/Symfony framework. 18 | I don't even use the composer autoloader, but predis autoloader. 19 | 20 | PHP7-FPM used via unix sockets from nginx. Nginx is mostly default at 4 worker_processes. 21 | **This will mean nginx will use multiple cores..while this node.js test will not.** 22 | 23 | All 3 scripts provide a simple HTTP endpoint that gets data from redis. The redis key is a simple 24 | hash of a few paragraphs worth of text. Nothing too big. 25 | 26 | All `ab` HTTP requests to node, go and nginx sockets are localhost, no external TCP/IP, no loadbalancers in the way, all 127.0.0.1 27 | Redis was setup to use TCP/IP sockets as usual, not UNIX sockets. 28 | 29 | Using apache bench with -n for number of connections and -c for concurrency 30 | 31 | 32 | ### The Results 33 | 34 | Node.js is short here because it will not utilize all cores in this test. 35 | 36 | 37 | ``` 38 | test node.js php7 go 39 | -------------------------------------------------------------- 40 | ab -n10 -c1 1173 r/s, 0.8 ms/r 560 r/s, 1.7 ms/r 797 r/s, 1.2 ms/r 41 | ab -n100 -c1 1200 r/s, 0.8 ms/r 622 r/s, 1.6 ms/r 795 r/s, 1.2 ms/r 42 | ab -n100 -c10 1749 r/s, 5.75 ms/r 1900 r/s, 5.1 ms/r 3100 r/s, 3.2 ms/r 43 | ab -n1000 -c20 2100 r/s, 9.4 ms/r 2200 r/s, 9.0 ms/r 4000 r/s, 4.9 ms/r 44 | ab -n5000 -c200 2300 r/s, 86.4 ms/r 5400 r/s, 37 ms/r 5000 r/s, 49.6 ms/r 45 | ``` 46 | 47 | `r/s` = requests per second 48 | 49 | `ms/r` = mean milliseconds per request 50 | 51 | Node faster for single hits, but as concurrency grew, PHP/nginx became faster (becuase nginx will utilize 52 | multiple cores while node will not in this test. Go at v1.5 will utilize multi-core. 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Node vs PHP vs Go 2 | 3 | - [Disclaimer](#disclaimer) 4 | - [Localhost Hello World](#test1) 5 | - [Localhost JSON Encode](#test2) 6 | - [Localhost MySQL JSON Encode](#test3) 7 | - [Localhost Redis JSON Encode](#test4) 8 | - [1GB LAN Test 5,6,7,8](#test5) 9 | 10 | 11 | 12 | ## Disclaimer 13 | 14 | This is not a raw benchmark but a comparison of basic operations between the 3 platforms. The personal nature of this repo is to help me decide on which HTTP JSON API platform to use for a particular project, which is why I include Laravel, Lumen, Iris... I compare basic `hello world`, but also basic database queries and json encoding. Feel free to add more comparison tests as needed. You can find actual raw benchmarks of each platform elsewhere. 15 | 16 | My original comparison can be read in the `README-OLD.md` file, which is not in-depth or accurate enough for my needs. 17 | 18 | 19 | 20 | 21 | 22 | ## Test #1 - Localhost Hello World 23 | 24 | A simple `hello world` test. Everything including `wrk` is localhost. 25 | 26 | ##### Results 27 | 28 | TODO: show results 29 | Pure PHP7 30 | Laravel PHP7 31 | Lumen PHP7 32 | Pure Node 33 | Express Node 34 | Koa Node 35 | Pure Go 36 | Iris Go 37 | 38 | ##### Setup 39 | 40 | TODO: explain the actual test machine and setup, which versions, PHP-FPM nginx etc... 41 | 42 | 43 | 44 | 45 | 46 | ## Test #2 - Localhost JSON Encode 47 | 48 | A hard coded array encoded to JSON. Everything including `wrk` is localhost. 49 | 50 | ##### Results 51 | 52 | TODO: show results 53 | 54 | ##### Setup 55 | 56 | TODO: explain the actual test machine and setup, which versions, PHP-FPM nginx etc... 57 | 58 | 59 | 60 | 61 | 62 | ## Test #3 - Localhost MySQL JSON Encode 63 | 64 | A MySQL result encoded to JSON. Everything including `wrk` is localhost. 65 | 66 | ##### Results 67 | 68 | TODO: show results 69 | 70 | ##### Setup 71 | 72 | TODO: explain the actual test machine and setup, which versions, PHP-FPM nginx etc... 73 | Mysql setup, and config optimizations etc... 74 | 75 | 76 | 77 | 78 | 79 | ## Test #4 - Localhost Redis JSON Encode 80 | 81 | A Redis result encoded to JSON. Everything including `wrk` is localhost. 82 | 83 | ##### Results 84 | 85 | TODO: show results 86 | 87 | ##### Setup 88 | 89 | TODO: explain the actual test machine and setup, which versions, PHP-FPM nginx etc... 90 | Redis setup and optimizations etc... 91 | 92 | 93 | 94 | 95 | 96 | ## Test #5, 6, 7, 8 97 | 98 | Same as test 1,2,3,4 but over 1GB LAN with physical servers and `wkr` on separate machine across network. 99 | 100 | 101 | 102 | 103 | ## Contributing 104 | 105 | Thank you for considering contributing to this comparison! Please add issues and comments or fork and pull! 106 | 107 | Thanks to [@Allendar](https://github.com/Allendar) and [@borislemke](https://github.com/borislemke) for their contributions. 108 | 109 | See also https://github.com/borislemke/nodejs_vs_php 110 | 111 | ### License 112 | 113 | This comparison is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT) 114 | -------------------------------------------------------------------------------- /test4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodeVSphpVSgo", 3 | "version": "1.0.0", 4 | "description": "A simpale REST webservice that gets data from redis.", 5 | "main": "node.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "ioredis": "^1.14.0", 14 | "redis": "^2.4.2" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test4/server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "gopkg.in/redis.v3" 7 | ) 8 | 9 | func handler(w http.ResponseWriter, r *http.Request) { 10 | //fmt.Fprint(w, "Hello World!"); 11 | client := redis.NewClient(&redis.Options{ 12 | Addr: "localhost:6379", 13 | Password: "", 14 | DB: 0, 15 | }) 16 | 17 | results, _ := client.HGetAll("keystone:dynatron/metric::ebis-wlri-analysis:info").Result() 18 | fmt.Fprint(w, results) 19 | //fmt.Printf("The type is: %s \n", results) 20 | } 21 | 22 | func main() { 23 | http.HandleFunc("/", handler) 24 | http.ListenAndServe(":3000", nil); 25 | } 26 | -------------------------------------------------------------------------------- /test4/server.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var redis = require('redis'), client = redis.createClient(); 3 | 4 | //ioredis is actually SLOWER that the redis library above...odd 5 | //var redis = require('ioredis'), client = new redis(); 6 | 7 | var server = http.createServer(function(request, response) { 8 | //response.end('hi'); 9 | client.hgetall('keystone:dynatron/metric::ebis-wlri-analysis:info', function(err, results) { 10 | response.writeHead(200, { 'Content-Type': 'application/json'}); 11 | response.write(JSON.stringify(results)); 12 | response.end(); 13 | }); 14 | }); 15 | 16 | server.listen(3000, function() { 17 | console.log("Listening on port 3000"); 18 | }); 19 | -------------------------------------------------------------------------------- /test4/server.php: -------------------------------------------------------------------------------- 1 | 'tcp', 9 | # 'host' => 'localhost', 10 | # 'port' => 6379 11 | #]); 12 | 13 | $client = new Predis\Client('tcp://localhost:6379'); 14 | $results = $client->hgetall('keystone:dynatron/metric::ebis-wlri-analysis:info'); 15 | 16 | header('Content-Type: application/json'); 17 | echo json_encode($results); 18 | 19 | #echo "hi"; 20 | --------------------------------------------------------------------------------