Does Node.js perform badly on Windows, surely it can't be slower than apache for basic I/O

Jack picture Jack · Feb 11, 2012 · Viewed 11.7k times · Source

Question: Are the result that i'm getting reasonable? Is there anything which could have such an impact in reducing the number of requests per second?

Edit: A friend of mine has just benchmarked the same application on Linux and the average r/s was approx 7000.

Edit #2: I've checked the CPU usage of Node.exe, and it's only using 5-6% of the cpu. Surely this figure should be 12% on a quad core machine, 8 thread CPU when running on a single thread if truly under load?

I've written a Node.js application (running Node v0.6.10) and benchmarked it with apachebench: ab -c 256 -n 50000 http://localhost:3000/. I'm getting a request per second rate of roughly 650 requests per second. There's too much code to put here, however this is the basic structure:

Application Settings:

/**
 * Module dependencies.
 */
var util = require('util'),                                   //Useful for inspecting JSON objects
    express = require('express'),                             //Express framework, similar to sinatra for ruby
    connect = require('connect'),                             //An integral part of the express framework
    app = module.exports = express.createServer(),            //Create the server
    io = require('socket.io').listen(app),                    //Make Socket.io listen on the server
    parseCookie = require('connect').utils.parseCookie,       //Parse cookies to retrieve session id
    MemoryStore = require('connect').session.MemoryStore,     //Session memory store
    sessionStore = new MemoryStore(),
    Session = require('connect').middleware.session.Session,
    mongodb = require('mongodb'),                             //MongoDB Database
    BSON = mongodb.BSONPure,                                  //Used to serialize JSON into BSON [binary]
    sanitize = require('validator').sanitize;

// Configuration
app.configure(function()
{
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.bodyParser());
  app.use(express.methodOverride());

  app.use(express.cookieParser());
  app.use(express.session({
    store: sessionStore,
    secret: '...',
    key: 'express.sid'}));
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});

app.configure('development', function(){
  //app.use(express.errorHandler({dumpExceptions: true, showStack: true}));
});

app.listen(3000);

console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);

io.configure('development', function()
{
  io.set('transports', ['websocket']);
  //io.set('heartbeats', false);
  //io.set('heartbeat timeout', 200);
  //io.set('heartbeat interval', 220);
});

//MongoDB Database port and ip
var DATABASE_PORT = 27017;
var DATABASE_IP = "127.0.0.1"; //Localhost

/*
setInterval(function(){
  console.log("BROWSING:\n" + util.inspect(browsing));
}, 1000);
*/

//Connected users
var validUsers = {};
var clients = {};
var browsing = {};

//Database handles
var users;
var projects;

//Connect to the database server
db = new mongodb.Db('nimble', new mongodb.Server(DATABASE_IP, DATABASE_PORT, {}, {}));
db.open(function (error, client)
{
  if (error) {
    console.error("Database is currently not running");
    throw error;
  }  
  users = new mongodb.Collection(client, 'users');        //Handle to users
  projects = new mongodb.Collection(client, 'projects');  //Handle to projects
});

app.get('/', function(req, res)
{
  //users.insert("test", {safe:true});
  //users.findOne("test", function(result){})    
  if(req.session.auth)
  {
    if(req.session.account == "client")
    {
      //Redirect to the client dash
      res.redirect('/dash');
    }
    else if (req.session.account == "developer")
    {
      res.redirect('/projects');
    }
  }
  else
  {
    res.redirect('/login');
  }       
});

Apart from the above code the only notable remaining code is a series of Express app.get and app.post event handlers.

I have performed the same test on a basic Express set up web server, and the basic node.js http web server.

Node.js with Express server

var express = require('express');
var app = express.createServer();

app.get('/', function(req, res){
    res.send();
});

app.listen(3000);

Node.js HTTP

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end();
}).listen(3000, "127.0.0.1");

The results being:
2000 requests per second on Express
2200 requests per second on Node.js

I've performed the same test against a static file hosted on an Apache web server:
6000 requests per second

Now this benchmark shows Node.js beating Apache hands down!
http://zgadzaj.com/benchmarking-nodejs-basic-performance-tests-against-apache-php

My relevant hardware spec:
Intel i7 2630qm
6 GB RAM

Answer

Jack picture Jack · Feb 11, 2012

I can conclude through testing my own application on a Linux install on the same machine that it was infact VERY slow on Windows. I'm unsure as to whether that's my Windows install or ALL Windows installs.

The same application with no change was able to deal with 3500 request / second on Linux. Which is over 500% faster...

Please feel free to post here if you've had a similar experience to myself, i'd like to know if this is a Windows problem.

Benchmarking on the same machine, first booted into Linux, and then Windows.

Linux   GET             R/s 3534    3494    3568    3580    3528
        CLUSTER GET     R/s 11987   11565   11950   12042   12056
        GET DB INSERT   R/s 2251    2201    2167    2207    2132
        GET DB SELECT   R/s 2436    2512    2407    2457    2496

Windows GET             R/s 725     730     721     760     723
        CLUSTER GET     R/s 3072    3129    3421    2912    3203
        GET DB INSERT   R/s 611     623     605     632     610
        GET DB SELECT   R/s 672     691     701     698     682