Premium Hosted Website & Server Monitoring Tool.

(Sysadmin / Devops blog)

visit our website

Blog   >   MongoDB   >   Real world MongoDB benchmarks with benchRun

Real world MongoDB benchmarks with benchRun

Benchmarks are interesting to look at from a general perspective but they often don’t really help test real world usage. You’re probably not that interested in how many concurrent inserts MongoDB can do to a single collection with a static document structure because in the real world you’ll have many clients connecting and executing many different types of queries – inserts, removes, updates and finds. You need to test your specific work profile on your specific hardware, and this is probably why MongoDB has no officially released benchmarks.

There is a tool built into MongoDB that allows you to benchmark specific queries in a custom way, so you can hit it with realistic queries – it’s called benchRun and is documented as the MongoDB JS Benchmarking Harness.

All you need to do is define the operations you want to perform (in normal Mongo console syntax) then pass them to the harness, along with how many instances you want to run in parallel (to simulate multiple clients). The example in the docs also shows how to test it with an increasing number of clients so you can gauge concurrent performance.

Here’s the example from the docs running on MongoDB 2.0.2 on my 11″ Macbook Air with 128GB SSD:

> db.foo.insert( { _id : 1 } )
> ops = [{ op : "findOne" , ns : "test.foo" , query : { _id : 1 } }, { op : "update" , ns : "test.foo" , query : { _id : 1 } , update : { $inc : { x : 1 } } } ]
[
	{
		"op" : "findOne",
		"ns" : "test.foo",
		"query" : {
			"_id" : 1
		}
	},
	{
		"op" : "update",
		"ns" : "test.foo",
		"query" : {
			"_id" : 1
		},
		"update" : {
			"$inc" : {
				"x" : 1
			}
		}
	}
]
> for ( x = 1; x<=128; x*=2){
...     res = benchRun( { parallel : x ,
...                       seconds : 5 ,
...                       ops : ops
...                     } )
...     print( "threads: " + x + "\t queries/sec: " + res.query )
... }
threads: 1	 queries/sec: 5821.2
threads: 2	 queries/sec: 8492.2
threads: 4	 queries/sec: 7671
threads: 8	 queries/sec: 5655
threads: 16	 queries/sec: 5261.2
threads: 32	 queries/sec: 5374.6
threads: 64	 queries/sec: 4083
threads: 128	 queries/sec: 3969.6

And the actual code you can copy/paste into your Mongo console:

db.foo.insert( { _id : 1 } )
ops = [{ op : "findOne" , ns : "test.foo" , query : { _id : 1 } }, { op : "update" , ns : "test.foo" , query : { _id : 1 } , update : { $inc : { x : 1 } } } ]
for ( x = 1; x<=128; x*=2){
    res = benchRun( { parallel : x ,
                      seconds : 5 ,
                      ops : ops
                    } )
    print( "threads: " + x + "\t queries/sec: " + res.query )
}

By defining the contents of the ops variable, you can specify exactly what kind of queries to run. Here I’m doing an atomic increment update and a findOne but you’d replace those with queries similar to what you expect to send to MongoDB.