Blog

Benchmarking ClusterNest Standard against Amazon OpenSearch Service

We ran OpenSearch Benchmark against a three-node ClusterNest Standard cluster and the matching Amazon OpenSearch Service configuration, from a test machine inside AWS’s own region. We measured bulk indexing, queries and both together, from a single client up to 64 in parallel, and priced each cluster at its list price.

Clusters and pricing

We picked the AWS configuration that matches our Standard tier on paper: the same vCPU and memory per node, three nodes, the same OpenSearch version.

ClusterNest Standard Amazon OpenSearch Service
Data nodes 3, each 2 vCPU, 16 GiB 3 × r6g.large.search, each 2 vCPU, 16 GiB
Storage 250 GB per node 250 GB gp3 per node
OpenSearch 3.7.0 3.7
Index layout 3 primaries, 1 replica 3 primaries, 1 replica
Monthly price $225 $551.28, excluding coordinator nodes and network traffic

OpenSearch 3.7 is the newest version Amazon OpenSearch Service offers, so we ran ClusterNest on 3.7.0 to match.

The AWS price is the on-demand list price in Europe (Frankfurt), checked on 15 October 2026: $0.202 an hour per r6g.large.search node for 730 hours, plus $0.1452 per GB-month for 250 GB of gp3 on each node. The cluster we tested ran 100 GB volumes, since the data never came close to filling them, and gp3 gives volumes of both sizes the same baseline IOPS and throughput. We also left out the three dedicated cluster manager nodes AWS recommends for production, which would add to the AWS bill. Every choice about the AWS side went toward the cheaper configuration.

Test machine placement

The test machine was an EC2 instance in eu-central-1, the same region as the AWS cluster: a c6i.large for the fixed-rate run and a c6i.2xlarge for the parallel sweeps, which never went above 43% CPU. That is where an AWS customer’s own applications would sit, and it gives AWS the shortest possible path.

ClusterNest’s endpoint is outside AWS, and every request to it also passes through a CDN and WAF layer before it reaches the cluster. From the same machine, on a connection that was already open, a _cluster/health request answered by the receiving node came back in:

Round trip from the test machine to each endpointRange plot of a _cluster/health request on an open connection. AWS: minimum 2.3, median 2.6, p90 2.8 milliseconds. ClusterNest: minimum 14.5, median 20.5, p90 45.5 milliseconds.Lower is better01020304050ClusterNestClusterNest, min: 14.5 msClusterNest, p90: 45.5 msClusterNest, p50: 20.5 msmin 14.5 · p50 20.5 · p90 45.5 msAWSAWS, min: 2.3 msAWS, p90: 2.8 msAWS, p50: 2.6 msmin 2.3 · p50 2.6 · p90 2.8 msRound trip (ms): band from minimum to p90, dot at the median
Every request to ClusterNest started at least 12 ms behind AWS, and about 43 ms behind at p90.

None of the results that follow correct for it.

Workload

We used OpenSearch Benchmark 2.4.0 and its http_logs workload, web server logs from the 1998 World Cup site, trimmed to its first three daily files: 25,460,091 documents, about 3.4 GB of JSON. The queries are the ones the workload ships with: a term lookup for one request line, GET / HTTP/1.0, a range over timestamps, and hourly_agg, a date histogram over the whole set.

Every number here comes from OpenSearch Benchmark’s own report. Both clusters finished every run with a 0% error rate.

Fixed-rate query schedule

The http_logs schedule sends each query from a single client at a fixed rate, 50 a second for term, and reports the latency.

On that schedule a single ClusterNest client spent about 110 ms per request against AWS’s 30, so it could send only about seven a second and fell short of the target rate on term, both status-code range queries and scroll.

Query throughput by client count

So we took the rate limit off and swept the number of clients: 1, 4, 8, 16, 32 and 64, each running the same query back to back for 45 seconds after a 10-second warmup. We turned off the shard request cache first. Without that, every repeat of hourly_agg after the first is answered from cache, and the test measures the cache.

