This is the second post in a series of 3 about my experiences with Node.js. In this post I will discuss my experiences porting a RESTful service from Java and some basic benchmarks, comparing the Node.js service and the Java service.

If you haven’t read the first article in this series, you can view it here: Experiences with Node.js: Researching Node. My final post in this series Experiences with Node.js: Final Thoughts is now available, where I summarize my experiences, provide some feedback, and discuss my next steps with Node.js.

Since the writing of the first article in this series, there have been a few new releases to the Node.js project. You can read about these updates on the Node Blog.

Porting a Java Project

The ultimate goal in this Node.js research is to successfully port an existing RESTful service written in Java using Jersey (JAX-RS) on Tomcat to JavaScript running on Node.js. Not only could the experience be gained of building a useful service with Node, but some basic testing could gain some insights to its power and the results compared. If things go well here, more time and energy could be invested into Node.

The port will use the ExpressJS library as the base framework. ExpressJS is a great web application framework for Node.js. It is very powerful and offers some great plugin to extend its functionality. In this example, the Express Resource plugin is used to handle resource routing. This too is very convenient and simplified creating individual routes. The ORM layer uses Sequelize, a powerful ORM on top of MySQL.

Module installation

First, the modules need to be installed for use in this project. This example uses the Node Package Manager (NPM) to install the modules. The module files are copied to the local node_modules directory in the current path, making a convenient directory structure for packaging a project.


The app.js file contains the core instructions for the application. It defines the application, sets global variables, initializes the ORM, routes files, and starts our HTTP server. There are many good resources available on the web for creating this core file. This example uses a combination of many different techniques from multiple sources. It also includes added support for pulling in command line parameters. There are modules available that add helper methods for this, but it is pretty simple to handle without them.


This is the routing file that defines what URL’s will use which resource. Using the express-resource module, simple routes were created for the RESTful resources with very minimal lines of code. In this example, the URL is passed in and the Order resource module to the resource to define that relationship.


In the database.js file, the database object is created and a utility method for pushing the data from the model to an object is appended. After the ORM has created it’s database connection, the models can be built.


Using the Sequelize ORM model structure, the individual model Java classes are converted to a singular  object that represented all the database tables with validations, constraints and relationships. In this models.js example, there is a mapAttributes is linked to the function to return only the data in a specific model. For this example, the Order model is shown.


A basic set of CRUD functions are constructed for the model and replicated it for each resource. The Sequelize ORM made this task very simple and allowed for querying the database with a few very simple function calls and callbacks. After querying the ORM, the success callback will call the mapAttributes function and return a JSON object to the response object. In the case of an error, the error callback function fires returning the error to the response object. For this example, the List and the Show methods are shown as they will be used for the first tests. Other methods can be created for a RESTful implementation. Documentation for the Express Resource module can be found on the project site.

After preparing the modules, it was time to fire up the server and see if there are any errors. Fortunately, effort was put into later versions of Node.js to support larger, more detailed stack traces for troubleshooting.

The server fired up without issue because this code is awesome… (Ok, so in reality, there were issues, but they were worked out before writing this article, of course.)


Now that there has been success in the goal of successfully creating a JavaScript port of the CRUD resources of a Java service, it is time to test and compare the results between the technologies. The test plan is simple and fairly unscientific: use JMeter to capture throughput results of Node.js’s single threaded, non-blocking I/O model against the traditional Java application on Tomcat. JMeter is These tests are running locally from a MacBook Pro running 2.2GHz Intel Core i7, 8GB of 1333MHz DDR3 on OS X Lion 10.7.2.

The first tests against Node and the Tomcat server were hitting 7 of the resource’s list methods simultaneously with up to 128 users (threads), 50 times. The Node.js server and application were solid. Neither crashed or leak memory. The throughput and bites processed was consistent no matter how many users pegging the application. From a system resources standpoint, the Node process never topped 63MB of Memory, but a full processor core was consistently pegged at 100%. The Java Application also handled itself very well, but consumed a lot more system resources.

In these summaries, the standard deviation of the sample’s elapsed time, the total average requests per second (throughput), and the throughput in kilobytes per second have been recorded. The peak CPU and peak Memory usage are also noted during the tests.

JavaScript on Node.js
UsersStandard DeviationThroughputBandwidthPeak CPUPeak Memory
1615.480212.531 req/sec446.085 KB/sec99.6%57.9MB
3221.798211.456 req/sec443.828 KB/sec99.7%58.7MB
4830.709208.421 req/sec437.457 KB/sec99.6%59.0MB
6449.849205.131 req/sec430.553 KB/sec99.7%59.7MB
12898.737218.719 req/sec406.021 KB/sec99.5%61.0MB
Java on Tomcat
UsersStandard DeviationThroughputBandwidthPeak CPUPeak Memory
16120.065502.197 req/sec1245.193 KB/sec135.5%270.5MB
32189.948642.680 req/sec1593.522 KB/sec206.6%271.1MB
48280.655685.770 req/sec1700.362 KB/sec278.4%276.3MB
64286.626671.825 req/sec1665.785 KB/sec340.2%279.0MB
128320.229526.198 req/sec1304.609 KB/sec582.7%304.1MB

The results here are shocking. There was a dramatic difference between the Node.js service and the Java service. At the very least, the Node application should have performed almost as well as the Java version. There had to be something wrong here.

After more research and swapping out modules, the bottleneck was narrowed down to the Sequelize ORM. A direct correlation was identified between the number of records and the throughput from the resource. By increasing the number of records in a table, it exponentially decreased the throughput of data when using Sequelize. Although no research was put in to this, based on this finding it could be assumed the problems were in the logic that create the model objects. The models and database code were rewritten using the library by writing select statements and the tests were ran again using the new code. The results were much better using node-mysql and the system resources were also lower.

JavaScript on Node.js with
UsersStandard DeviationThroughputBandwidthPeak CPUPeak Memory
1694.879525.624 req/sec1089.159 KB/sec81.0% 53.8MB
32159.954686.779 req/sec1423.093 KB/sec83.0% 54.1MB
48210.742769.301 req/sec1594.089 KB/sec83.3% 54.6MB
64197.575703.849 req/sec1458.464 KB/sec86.0% 55.7MB
128208.428562.785 req/sec1166.163 KB/sec89.2% 57.1MB

In the end, the results were better by dropping Sequelize and using node-mysql. The throughput was pretty much on-par with the Tomcat server, consuming much less resources. There may be some amazing opportunities for optimization here that could easily push the Node.js beyond Tomcat’s. The results reasonably show that Node.js can perform as well as Java in this scenario.

Be sure to visit Experiences with Node.js: Final Thoughts, where I summarize my experiences, provide some feedback, and discuss my next steps with Node.js.