Evaluating NoSQL performance: Which database is right for your data?
Sergey Sverchkov explains how you can cut through the masses of NoSQL marketing jargon and find the perfect database for your project.
Often referred to as NoSQL, non-relational databases
feature elasticity and scalability. In addition, they can store big
data and work with cloud computing systems. All of these factors
make them extremely popular. In 2013, the number of NoSQL products
reached 150 plus, and the figure is still growing. That variety
makes it difficult to select just one. To make things worse, the
abundance of marketing materials describing NoSQL products makes it
hard to understand whether a particular solution will be useful for
your use case.
To choose the best NoSQL solutions for our customer’s
projects, we at Altoros test them under varying types of workloads.
This article overviews the results of the latest performance tests
of some of the most mature and popular NoSQL data stores on the
NoSQL data stores: The basics
Why did NoSQL data stores appear? Mostly because
relational databases (RDBMS) have a number of restrictions when
working with large datasets. For example, RDBMS are hard to scale
and their architecture is designed to work on a single machine
-Scaling write operations is hard, expensive, or
-Vertical scaling (or upgrading equipment) is either
limited or very expensive. Unfortunately, this is often the only
possible way you can scale.
-Horizontal scaling (or adding new nodes to the
cluster) is either unavailable or you can only implement it
partially. There are some solutions from Oracle and Microsoft that
make it possible to have computing instances on several servers.
Still, the database itself remains in shared storage.
In addition to poor scalability, RDBMS have strict
data models. The schema is created together with the database and
you may need significant time and effort to change this structure.
In most cases it is a complex process that most likely involves a
considerable amount of production downtime. Apart from that, RDBMS
have difficulties with semi-structured data.
NoSQL solutions address these and a lot of other
problems. Several types exist – key-value, columnar,
document-oriented, and graph. None of them use the relational data
model, being inherently schema-free, without obsessive complexity,
with a flexible data model and eventual consistency (complying with
BASE rather than ACID).
NoSQL data stores provide APIs to perform various
operations. Some of them support query language operations, for
example, Cassandra and HBase. However, there is no standard. NoSQL
architectures are designed to run in clusters. This makes it
possible to scale them horizontally by increasing the number of
nodes in the deployment. In addition, NoSQL data stores serve huge
amounts of data and provide a very high throughput.
How do you evaluate NoSQL data stores?
NoSQL databases differ from RDBMS in their data models.
These systems can be divided into four distinct groups:
Key-value stores are similar to maps or
dictionaries where data is addressed by a unique key.
Document-oriented stores encapsulate key value
pairs in JSON or JSON like documents. Within documents, keys have
to be unique. In contrast to key-value stores, values are not
opaque to the system and can be queried, as well.
Column family stores are also known as column
oriented stores, extensible record stores, and wide columnar
Graph databases—in contrast to key oriented
NoSQL databases, graph databases are specialized in efficient
management of heavily linked data.
NoSQL databases differ in the way they distribute data
among multiple machines. Since data models of key-value stores,
document stores, and column family stores are key oriented, the two
common partition strategies are based on keys, too:
1. The first strategy distributes datasets by the range of
their keys. A routing server splits the whole keyset into blocks
and allocates these blocks to different nodes. Afterwards, one node
is responsible for storage and request handling of his specific key
ranges. In order to find a certain key, clients have to contact the
routing server to get the partition table.
2. Higher availability and much simpler cluster architecture
can be achieved with the second type of distribution.
Replication is another “core” feature of NoSQL
solutions. In addition to better read performance through load
balancing, replication brings better availability and durability,
because failing nodes can be easily replaced.
If all replicas of a master server were updated
synchronously, the system would not be available until all slaves
had committed a write operation. That is why this solution is not
suitable for platforms relying on high availability, because even a
few milliseconds of latency can have a big influence on user
And obviously, performance is also a very important
factor. Performance of data storage solutions can be evaluated
using typical scenarios. These scenarios simulate the most common
operations performed by applications that use the data store, also
known as typical workloads. The tests that were performed by
Altoros to compare performance of several NoSQL data stores also
used typical workloads.
Performance evaluation approach
Database vendors usually measure productivity of their
products with custom hardware and software settings designed to
demonstrate the advantages of their solutions. In our tests we
tried to see how NoSQL data stores perform under the equal
For benchmarking, we used the Yahoo Cloud Serving
Benchmark (YCSB). The kernel of YCSB has a framework with a
workload generator that creates test workload and a set of workload
scenarios. When using YCSB, developers have to describe the
scenario of the workload by operation type, i.e. indicate what
operations are performed on what types of records. Supported
operations include: insert, update (change one of the fields), read
(one random field or all the field of one record), and scan (read
the records in the order of the key starting from a randomly
In our tests each workload was applied to a table of
100,000,000 records; each record was 1,000 bytes in size and
contained 10 fields. A primary key identified each record, which
was a string, such as, for example, “user234123”. Each field was
named field0, field1, and so on. The values in each field were
random strings of ASCII characters, 100 bytes each.
Database performance was defined by the speed at which
it computed basic operations. An action performed by the workload
executor, which drives multiple client threads, was considered to
be a basic operation. In a NoSQL data store, each thread executes a
sequential series of operations by making calls to the database
interface layer both to load the database (the load phase) and to
execute the workload (the transaction phase). The threads throttle
the rate at which they generate requests, so that we may directly
control the load. In addition, the threads measure the latency and
throughput achieved when performing operations. This data is then
sent to the statistics module.
For our test, we decided to use the AWS public cloud
environment. All the virtual machines operated in one region
(Ireland, Europe) and in one availability zone (or one datacenter).
Each database stored data in a four-node cluster. We used m1.xlarge
computing instances. The nodes were 64-bit instances with 16 GB of
RAM, 4 vCPU, 8 ECU, and high-performance network. We used Amazon
Linux as the operating system.
For each node in the cluster, we created data storage.
We used four EBS optimized elastic block storage volumes (EBS) of
25 GB each. The volumes were assembled in RAID0. Data were
distributed or sharded into 4 nodes.
The client with the YCSB framework was on a separate
c1.xlarge instance. For MongoDB, we used two additional c1.medium
instances that served as routers. This was necessary due to the
specifics of MongoDB’s architecture.
We started all the instances with the same security
group and preconfigured all the necessary network ports for the
nodes to communicate. We also configured all the ports required for
each database to be opened. Then we uploaded workload definitions
to the YCSB client and performed the tests. The results were
measured at the instance where YCSB was installed.
Figure 1: The infrastructure for testing NoSQL data
stores. Source: Altoros
Databases to evaluate and workload definitions
In our test we measured the performance of several
NoSQL databases that we consider to be the most mature and popular
products on the market. Let’s take a closer look at each of
Cassandra 2.0. This is a column-value data
store. We ran it with Java 1.7.40 installed. The transactions were
performed with the non-default configuration. In particular, we
used a random partitioner to section data by nodes. The amount of
data cash for the keys was 1 GB. The size of row cash was 6 GB. The
size of JVM heap was 6 GB.
MongoDB 2.4.6. This is a document-oriented
database. Here, we did not do much additional configuration or
tuning—we added two instances that served as routers, as
recommended by MongoDB documentation. However, if you need to
simplify the model, mongo router may run on the same machine where
the YCSB client is. In one of our earlier tests, we discovered that
it uses a lot of CPU. This is why we placed router processes on 2
separate machines. Data sharding for MongoDB was based on document
HBase 0.92. For HBase, we set the size of memory
for the JVM to 12 GB.
Additionally, we used data compression with the Snappy
compressor for Cassandra and HBase.
The replica factor was set to one for all data stores.
This approach was intentional – we wanted to test performance, not
the failure tolerance of the cluster.
We used the following workloads with the YSCB
Workload A. Workload A is an update-heavily
scenario that simulates how a database works, when recording
typical actions of an e-commerce solution user.
Workload B. Workload B is a read-mostly workload
that has a 95/5 (ninety five to five percent) read/update ratio. It
recaps content tagging when adding a tag is an update, but most
operations include reading tags.
Workload C. Workload C is a read-only workload
that simulates a data caching layer, for example a user profile
Workload D. Workload D has a 95/5 read/insert
ratio. The workload simulates accessing the latest data, such as
user status updates, or working with inbox messages.
Workload E. Workload E is a scan-short-ranges
workload with a scan/insert percentile proportion of 95/5. It
simulates threaded conversations that are clustered by a thread ID.
Each scan is performed for the posts of a given thread.
Workload F. Workload F has
read-modify-write/read ops in a proportion of 50/50. It simulates
accessing a user database where records are read and modified by
the user. This activity is also recorded to this
Workload G. Workload G has a 10/90 read/insert
ratio. It simulates a process of data migration or a process of
creating large amounts of data.
Every workload was executed by 100 concurrent threads.
The dataset consisted of 100,000,000 records and the number of
operations that were divided between threads was 10,000.
During the first stage of the test, the load phase, we
uploaded 100,000,000 records of 1 Kb each to every data store. YCSB
measured the average throughput in operations per second and
average latency of operations in milliseconds. The next diagram
displays the results of the load phase:
Figure 2: The results of the load phase. Source:
HBase demonstrated the lowest throughput, probably
because we turned on the auto-flash mode. This mode ensures that
each operation that creates a record will be sent from the client
to the server and then persisted to the database. HBase also
supports an alternative mode that uses additional cash on the
client side. When the client is out of client cache it sends data
from the cash to the server. In this alternative mode, HBase saves
data to disk in batches.
As we expected, Cassandra demonstrated excellent
results with almost 18,000 operations per second. This is due to
Cassandra’s architecture. It simultaneously updates data in memory
and writes it to the transaction journal on the disk. This
guarantees data persistency should a node crash.
The number of operations per second in MongoDB’s
results was pretty close to that of Hbase – the average latency was
around seven milliseconds at 13,000 operations per second.
In this particular test, all data was loaded in a
single iteration, but insert, update, read, and scan operations in
the transaction phase of the test were performed in five iterations
for each workload (for every database).
It should be noted that many of the diagrams with test
results demonstrate that database performance is limited and starts
to decline at a certain throughput level. Also we need to mention
that we used Amazon AWS and network storage which could potentially
influence the results.
Workload A includes read and update operations in a
ratio of 50/50. It simulates an e-commerce application. This slide
shows the results of update operations.
Figure 3: The results of update operations in Workload
A. Source: Altoros
Cassandra and HBase demonstrated good performance with
a throughput below 20 milliseconds.
MongoDB’s latency increased substantially as we
increased the workload. At 100 operations per second all the four
databases had similar performance. But when the workload reached
1,500 operations per second, MongoDB’s latency increased to 100
The next diagram shows results of read operations in
Figure 4: Figure 4. The results of read operations for
Workload A. Source: Altoros
All the graphs are very different because reads and
updates were randomly distributed. The results for read operations
in Workload A were more or less similar in all the tested
solutions. The difference in latencies was insignificant, within a
range of 15-30 milliseconds.
Workload B is read-mostly with 95% of reads and only
5% of updates. It simulates content tagging when adding a tag is an
update, but most other transactions are reads. Here are the results
for update operations in workload B.
Figure 5. The results of update operations for
Workload B. Source: Altoros
Cassandra demonstrates a very low latency, but her
performance is limited to 1200 operations per second. With HBase,
the latency increases evenly as the workload grows. The behavior of
MongoDB is similar to the previous test where the latency increased
together with the throughput.
The next slide shows the results of read operations
that make up 95% of Workload B.
Figure 6. The results of read operations for Workload
B. Source: Altoros
HBase demonstrated the highest throughput with several
peaks in latency. MongoDB also had good results thanks to its
architecture, which features memory-mapped files. On this diagram,
there are points where the maximum throughput starts to degrade.
They were left here on purpose.
Workload C is a read-only workload. MongoDB’s
performance does not degrade as the workload increases. Latency
peaks on the graphs for Cassandra and HBase can be explained by the
fact that we used cloud infrastructure to run the tests and network
storage for the data nodes.
Figure 7. The results of read operations for Workload
C. Source: Altoros
Workload D includes a 5% of insert and 95% of read
operations. It simulates users checking inbox messages or accessing
latest data, for example, status updates. The following slide shows
the results of insert operations.
Figure 8. The results of insert operations for
Workload D. Source: Altoros
Cassandra demonstrated the best performance. The
latencies were within five milliseconds. This is similar to what we
saw at the upload stage where Cassandra was pretty efficient.
The maximum throughput for HBase is 1500 operations
Mongo has an acceptable throughput of up to 2500 ops
per second. At the same time, the average latency doubles.
Read operations are the second scenario in Workload D.
Cassandra and MongoDB achieved good results. For HBase, the
throughput was limited to 1500 operations per second. The maximum
throughput in this mixed workload was demonstrated by MongoDB.
Figure 9. The results of read operations for Workload
D. Source: Altoros
Workload F consisted of randomly distributed read and
complex read/modify/write operations. Each record was read,
changed, and then saved to the database.
The first diagram shows the results of read operations
only. All the databases demonstrated similar results in this test.
Cassandra and HBase had maximum throughput values of about 1,500
operations per second (for read operations). Performance of MongoDB
starts to decline at less than 1,000 operations per second.
Figure 10. The results of read operations for Workload
F. Source: Altoros
The second diagram for Workload F shows the results of
update operations performed on data that has already been read.
Hbase and Cassandra have very low latencies. As you
can see on all the previous graphs, update operations are performed
pretty fast by all the databases, except for MongoDB. As we
increase the workload, MongoDB’s latency starts to grow
Figure 11. The results of read operations for Workload
F. Source: Altoros
The third diagram for Workload F shows the results of
read-modify-write operations. Cassandra and HBase have similar
performance. MongoDB’s latency increases together with the
workload, up to the maximum throughput of roughly 1,000 operations
We can conclude that Cassandra and Hbase are pretty
good at dealing with mixed workloads.
Figure 12. The results of read-modiry-write operations
for Workload F. Source: Altoros
The last workload, Workload G, mostly consists of
insert operations. It simulates the process of data migration or
inserting a lot of data into a database. The results are similar to
what you can see on the previous graphs. HBase and Cassandra
demonstrate low latencies and a high throughput. MongoDB’s
performance starts to decline at about 4,000 ops per second with an
average latency up to five times greater than in other
Figure 13. The results of insert operations for
Workload G. Source: Altoros
Below is the last diagram, showing the results of the
read operations which make up 10% of workload G. Here we can see
that latencies vary for different solutions. This might be because
the data is in network storage on the cloud. Cassandra shows a
maximum throughput of up to 7,000 operations per second and
MongoDB’s throughput is limited by 4,000 operations per second.
Figure 14. The results of read operations for Workload
G. Source: Altoros
What you choose depends on your needs. Before making
the decision you should:
Determine what your data sets and your data
model will be like; the data model will depend on the data sets and
typical operations that your app will perform
Determine your requirements to transaction
support; decide whether you need transactions
Choose whether you need replication;
decide on your requirements to data consistency
Determine your performance
If the project is based on an existing
solution, evaluate if it is possible to migrate existing
Then, taking into account all these factors, evaluate
different solutions and test their performance. It is very useful
to build a prototype of your future system during the
proof-of-concept phase. Prototyping makes it possible to see how
the solution will work in a real-life project. If it does not work
well enough, you need to review the architecture, the components,
and build a new prototype.
There are no perfect solutions and there are no bad
NoSQL or RDBMS data stores. Which database is the best for your use
case can be determined by particular system requirements. The tests
performed by Altoros show that in different scenarios different
solutions have very different results. Your final choice might be a
compromise. The main determinant will be what you want to achieve
and what properties you need most. The system may use several
solutions, including relational and NoSQL databases.
Sergey Sverchkov: Head of Software
With more than 15 years in IT industry and strong
experience in the whole cycle of software project development and
support, Sergey serves as Senior R&D Engineer and Project
Manager at Altoros. He specializes in Big Data analysis,
integration and processing. Sergey is an Oracle DBA trainer, and a
frequent speaker on data analysis and cloud technologies.