Query throughput by number of parallel clients, for three query typesThree line charts, one per query type. For term and range queries, AWS levels off around 250 to 280 operations per second while ClusterNest keeps climbing to about 670 to 690 at 64 clients, crossing AWS at 16 clients. For the hourly aggregation, AWS levels off near 68 operations per second from 16 clients and ClusterNest reaches 172 at 64.ClusterNestAWSterm0200400600148163264ClusterNest, 1 client: 9.9 ops/sClusterNest, 4 clients: 40.5 ops/sClusterNest, 8 clients: 85.2 ops/sClusterNest, 16 clients: 189.6 ops/sClusterNest, 32 clients: 437.6 ops/sClusterNest, 64 clients: 668.6 ops/sClusterNest 669AWS, 1 client: 35.5 ops/sAWS, 4 clients: 113.4 ops/sAWS, 8 clients: 167.3 ops/sAWS, 16 clients: 219.4 ops/sAWS, 32 clients: 254.6 ops/sAWS, 64 clients: 278.2 ops/sAWS 278range0200400600148163264ClusterNest, 1 client: 10.3 ops/sClusterNest, 4 clients: 41.5 ops/sClusterNest, 8 clients: 84.5 ops/sClusterNest, 16 clients: 190 ops/sClusterNest, 32 clients: 444.8 ops/sClusterNest, 64 clients: 686.7 ops/sClusterNest 687AWS, 1 client: 40.2 ops/sAWS, 4 clients: 117.3 ops/sAWS, 8 clients: 150.2 ops/sAWS, 16 clients: 188.1 ops/sAWS, 32 clients: 228.1 ops/sAWS, 64 clients: 250.3 ops/sAWS 250hourly_agg0100200148163264ClusterNest, 1 client: 9.6 ops/sClusterNest, 4 clients: 43.4 ops/sClusterNest, 8 clients: 84.4 ops/sClusterNest, 16 clients: 133.4 ops/sClusterNest, 32 clients: 155.7 ops/sClusterNest, 64 clients: 172.3 ops/sClusterNest 172AWS, 1 client: 21.9 ops/sAWS, 4 clients: 51.7 ops/sAWS, 8 clients: 60.7 ops/sAWS, 16 clients: 68.6 ops/sAWS, 32 clients: 67.9 ops/sAWS, 64 clients: 67.5 ops/sAWS 68Parallel query clientsOperations per second
AWS levels off as clients rise. ClusterNest keeps climbing, past AWS at 16 clients for term and range and at 4 to 8 for the aggregation.
QueryClientsOperations per second, higher is betterp90 latency (ms), lower is better
AWSClusterNestAWSClusterNest
term135.59.930109
term16219190107106
term64278669318137
range140.210.326127
range16188190100121
range64250687362132
hourly_agg121.99.648134
hourly_agg1668.6133294153
hourly_agg6467.51721,155416

AWS runs out of room first. hourly_agg stops gaining at about 68 operations a second from 16 clients on, and from then on every extra client only adds queueing. term and range still creep upward at 64 clients, but their latency grows faster than their throughput does.

ClusterNest’s latency barely moves.

p90 latency of a term query by number of parallel clientsLine chart. AWS p90 latency rises from 30 milliseconds at 1 client to 318 at 64. ClusterNest stays between 104 and 109 milliseconds up to 32 clients and reaches 137 at 64, crossing AWS at 16 clients.Lower is betterClusterNestAWS0100200300148163264ClusterNest, 1 client: 108.9 msClusterNest, 4 clients: 108.7 msClusterNest, 8 clients: 105.8 msClusterNest, 16 clients: 106 msClusterNest, 32 clients: 104.2 msClusterNest, 64 clients: 136.5 msClusterNest 137 msAWS, 1 client: 29.6 msAWS, 4 clients: 45.4 msAWS, 8 clients: 65.4 msAWS, 16 clients: 107 msAWS, 32 clients: 176.8 msAWS, 64 clients: 318 msAWS 318 msParallel query clientsp90 latency (ms)
ClusterNest's p90 for a term query holds near 105 ms from 1 client to 32. AWS starts lower and passes it at 16 clients.

Its 110 ms is a fixed cost per request, not a sign of a busy cluster, so more clients add throughput almost one for one. At 64 clients ClusterNest served 669 term queries a second with a p90 of 137 ms. AWS served 278 at 318 ms. It had not hit a ceiling at 64; we stopped there.

Bulk indexing throughput by client count

Bulk indexing shows the same shape, more sharply. We sent 5,000-document bulk requests from 1 to 32 parallel clients, 90 seconds per step after a 20-second warmup, into fresh indices.

Bulk indexing throughput by number of parallel bulk clientsLine chart. AWS rises from 27,634 documents per second at 1 client to about 60,000 from 4 clients on. ClusterNest rises from 6,905 at 1 client to 131,301 at 32 clients, crossing AWS between 4 and 8 clients.ClusterNestAWS040K80K120K1481632ClusterNest, 1 client: 6,905 docs/sClusterNest, 4 clients: 40,664 docs/sClusterNest, 8 clients: 77,409 docs/sClusterNest, 16 clients: 91,808 docs/sClusterNest, 32 clients: 131,301 docs/sClusterNest 131KAWS, 1 client: 27,634 docs/sAWS, 4 clients: 58,565 docs/sAWS, 8 clients: 58,206 docs/sAWS, 16 clients: 63,581 docs/sAWS, 32 clients: 60,226 docs/sAWS 60KParallel bulk clients (5,000 documents per request)Documents per second
AWS reaches about 60,000 documents a second with 4 clients and stays there. ClusterNest passes it between 4 and 8 clients and reaches 131,000 at 32.
Bulk clientsDocuments per second, higher is betterp90 latency (ms), lower is better
AWSClusterNestAWSClusterNest
127,6346,905161701
458,56540,664443527
858,20677,409903601
1663,58191,8081,342990
3260,226131,3013,4011,733

One bulk request of 5,000 documents, about 670 KB, took around 620 ms to reach ClusterNest and complete, against 134 ms for AWS. A shipper that keeps a single request in flight gets about 7,000 documents a second. Four in flight gets 40,000, and 32 get 131,000, more than twice the most we could push into the AWS cluster with any number of clients.

Queries during bulk indexing

Log clusters rarely get to choose between reading and writing, so we ran the query sweep a second time with a background feed of 10,000 documents a second, about a sixth of what the AWS cluster could absorb on its own.

Query throughput at 64 parallel clients during a 10,000 documents per second bulk feedGrouped column chart. At 64 clients with bulk indexing running, ClusterNest served 578 term, 516 range and 167 hourly_agg operations per second; AWS served 210, 216 and 53.ClusterNestAWS0200400600termClusterNest, term: 578.3 ops/s578AWS, term: 209.5 ops/s210rangeClusterNest, range: 515.9 ops/s516AWS, range: 216.4 ops/s216hourly_aggClusterNest, hourly_agg: 166.8 ops/s167AWS, hourly_agg: 52.9 ops/s53Operations per second
At 64 clients with the bulk feed running, ClusterNest served 2.4 to 3.2 times AWS's query rate. Its p90 stayed between 158 and 440 ms; AWS's ran from 426 to 1,528 ms.

AWS lost 14 to 25% of its peak query rate to the writes. ClusterNest lost 3 to 25% and kept the larger lead at every client count above 16. Both held the feed at 10,000 documents a second for most of the run. The exceptions were the heaviest steps: AWS slipped to 7,600 at 64 term clients, and ClusterNest to 6,200 at 64 hourly_agg clients.

Throughput per dollar

Dividing the highest rate each cluster reached in the sweeps by its monthly price gives the throughput each $100 a month buys. The AWS price is the lowest that configuration can cost, before data transfer and coordinator nodes, so the AWS bars are the most a dollar could buy there.

Peak measured throughput per $100 of monthly priceFour pairs of horizontal bars, each on its own scale, giving peak throughput per $100 of monthly price. Bulk indexing (docs/s): ClusterNest 58,356, AWS 11,533. term (ops/s): ClusterNest 297, AWS 50. range (ops/s): ClusterNest 305, AWS 45. hourly_agg (ops/s): ClusterNest 77, AWS 12.Peak throughput per $100 of monthly priceHigher is betterBulk indexing (docs/s)ClusterNestClusterNest, Bulk indexing (docs/s): 58,35658,356AWSAWS, Bulk indexing (docs/s): 11,53311,533term (ops/s)ClusterNestClusterNest, term (ops/s): 297297AWSAWS, term (ops/s): 5050range (ops/s)ClusterNestClusterNest, range (ops/s): 305305AWSAWS, range (ops/s): 4545hourly_agg (ops/s)ClusterNestClusterNest, hourly_agg (ops/s): 7777AWSAWS, hourly_agg (ops/s): 1212
Per dollar, ClusterNest delivered at least 5.1 to 6.7 times AWS's peak throughput.

These are the highest rates each cluster reached, not its ceiling. AWS had stopped gaining on bulk indexing and hourly_agg. ClusterNest was still climbing on every measure when the sweeps ended.

Limitations

  • A strictly sequential client pays the per-request floor. A script that sends one query, waits for the answer and then sends the next sees about 110 ms per request on ClusterNest against 30 ms on AWS, from inside AWS’s region.
  • One region, one day. The test machine sat in Frankfurt, next to AWS. A machine in another region, or in your own data centre, would close some or all of the 12 ms gap.
  • Repeat runs of heavy aggregations moved more on ClusterNest. Over two passes of the stock schedule, the p90 of hourly_agg_with_filter went from 221 ms to 576 ms on ClusterNest and from 383 ms to 389 ms on AWS. The parallel sweeps ran once each.
  • Shortened schedules. Fixed-rate queries ran 20 measured iterations rather than the workload’s 100, and each sweep step ran 45 seconds. Percentiles beyond p90 are noisy at that length, so we do not quote them.
  • No dedicated cluster managers on AWS. Adding them, as AWS recommends, would raise the AWS price and might help its coordination time.

Reproducing the test

Everything here runs on open-source tools: OpenSearch Benchmark 2.4.0 from its Docker image, the http_logs workload trimmed to logs-181998, logs-191998 and logs-201998, three primaries and one replica per index, 5,000-document bulk requests. The sweeps are three custom test procedures in that workload, and we will send them to anyone who asks.

Run it from where your applications run. The result that counts is the one from your own network, with your own concurrency.

ClusterNest Standard

A three-node ClusterNest Standard cluster is $225 a month at a flat per-node price. Ingest isn’t metered, queries aren’t counted, and Dashboards, coordinator nodes and support are included, so 669 queries a second cost the same as one. The pricing page sets it against AWS, Datadog and New Relic for a full logging workload.

If you are weighing it against Amazon OpenSearch Service for a workload of your own, write to [email protected]. We are happy to run your numbers with you.