<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: HotKV Ltd</title>
    <description>The latest articles on DEV Community by HotKV Ltd (@hotkv-ltd).</description>
    <link>https://dev.to/hotkv-ltd</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4191755%2F33e9521d-d987-4806-8bc4-edda6da08dce.png</url>
      <title>DEV Community: HotKV Ltd</title>
      <link>https://dev.to/hotkv-ltd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hotkv-ltd"/>
    <language>en</language>
    <item>
      <title>Redis benchmark: HotKV vs Valkey and Dragonfly in a three-node cluster</title>
      <dc:creator>HotKV Ltd</dc:creator>
      <pubDate>Thu, 05 Nov 2026 19:00:00 +0000</pubDate>
      <link>https://dev.to/hotkv/redis-benchmark-hotkv-vs-valkey-and-dragonfly-in-a-three-node-cluster-63l</link>
      <guid>https://dev.to/hotkv/redis-benchmark-hotkv-vs-valkey-and-dragonfly-in-a-three-node-cluster-63l</guid>
      <description>&lt;p&gt;This Redis benchmark runs HotKV, Redis, Valkey and Dragonfly as three-node clusters on AWS. Our earlier benchmarks ran each server as one instance on a whole machine. That layout suits HotKV, which uses every core in one process. Redis and Valkey run commands on one thread per process, and they are commonly scaled across cores with many processes, usually as a cluster. So we measured every product the way a cluster deploys it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;In short.&lt;/strong&gt; In this Redis benchmark on three AWS servers, HotKV had the highest throughput on 8 of 9 commands: 92.3 million GETs per second against 57.3 million for Redis, 52.9 million for Valkey and 22.5 million for Dragonfly. Redis and Valkey were ahead on APPEND. The load generators were near their limit on some commands, so the figures are lower bounds.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why we ran this Redis benchmark as a cluster
&lt;/h2&gt;

&lt;p&gt;A single-instance benchmark, like the one in our &lt;a href="https://hotkv.com/blog/introducing-hotkv" rel="noopener noreferrer"&gt;launch article&lt;/a&gt;, asks how much one server process can do with a whole machine. That is a reasonable question for HotKV and Dragonfly, which use all cores in one process. It says less about Redis and Valkey. Their commands run on one thread per process (I/O threads can offload network work), so a 48-vCPU server is normally used by running dozens of processes.&lt;/p&gt;

&lt;p&gt;We do not want our numbers to depend on a layout that suits one architecture better than another. A cluster is common ground. All four products can run as one, and for Redis and Valkey it is a usual way to use many cores. We ran this benchmark to see how the comparison looks when each product is deployed that way.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we tested
&lt;/h2&gt;

&lt;p&gt;Every product ran as a cluster on the same three servers, one product at a time, driven by the same two load generators. The sections below give the machines, each layout and the procedure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fhotkv.com%2Fblog%2Ffigures%2Fcluster-benchmark.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fhotkv.com%2Fblog%2Ffigures%2Fcluster-benchmark.svg" alt="The Redis benchmark setup. Two load-generator machines drive three servers that form one cluster. HotKV and Dragonfly run one process per server with 40 threads, Redis and Valkey run 40 single-thread processes per server." width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Machines
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Servers.&lt;/strong&gt; Three &lt;code&gt;c8in.12xlarge&lt;/code&gt; instances (Intel Xeon 6975P-C, 48 vCPUs, 75 Gbit/s network) in one AWS cluster placement group in eu-south-2a, running Ubuntu 24.04. Every server process was pinned to CPUs 0 to 39.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Load generators.&lt;/strong&gt; One &lt;code&gt;c8in.48xlarge&lt;/code&gt; running 16 &lt;code&gt;memtier_benchmark&lt;/code&gt; processes of 12 threads each, and one &lt;code&gt;c8in.12xlarge&lt;/code&gt; running 4 processes of 12 threads. They were started together and the operations per second of all processes were added up.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tuning.&lt;/strong&gt; All five machines got the same host tuning: the repository's &lt;code&gt;tune_server.sh&lt;/code&gt;, receive packet steering over all CPUs, the network card's receive ring at its maximum, a larger softirq budget and a listen backlog of 65,535.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Servers and layout
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HotKV.&lt;/strong&gt; One process per server with 40 threads, in cluster mode (3 primaries). The build is 0.3.0 plus a change that adds the &lt;code&gt;pipeline-prefetch&lt;/code&gt; setting, and it ran with &lt;code&gt;pipeline-prefetch yes&lt;/code&gt;. The setting is off by default. It looks ahead in a client's pipeline and asks the CPU for the memory the next commands will read.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redis 8.10.3 and Valkey 9.1.3.&lt;/strong&gt; 40 single-thread processes per server, so 120 primaries, in cluster mode. Each process had a core to itself. Their own batch prefetching was left at its default.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dragonfly 2.0.2.&lt;/strong&gt; One process per server with 40 threads, in cluster mode, built from source.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persistence.&lt;/strong&gt; Off on every server.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Workload and procedure
&lt;/h3&gt;

&lt;p&gt;The data set was 5,000,000 keys with 256-byte values, and pipeline depth was 100. &lt;code&gt;memtier_benchmark&lt;/code&gt; ran in cluster mode, so each client talks to the right node. Each command ran for 15 seconds, twice, and we report the median of the two. The data set was loaded again, identically, before every run, so a command never ran on top of the previous command's changes. The scripts and every run are in the &lt;a href="https://github.com/HotKV-LTD/hotkv/tree/main/results/aws-c8in-12xlarge-cluster-256B-p100-4server-2run-v0.3.0-20261101" rel="noopener noreferrer"&gt;benchmark repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;Millions of operations per second, median of two runs. The highest value in each row is in bold.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;HotKV&lt;/th&gt;
&lt;th&gt;Redis 8.10.3&lt;/th&gt;
&lt;th&gt;Valkey 9.1.3&lt;/th&gt;
&lt;th&gt;Dragonfly 2.0.2&lt;/th&gt;
&lt;th&gt;HotKV vs Redis&lt;/th&gt;
&lt;th&gt;HotKV vs Valkey&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;92.3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;57.3&lt;/td&gt;
&lt;td&gt;52.9&lt;/td&gt;
&lt;td&gt;22.5&lt;/td&gt;
&lt;td&gt;1.61x&lt;/td&gt;
&lt;td&gt;1.74x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SET&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;76.1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;55.0&lt;/td&gt;
&lt;td&gt;48.5&lt;/td&gt;
&lt;td&gt;25.2&lt;/td&gt;
&lt;td&gt;1.38x&lt;/td&gt;
&lt;td&gt;1.57x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SETNX&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;86.1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;60.7&lt;/td&gt;
&lt;td&gt;57.0&lt;/td&gt;
&lt;td&gt;27.5&lt;/td&gt;
&lt;td&gt;1.42x&lt;/td&gt;
&lt;td&gt;1.51x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;INCR&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;119.2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;118.4&lt;/td&gt;
&lt;td&gt;104.6&lt;/td&gt;
&lt;td&gt;30.8&lt;/td&gt;
&lt;td&gt;1.01x&lt;/td&gt;
&lt;td&gt;1.14x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SADD&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;51.7&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;40.4&lt;/td&gt;
&lt;td&gt;33.8&lt;/td&gt;
&lt;td&gt;22.7&lt;/td&gt;
&lt;td&gt;1.28x&lt;/td&gt;
&lt;td&gt;1.53x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RPUSH&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;47.1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;29.3&lt;/td&gt;
&lt;td&gt;29.0&lt;/td&gt;
&lt;td&gt;18.7&lt;/td&gt;
&lt;td&gt;1.61x&lt;/td&gt;
&lt;td&gt;1.62x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HSET&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;38.4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;28.8&lt;/td&gt;
&lt;td&gt;27.2&lt;/td&gt;
&lt;td&gt;18.4&lt;/td&gt;
&lt;td&gt;1.33x&lt;/td&gt;
&lt;td&gt;1.41x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LPUSH&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;31.1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;23.7&lt;/td&gt;
&lt;td&gt;24.0&lt;/td&gt;
&lt;td&gt;16.9&lt;/td&gt;
&lt;td&gt;1.31x&lt;/td&gt;
&lt;td&gt;1.30x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;APPEND&lt;/td&gt;
&lt;td&gt;35.0&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;41.7&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;40.9&lt;/td&gt;
&lt;td&gt;10.4&lt;/td&gt;
&lt;td&gt;0.84x&lt;/td&gt;
&lt;td&gt;0.86x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Against Dragonfly, HotKV was ahead on all nine commands, from 1.85 times (LPUSH) to 4.09 times (GET).&lt;/p&gt;

&lt;h2&gt;
  
  
  How to read the ratios
&lt;/h2&gt;

&lt;p&gt;A throughput figure from a load test is a floor when the load generators are the limit. If a load generator is at 100 percent CPU, the server may have been able to take more. The figure then shows only that it took at least this much. A ratio between two floors is not exact, because either side could be higher.&lt;/p&gt;

&lt;p&gt;We flag every figure where the main load generator ran above 85 percent CPU. These were GET, SETNX and INCR for HotKV, and GET, SET, SETNX, INCR, SADD, HSET and APPEND for Redis and Valkey. On those figures, read the ratio as a rough size and not a precise one.&lt;/p&gt;

&lt;p&gt;On SADD and HSET, HotKV's figure is not flagged but Redis's and Valkey's are. Their true throughput may be higher, and HotKV's lead smaller than shown. The same applies to APPEND, where it would make their lead over HotKV larger than shown.&lt;/p&gt;

&lt;p&gt;RPUSH and LPUSH have no flag for any server, so they give the cleanest comparison. HotKV was 1.3 to 1.6 times ahead of Redis and Valkey on them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the results show
&lt;/h2&gt;

&lt;p&gt;Three things stand out in the table, and the first is about Redis and Valkey rather than HotKV.&lt;/p&gt;

&lt;h3&gt;
  
  
  Redis and Valkey scale well as clusters
&lt;/h3&gt;

&lt;p&gt;With 120 single-thread processes, Redis served 57 million GETs per second and 118 million INCRs per second across three servers. That confirms the cluster layout suits them. It is also why HotKV's margin here is smaller than in our single-instance runs.&lt;/p&gt;

&lt;p&gt;Those runs compared a design that uses all cores in one process with products that were not run in the layout they are commonly scaled in. This Redis benchmark gives Redis and Valkey that layout. HotKV's lead over them narrows to between 1.0 and 1.7 times on eight commands.&lt;/p&gt;

&lt;h3&gt;
  
  
  HotKV had the highest throughput on 8 of 9 commands
&lt;/h3&gt;

&lt;p&gt;The lead was widest on GET and RPUSH against Redis (1.6 times) and on GET against Valkey (1.7 times). On RPUSH and LPUSH the load generators had room for every server, so those figures are limited by the servers. On INCR, HotKV and Redis were level within 1 percent, and the load generators, not the servers, set the limit for all three.&lt;/p&gt;

&lt;h3&gt;
  
  
  Redis and Valkey were ahead on APPEND
&lt;/h3&gt;

&lt;p&gt;HotKV served 35.0 million APPENDs per second against 41.7 million for Redis and 40.9 million for Valkey. We have not found the reason. APPEND grows the dataset by about 10 GB per second across the cluster, so the run is also a test of memory allocation. A 30-second APPEND run ran the servers out of memory.&lt;/p&gt;

&lt;p&gt;We profiled HotKV on APPEND and saw page faults, TLB shootdowns and lock contention. We have not shown which of them accounts for the gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;p&gt;These are HotKV Ltd's measurements of the versions and configuration above. They are not a claim about any other version, configuration or workload of these products.&lt;/p&gt;

&lt;h3&gt;
  
  
  The test setup
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Load generators near their limit.&lt;/strong&gt; Many figures are lower bounds, as the section on reading the ratios explains. HotKV's APPEND figure is not one of them, because the load generators were at about 30 percent CPU with it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Layouts we chose.&lt;/strong&gt; We ran Redis and Valkey as one single-thread process per core and did not tune either product beyond that. Other layouts or tuning could change their figures. If you think a setting here disadvantages a product, &lt;a href="https://hotkv.com/contact" rel="noopener noreferrer"&gt;tell us&lt;/a&gt; and we will check it and publish the result.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Two runs, one region.&lt;/strong&gt; Each figure is the median of two 15-second runs on one set of machines in one region. We did not measure variation between machines or days.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What was not measured
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Latency.&lt;/strong&gt; We measured throughput only here. A separate &lt;a href="https://hotkv.com/blog/redis-latency-benchmark" rel="noopener noreferrer"&gt;Redis latency benchmark&lt;/a&gt; measures latency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persistence, replication and failover.&lt;/strong&gt; All servers ran with persistence off and no replicas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Other setups.&lt;/strong&gt; Three servers and one workload shape. A larger cluster, other value sizes or other pipeline depths can change the ratios.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Redis, Valkey and Dragonfly are trademarks of their respective owners. They are named only to identify the software we measured, and this implies no sponsorship, endorsement or affiliation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reproduce it
&lt;/h2&gt;

&lt;p&gt;The sweep script, the exact command sequence, the host tuning and every raw result are in the &lt;a href="https://github.com/HotKV-LTD/hotkv/tree/main/results/aws-c8in-12xlarge-cluster-256B-p100-4server-2run-v0.3.0-20261101" rel="noopener noreferrer"&gt;benchmark repository&lt;/a&gt;. The sweep script is &lt;code&gt;harness/cluster_bench_sweep.sh&lt;/code&gt;. A chart of the same figures is on the &lt;a href="https://hotkv.com/performance" rel="noopener noreferrer"&gt;performance page&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;HotKV Cloud runs HotKV clusters for you. &lt;a href="https://console.hotkv.com/register" rel="noopener noreferrer"&gt;Start on HotKV Cloud&lt;/a&gt;, or &lt;a href="mailto:sales@hotkv.com?subject=HotKV%20cluster%20benchmark"&gt;talk to sales&lt;/a&gt; to benchmark a cluster against your own workload.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why run a Redis benchmark as a cluster?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Redis and Valkey run commands on one thread per process, so a single process cannot use a large machine. They are commonly scaled across cores by running many processes as a cluster. A cluster benchmark measures each product in a layout like that, so the comparison does not rest on a single-instance deployment alone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Did HotKV have the highest throughput in cluster mode?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On 8 of 9 commands, yes. HotKV led Redis by 1.0 to 1.6 times and Valkey by 1.1 to 1.7 times, and Dragonfly by 1.85 to 4.09 times. Redis and Valkey were ahead on APPEND. On INCR, HotKV and Redis were level within 1 percent, and the load generators set the limit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why were Redis and Valkey ahead on APPEND?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We do not know yet. APPEND grows the dataset by about 10 GB per second across the cluster, so the run also tests memory allocation. A profile of HotKV showed page faults, TLB shootdowns and lock contention, but we have not shown which of them accounts for the gap.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the pipeline-prefetch setting?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It makes HotKV look ahead in a client's pipeline and ask the CPU for the memory the next commands will read, so those reads overlap. It changes no reply. It is off by default, and HotKV ran with it on in this benchmark.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I reproduce this Redis benchmark?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. The sweep script, the exact command sequence, the host tuning and every raw result are in the benchmark repository, and the same figures are charted on the performance page. You need three servers, one or more load generators and the four products installed by the harness.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does this replace the single-instance results?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. The two answer different questions. A single-instance run shows what one server process does with a whole machine. A cluster run shows what three machines do when each product is laid out as a cluster. Both are on the performance page.&lt;/p&gt;

</description>
      <category>redis</category>
      <category>aws</category>
      <category>performance</category>
      <category>database</category>
    </item>
    <item>
      <title>Redis latency benchmark: HotKV vs Valkey and Dragonfly</title>
      <dc:creator>HotKV Ltd</dc:creator>
      <pubDate>Thu, 05 Nov 2026 07:00:00 +0000</pubDate>
      <link>https://dev.to/hotkv/redis-latency-benchmark-hotkv-vs-valkey-and-dragonfly-584o</link>
      <guid>https://dev.to/hotkv/redis-latency-benchmark-hotkv-vs-valkey-and-dragonfly-584o</guid>
      <description>&lt;p&gt;This Redis latency benchmark measures how long HotKV, Redis, Valkey and Dragonfly take to answer at a fixed request rate. Our earlier benchmarks measured throughput, and a reader rightly pointed out that throughput is not everything. So we held the load constant, raised it step by step, and recorded the median (p50) and the 99th percentile (p99) at each step. We also measured pub/sub delivery time.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;In short.&lt;/strong&gt; In this Redis latency benchmark on AWS, HotKV and Dragonfly both held 1.6 million GETs per second, Redis with 8 I/O threads held about 0.8 million, Valkey with 8 I/O threads about 0.4 million, and single-thread Redis and Valkey about 0.2 million. From 200,000 to 1.6 million requests per second HotKV's p99 stayed between 0.59 and 0.76 ms, against 0.71 to 1.48 ms for Dragonfly. At light load the multi-threaded products tied on p99, and pub/sub delivery was a tie.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why we ran a Redis latency benchmark at a fixed rate
&lt;/h2&gt;

&lt;p&gt;A throughput test pushes a server as hard as it will go and reports how much it served. That says little about how long one request waits. A latency test fixes how many requests per second the clients send, and measures the time each takes. The server is then at the same load as every other product, so the times can be compared.&lt;/p&gt;

&lt;p&gt;This kind of test has a catch. &lt;code&gt;memtier_benchmark&lt;/code&gt; is a closed-loop tool, so a client waits for a reply before it sends the next request. If a server cannot keep up, the client simply sends fewer requests, and the latency of the ones it did send looks better than it should. We therefore count a step as sustained only when the achieved rate is at least 97 percent of the rate we asked for. Steps that fail the test are marked "not sustained" in the tables and their latency is not shown.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we tested
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fhotkv.com%2Fblog%2Ffigures%2Flatency-benchmark.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fhotkv.com%2Fblog%2Ffigures%2Flatency-benchmark.svg" alt="The latency benchmark setup. One load generator drives one server. Each product ran alone on the server, one at a time." width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Machines
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Servers and load generator.&lt;/strong&gt; &lt;code&gt;c8a.12xlarge&lt;/code&gt; instances (AMD EPYC 9R45, 48 cores, no SMT, 96 GiB, 22.5 Gbit/s network) in one AWS cluster placement group in eu-south-2a, running Ubuntu 24.04. One instance ran the load generator and one ran the server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One product at a time.&lt;/strong&gt; Each product ran alone on the server, so nothing overlapped and nothing shared the network. Every server process was pinned to CPUs 0 to 39, with persistence off and protected mode off.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Products
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HotKV 0.3.0&lt;/strong&gt; with 40 threads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dragonfly 2.0.2&lt;/strong&gt; with 40 proactor threads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redis 8.10.3&lt;/strong&gt; and &lt;strong&gt;Valkey 9.1.3&lt;/strong&gt;, each run twice, once in the default single-thread setup and once with &lt;code&gt;--io-threads 8&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The launch line and the live &lt;code&gt;CONFIG GET&lt;/code&gt; output of every run are saved with its results.&lt;/p&gt;

&lt;h3&gt;
  
  
  Workload and procedure
&lt;/h3&gt;

&lt;p&gt;The data set was 1,000,000 keys with 256-byte values, and pipeline depth was 1, so each request waits for its own reply. The load was GET only, and a mix of 1 write to 10 reads. Each step ran for 20 seconds, twice, and we report the mean of the two runs. &lt;code&gt;memtier_benchmark&lt;/code&gt; used a per-connection rate limit and recorded an HDR histogram. We ran two connection counts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;816 connections&lt;/strong&gt; (24 threads of 34 connections), for rates from 20,000 to 2.4 million requests per second.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;48 connections&lt;/strong&gt; (4 threads of 12 connections), for rates up to 300,000 requests per second. Above that, 48 connections cannot reach the rate, because each connection can only send as fast as it gets replies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;The GET tables come first, one for each connection count, followed by pub/sub.&lt;/p&gt;

&lt;h3&gt;
  
  
  At 816 connections
&lt;/h3&gt;

&lt;p&gt;Each cell is p50 / p99 in milliseconds, for GET. "NS" means not sustained, and the rate it did reach is in brackets. A dash means the sweep for that product had already stopped.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Requests/s&lt;/th&gt;
&lt;th&gt;HotKV&lt;/th&gt;
&lt;th&gt;Dragonfly&lt;/th&gt;
&lt;th&gt;Redis 1 thread&lt;/th&gt;
&lt;th&gt;Redis 8 I/O threads&lt;/th&gt;
&lt;th&gt;Valkey 1 thread&lt;/th&gt;
&lt;th&gt;Valkey 8 I/O threads&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;19,584&lt;/td&gt;
&lt;td&gt;0.38 / 1.81&lt;/td&gt;
&lt;td&gt;0.48 / 1.90&lt;/td&gt;
&lt;td&gt;1.63 / 5.29&lt;/td&gt;
&lt;td&gt;0.68 / 2.07&lt;/td&gt;
&lt;td&gt;1.59 / 5.13&lt;/td&gt;
&lt;td&gt;0.76 / 2.63&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99,552&lt;/td&gt;
&lt;td&gt;0.24 / 0.76&lt;/td&gt;
&lt;td&gt;0.27 / 1.76&lt;/td&gt;
&lt;td&gt;2.60 / 5.12&lt;/td&gt;
&lt;td&gt;0.40 / 0.98&lt;/td&gt;
&lt;td&gt;2.65 / 5.13&lt;/td&gt;
&lt;td&gt;1.71 / 3.19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;199,920&lt;/td&gt;
&lt;td&gt;0.25 / 0.59&lt;/td&gt;
&lt;td&gt;0.25 / 1.34&lt;/td&gt;
&lt;td&gt;2.91 / 5.60&lt;/td&gt;
&lt;td&gt;0.55 / 1.11&lt;/td&gt;
&lt;td&gt;3.02 / 5.81&lt;/td&gt;
&lt;td&gt;1.11 / 2.15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;399,840&lt;/td&gt;
&lt;td&gt;0.27 / 0.63&lt;/td&gt;
&lt;td&gt;0.27 / 1.48&lt;/td&gt;
&lt;td&gt;NS (258k)&lt;/td&gt;
&lt;td&gt;0.62 / 1.23&lt;/td&gt;
&lt;td&gt;NS (259k)&lt;/td&gt;
&lt;td&gt;1.24 / 1.49&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;799,680&lt;/td&gt;
&lt;td&gt;0.28 / 0.75&lt;/td&gt;
&lt;td&gt;0.28 / 1.26&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;0.68 / 1.18&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;NS (670k)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,199,520&lt;/td&gt;
&lt;td&gt;0.28 / 0.67&lt;/td&gt;
&lt;td&gt;0.28 / 1.05&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;NS (1,078k)&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,599,360&lt;/td&gt;
&lt;td&gt;0.28 / 0.64&lt;/td&gt;
&lt;td&gt;0.28 / 0.71&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2,399,856&lt;/td&gt;
&lt;td&gt;NS (2,284k)&lt;/td&gt;
&lt;td&gt;NS (2,281k)&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The mixed workload gave the same picture. HotKV's p99 was 0.54 to 0.75 ms from 200,000 to 1.6 million requests per second, and the points each product could sustain were the same as for GET. All of it is in the results folder.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to read the single-thread rows
&lt;/h3&gt;

&lt;p&gt;The 1.6 to 3 ms medians of single-thread Redis and Valkey at 816 connections are not their steady-state latency. With a rate limit, &lt;code&gt;memtier_benchmark&lt;/code&gt; makes all 816 connections fire at the same moment. A single-thread server has to work through that burst of 816 requests one after another, so the median of a request includes its place in the queue. We ran the 48-connection test below to remove this effect.&lt;/p&gt;

&lt;h3&gt;
  
  
  At 48 connections
&lt;/h3&gt;

&lt;p&gt;The cells have the same meaning as above, for GET only.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Requests/s&lt;/th&gt;
&lt;th&gt;HotKV&lt;/th&gt;
&lt;th&gt;Dragonfly&lt;/th&gt;
&lt;th&gt;Redis 1 thread&lt;/th&gt;
&lt;th&gt;Redis 8 I/O threads&lt;/th&gt;
&lt;th&gt;Valkey 1 thread&lt;/th&gt;
&lt;th&gt;Valkey 8 I/O threads&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;9,984&lt;/td&gt;
&lt;td&gt;0.14 / 0.54&lt;/td&gt;
&lt;td&gt;0.14 / 0.37&lt;/td&gt;
&lt;td&gt;0.21 / 0.89&lt;/td&gt;
&lt;td&gt;0.17 / 0.92&lt;/td&gt;
&lt;td&gt;0.21 / 0.91&lt;/td&gt;
&lt;td&gt;0.20 / 0.81&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;49,968&lt;/td&gt;
&lt;td&gt;0.10 / 0.28&lt;/td&gt;
&lt;td&gt;0.11 / 0.28&lt;/td&gt;
&lt;td&gt;0.21 / 0.41&lt;/td&gt;
&lt;td&gt;0.13 / 0.28&lt;/td&gt;
&lt;td&gt;0.21 / 0.43&lt;/td&gt;
&lt;td&gt;0.21 / 0.44&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99,984&lt;/td&gt;
&lt;td&gt;0.09 / 0.28&lt;/td&gt;
&lt;td&gt;0.10 / 0.28&lt;/td&gt;
&lt;td&gt;0.20 / 0.40&lt;/td&gt;
&lt;td&gt;0.13 / 0.28&lt;/td&gt;
&lt;td&gt;0.20 / 0.38&lt;/td&gt;
&lt;td&gt;0.19 / 0.35&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;199,968&lt;/td&gt;
&lt;td&gt;0.08 / 0.27&lt;/td&gt;
&lt;td&gt;0.08 / 0.27&lt;/td&gt;
&lt;td&gt;0.20 / 0.35&lt;/td&gt;
&lt;td&gt;0.10 / 0.27&lt;/td&gt;
&lt;td&gt;0.21 / 0.36&lt;/td&gt;
&lt;td&gt;0.11 / 0.28&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;300,000&lt;/td&gt;
&lt;td&gt;0.08 / 0.27&lt;/td&gt;
&lt;td&gt;0.08 / 0.27&lt;/td&gt;
&lt;td&gt;NS (231k)&lt;/td&gt;
&lt;td&gt;0.09 / 0.26&lt;/td&gt;
&lt;td&gt;NS (233k)&lt;/td&gt;
&lt;td&gt;0.09 / 0.26&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Pub/sub delivery time
&lt;/h2&gt;

&lt;p&gt;We measured the time from a publish to its delivery to a subscriber, with 64 publishers, 100 subscribers and a 128-byte payload, using &lt;code&gt;pubsub-sub-bench&lt;/code&gt;. Each message went to one subscriber. Cells are p50 / p99 in milliseconds.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Deliveries/s&lt;/th&gt;
&lt;th&gt;HotKV&lt;/th&gt;
&lt;th&gt;Dragonfly&lt;/th&gt;
&lt;th&gt;Redis 1 thread&lt;/th&gt;
&lt;th&gt;Redis 8 I/O threads&lt;/th&gt;
&lt;th&gt;Valkey 1 thread&lt;/th&gt;
&lt;th&gt;Valkey 8 I/O threads&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;about 21,000&lt;/td&gt;
&lt;td&gt;0.10 / 0.71&lt;/td&gt;
&lt;td&gt;0.10 / 0.65&lt;/td&gt;
&lt;td&gt;0.11 / 0.74&lt;/td&gt;
&lt;td&gt;0.11 / 0.62&lt;/td&gt;
&lt;td&gt;0.11 / 0.76&lt;/td&gt;
&lt;td&gt;0.12 / 0.78&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;about 107,000&lt;/td&gt;
&lt;td&gt;0.10 / 1.02&lt;/td&gt;
&lt;td&gt;0.12 / 0.92&lt;/td&gt;
&lt;td&gt;0.10 / 0.80&lt;/td&gt;
&lt;td&gt;0.11 / 0.63&lt;/td&gt;
&lt;td&gt;0.10 / 0.82&lt;/td&gt;
&lt;td&gt;0.10 / 0.86&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;about 215,000&lt;/td&gt;
&lt;td&gt;0.11 / 1.20&lt;/td&gt;
&lt;td&gt;0.13 / 1.13&lt;/td&gt;
&lt;td&gt;0.51 / 1.03&lt;/td&gt;
&lt;td&gt;0.20 / 0.73&lt;/td&gt;
&lt;td&gt;0.57 / 1.07&lt;/td&gt;
&lt;td&gt;0.12 / 1.22&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All products delivered in the same range. At the highest load the single-thread products had a higher median, 0.51 and 0.57 ms against 0.11 ms for HotKV.&lt;/p&gt;

&lt;p&gt;We also had to patch &lt;code&gt;pubsub-sub-bench&lt;/code&gt;. It compared a publish time in milliseconds with a receive time in microseconds. The patch is in the results folder.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the results show
&lt;/h2&gt;

&lt;p&gt;The tables show a lead for HotKV and Dragonfly at high load, a tie at light load, and a ceiling for single-thread Redis and Valkey.&lt;/p&gt;

&lt;h3&gt;
  
  
  HotKV and Dragonfly kept a low tail to 1.6 million requests per second
&lt;/h3&gt;

&lt;p&gt;Both sustained 1.6 million GETs per second at 816 connections, with a median of 0.28 ms. HotKV's p99 was between 0.59 and 0.76 ms from 200,000 requests per second up. Dragonfly's was between 0.71 and 1.48 ms, and the two were close at 1.6 million (0.64 against 0.71 ms). Redis and Valkey with I/O threads stopped sustaining the rate at lower loads, and single-thread Redis and Valkey stopped at about 260,000.&lt;/p&gt;

&lt;h3&gt;
  
  
  At light load the multi-threaded products tie
&lt;/h3&gt;

&lt;p&gt;At 48 connections, up to 300,000 requests per second, HotKV, Dragonfly and Redis with 8 I/O threads all had a p99 of about 0.27 ms. HotKV had the lowest median, 0.08 to 0.09 ms from 100,000 requests per second, with Dragonfly at 0.08 to 0.10 ms. A difference of 0.01 ms is within what other parts of the setup can cause, so we do not claim it as a win.&lt;/p&gt;

&lt;h3&gt;
  
  
  Single-thread Redis and Valkey ran out at about 230,000 a second
&lt;/h3&gt;

&lt;p&gt;At 48 connections they had a median of about 0.2 ms and a p99 of 0.35 to 0.43 ms, and they did not sustain 300,000 requests per second (about 231,000 and 233,000). That is the ceiling of one thread on this hardware and workload. It is why Redis and Valkey are usually run as many processes or as a cluster, as in our &lt;a href="https://hotkv.com/blog/redis-benchmark-cluster" rel="noopener noreferrer"&gt;cluster benchmark&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;p&gt;These are HotKV Ltd's measurements of the versions and configuration above. They are not a claim about any other version, configuration or workload of these products.&lt;/p&gt;

&lt;h3&gt;
  
  
  The test setup
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One server, one load generator.&lt;/strong&gt; Two repeats per step, on one set of machines on one date. We did not measure variation between machines or days.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Layouts we chose.&lt;/strong&gt; Redis and Valkey ran in their default single-thread setup and with &lt;code&gt;--io-threads 8&lt;/code&gt;, and we did not tune either beyond that. Other settings could change their figures. If you think a setting here disadvantages a product, &lt;a href="https://hotkv.com/contact" rel="noopener noreferrer"&gt;tell us&lt;/a&gt; and we will check it and publish the result.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The tool's burst effect.&lt;/strong&gt; At 816 connections, the medians of single-thread products are inflated by the way &lt;code&gt;memtier_benchmark&lt;/code&gt; rate limiting works, as explained above.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What was not measured
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data.&lt;/strong&gt; Larger or skewed values, memory per key, and persistence. Persistence was off for every server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modes.&lt;/strong&gt; Cluster mode, sharded pub/sub, TLS, replication and failover.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pub/sub fan-out.&lt;/strong&gt; One message to many subscribers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Redis, Valkey and Dragonfly are trademarks of their respective owners. They are named only to identify the software we measured, and this implies no sponsorship, endorsement or affiliation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reproduce it
&lt;/h2&gt;

&lt;p&gt;The sweep scripts, the launch line and live configuration of every server, the &lt;code&gt;pubsub-sub-bench&lt;/code&gt; patch and every raw result are in the &lt;a href="https://github.com/HotKV-LTD/hotkv/tree/main/results/aws-c8a-latency-256B-p1-2server-2run-v0.3.0-20261102" rel="noopener noreferrer"&gt;benchmark repository&lt;/a&gt;. The latency script is &lt;code&gt;harness/lat_sweep.sh&lt;/code&gt;, and the pub/sub script is &lt;code&gt;harness/ps_sweep.sh&lt;/code&gt;. The &lt;code&gt;raw&lt;/code&gt; folder holds one archive per test with the &lt;code&gt;memtier_benchmark&lt;/code&gt; JSON, the HDR histograms and the CPU use of the server for every run.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;HotKV Cloud runs HotKV for you. &lt;a href="https://console.hotkv.com/register" rel="noopener noreferrer"&gt;Start on HotKV Cloud&lt;/a&gt;, or &lt;a href="mailto:sales@hotkv.com?subject=HotKV%20latency%20benchmark"&gt;talk to sales&lt;/a&gt; to benchmark HotKV against your own workload.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is HotKV faster than Redis in latency?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Under load, at the rates we tested, yes. At 816 connections and 200,000 requests per second HotKV had a p99 of 0.59 ms, Redis with 8 I/O threads 1.11 ms and single-thread Redis 5.60 ms. At light load with 48 connections the multi-threaded products tied on p99, at about 0.27 ms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why did you hold the request rate fixed?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At a fixed rate every product carries the same load, so the latencies can be compared. A throughput test shows how much a server serves at its limit, which says little about how long one request waits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does "not sustained" mean?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The product achieved less than 97 percent of the request rate we asked for. &lt;code&gt;memtier_benchmark&lt;/code&gt; is a closed-loop tool, so an overloaded server makes the clients send less and the latency of the remaining requests looks better than it is. We show no latency for those steps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How did pub/sub delivery time compare?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At the three loads we tested, all products delivered in the same range, with a median of about 0.1 ms at the two lower loads. The table above has every figure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I reproduce this Redis latency benchmark?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. The scripts, the configurations and every raw result are in the benchmark repository. You need two servers on the same network, a load generator, and the four products.&lt;/p&gt;

</description>
      <category>redis</category>
      <category>aws</category>
      <category>performance</category>
      <category>database</category>
    </item>
    <item>
      <title>Vector search: HotKV vs Redis 8 vector sets, from 1 to 100 clients</title>
      <dc:creator>HotKV Ltd</dc:creator>
      <pubDate>Thu, 05 Nov 2026 01:39:46 +0000</pubDate>
      <link>https://dev.to/hotkv/vector-search-hotkv-vs-redis-8-vector-sets-from-1-to-100-clients-2d4o</link>
      <guid>https://dev.to/hotkv/vector-search-hotkv-vs-redis-8-vector-sets-from-1-to-100-clients-2d4o</guid>
      <description>&lt;p&gt;Vector search sits underneath many AI features: retrieval for RAG, semantic caching, agent memory. Redis 8 ships vector sets, a beta data type, built into the server, so it is the obvious comparison. We loaded the same OpenAI embeddings into HotKV and into Redis 8.10.2, ran the same 1,000 queries against each with 1 to 100 concurrent client connections, and measured how accurate the answers were, how many queries per second each engine served, and how long each query took.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;In short.&lt;/strong&gt; On 999,000 vectors, at a minimum recall of 95%, HotKV served 1.4 times the queries per second of Redis with one client and 7.9 times with 100 clients (51,146 against 6,510). At 99% recall the ratios were 1.8 and 5.4. HotKV's median latency was lower at every client count. Redis's throughput levelled off by 32 clients, while HotKV's kept growing to 100. HotKV loaded the vectors in 188 s against 935 s for Redis, which was pinned to four vCPUs for its load, and its recall was higher at every search depth. This is one dataset on one machine, the HotKV build is an unreleased development build, and we did not measure Redis's Query Engine or its 8-bit mode, so read it as a measurement, not a ranking.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What we tested
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Data
&lt;/h3&gt;

&lt;p&gt;The first 999,000 rows of &lt;a href="https://huggingface.co/datasets/KShivendu/dbpedia-entities-openai-1M" rel="noopener noreferrer"&gt;dbpedia-entities-openai-1M&lt;/a&gt; by Kumar Shivendu and Nirant Kasliwal (MIT license), and, for a smaller index, the first 100,000 rows. The rows are DBpedia entities embedded with OpenAI &lt;code&gt;text-embedding-ada-002&lt;/code&gt;, 1,536 dimensions. The last 1,000 rows are the queries, so no row appears in both sets. The answer key is the exact top 10 nearest neighbours of every query, computed by brute force in 64-bit floating point independently of either engine, so both are graded against the same ground truth.&lt;/p&gt;

&lt;h3&gt;
  
  
  Engines and settings
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Engines.&lt;/strong&gt; HotKV commit &lt;code&gt;c8dafd37&lt;/code&gt; (&lt;code&gt;VSIM.CREATEINDEX&lt;/code&gt;, &lt;code&gt;VSIM.SET&lt;/code&gt;, &lt;code&gt;VSIM.SEARCH&lt;/code&gt;), an unreleased development build compiled with default release flags, not &lt;code&gt;-march=native&lt;/code&gt;. Redis 8.10.2 built from its release tag with a stock &lt;code&gt;make&lt;/code&gt; (&lt;code&gt;VADD&lt;/code&gt;, &lt;code&gt;VSIM&lt;/code&gt;). Both build &lt;a href="https://arxiv.org/abs/1603.09320" rel="noopener noreferrer"&gt;HNSW graphs&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Index settings.&lt;/strong&gt; Cosine similarity, HNSW with &lt;code&gt;M=16&lt;/code&gt; and &lt;code&gt;ef_construction=200&lt;/code&gt; on both, set explicitly. They are also each engine's own defaults.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Precision.&lt;/strong&gt; Full-precision float32 vectors on both. Redis defaults to &lt;a href="https://redis.io/docs/latest/commands/vadd/" rel="noopener noreferrer"&gt;8-bit quantization&lt;/a&gt;, so it ran with &lt;code&gt;NOQUANT&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Machine.&lt;/strong&gt; One Azure Standard_D160alds_v7 (AMD EPYC 9V45, 160 vCPUs). Both servers were pinned to the same 128 vCPUs, the load generators to the other 32, all over loopback. HotKV ran 128 threads and Redis its default I/O threads. We tried 1, 4, 8 and 16 and the setting made no consistent difference.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Load generator.&lt;/strong&gt; One process per client connection, each keeping one request outstanding, with the requests built before the timed part. The busiest load-generator process used 8% of one CPU in any run, so the client never set the limit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Procedure
&lt;/h3&gt;

&lt;p&gt;For search depths (&lt;code&gt;ef&lt;/code&gt;) of 40, 80, 150 and 300, and 500 on the larger index, we ran the 1,000 queries repeatedly with 1, 2, 4, 8, 16, 32, 50 and 100 clients: one second of warm-up, then four seconds counted, three times each, with the order of the two engines alternating. We report the median. Recall was measured separately, over one connection. HotKV was loaded over 32 connections in every run. The Redis indexes were built once, over 32 connections with &lt;code&gt;VADD ... CAS&lt;/code&gt;, saved, and loaded for the measurements. The scripts and every trial are in the &lt;a href="https://github.com/HotKV-LTD/hotkv/tree/main/vector-search" rel="noopener noreferrer"&gt;benchmark repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Matched recall targets
&lt;/h3&gt;

&lt;p&gt;The two engines do not reach the same recall at the same &lt;code&gt;ef&lt;/code&gt;, so we compare throughput at shared minimum recall targets: for each target, the fastest measured search depth that reaches it. The depths and recalls reached are in the tables, because they differ a little. This uses measured depths, not interpolation. Queries per second on 999,000 vectors:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Recall@10 target&lt;/th&gt;
&lt;th&gt;Clients&lt;/th&gt;
&lt;th&gt;HotKV&lt;/th&gt;
&lt;th&gt;Redis 8.10.2&lt;/th&gt;
&lt;th&gt;HotKV vs Redis&lt;/th&gt;
&lt;th&gt;Median latency&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;95% or better&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1,328 (ef 80, 0.970)&lt;/td&gt;
&lt;td&gt;946 (ef 80, 0.962)&lt;/td&gt;
&lt;td&gt;1.40x&lt;/td&gt;
&lt;td&gt;0.77 / 1.07 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;95% or better&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;10,342&lt;/td&gt;
&lt;td&gt;5,531&lt;/td&gt;
&lt;td&gt;1.87x&lt;/td&gt;
&lt;td&gt;0.79 / 1.43 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;95% or better&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;18,500&lt;/td&gt;
&lt;td&gt;7,265&lt;/td&gt;
&lt;td&gt;2.55x&lt;/td&gt;
&lt;td&gt;0.87 / 2.15 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;95% or better&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;37,508&lt;/td&gt;
&lt;td&gt;6,825&lt;/td&gt;
&lt;td&gt;5.50x&lt;/td&gt;
&lt;td&gt;1.33 / 7.17 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;95% or better&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;51,146&lt;/td&gt;
&lt;td&gt;6,510&lt;/td&gt;
&lt;td&gt;7.86x&lt;/td&gt;
&lt;td&gt;1.91 / 13.49 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99% or better&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;507 (ef 300, 0.993)&lt;/td&gt;
&lt;td&gt;287 (ef 500, 0.994)&lt;/td&gt;
&lt;td&gt;1.77x&lt;/td&gt;
&lt;td&gt;1.99 / 3.31 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99% or better&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;6,961&lt;/td&gt;
&lt;td&gt;2,322&lt;/td&gt;
&lt;td&gt;3.00x&lt;/td&gt;
&lt;td&gt;2.30 / 6.70 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99% or better&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;12,393&lt;/td&gt;
&lt;td&gt;2,483&lt;/td&gt;
&lt;td&gt;4.99x&lt;/td&gt;
&lt;td&gt;4.02 / 18.91 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99% or better&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;13,843&lt;/td&gt;
&lt;td&gt;2,583&lt;/td&gt;
&lt;td&gt;5.36x&lt;/td&gt;
&lt;td&gt;7.11 / 37.65 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Median latency is HotKV / Redis. The same pattern held for a 90% target: 90,003 against 7,973 queries per second at 100 clients (11.3 times), both at &lt;code&gt;ef&lt;/code&gt; 40.&lt;/p&gt;

&lt;h3&gt;
  
  
  Every search depth
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ef&lt;/th&gt;
&lt;th&gt;HotKV recall&lt;/th&gt;
&lt;th&gt;Redis recall&lt;/th&gt;
&lt;th&gt;HotKV, 1 client&lt;/th&gt;
&lt;th&gt;Redis, 1 client&lt;/th&gt;
&lt;th&gt;HotKV, 50 clients&lt;/th&gt;
&lt;th&gt;Redis, 50 clients&lt;/th&gt;
&lt;th&gt;HotKV, 100 clients&lt;/th&gt;
&lt;th&gt;Redis, 100 clients&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;td&gt;0.940&lt;/td&gt;
&lt;td&gt;0.923&lt;/td&gt;
&lt;td&gt;2,108&lt;/td&gt;
&lt;td&gt;1,259&lt;/td&gt;
&lt;td&gt;63,897&lt;/td&gt;
&lt;td&gt;8,061&lt;/td&gt;
&lt;td&gt;90,003&lt;/td&gt;
&lt;td&gt;7,973&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;80&lt;/td&gt;
&lt;td&gt;0.970&lt;/td&gt;
&lt;td&gt;0.962&lt;/td&gt;
&lt;td&gt;1,328&lt;/td&gt;
&lt;td&gt;946&lt;/td&gt;
&lt;td&gt;37,508&lt;/td&gt;
&lt;td&gt;6,825&lt;/td&gt;
&lt;td&gt;51,146&lt;/td&gt;
&lt;td&gt;6,510&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;150&lt;/td&gt;
&lt;td&gt;0.987&lt;/td&gt;
&lt;td&gt;0.980&lt;/td&gt;
&lt;td&gt;875&lt;/td&gt;
&lt;td&gt;636&lt;/td&gt;
&lt;td&gt;21,912&lt;/td&gt;
&lt;td&gt;5,241&lt;/td&gt;
&lt;td&gt;26,122&lt;/td&gt;
&lt;td&gt;4,942&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;300&lt;/td&gt;
&lt;td&gt;0.993&lt;/td&gt;
&lt;td&gt;0.990&lt;/td&gt;
&lt;td&gt;507&lt;/td&gt;
&lt;td&gt;396&lt;/td&gt;
&lt;td&gt;12,393&lt;/td&gt;
&lt;td&gt;3,454&lt;/td&gt;
&lt;td&gt;13,843&lt;/td&gt;
&lt;td&gt;3,402&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;500&lt;/td&gt;
&lt;td&gt;0.997&lt;/td&gt;
&lt;td&gt;0.994&lt;/td&gt;
&lt;td&gt;338&lt;/td&gt;
&lt;td&gt;287&lt;/td&gt;
&lt;td&gt;7,688&lt;/td&gt;
&lt;td&gt;2,483&lt;/td&gt;
&lt;td&gt;8,843&lt;/td&gt;
&lt;td&gt;2,583&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Queries per second on 999,000 vectors. On 100,000 vectors the pattern is the same. At 95% recall HotKV served 1.5 times Redis's queries per second with one client (1,816 against 1,214) and 8.9 times with 100 (63,247 against 7,119).&lt;/p&gt;

&lt;h3&gt;
  
  
  How much of this is noise
&lt;/h3&gt;

&lt;p&gt;Each cell is the median of three trials. Half of the cells had a spread between their lowest and highest trial of 1.3% of the median or less, nine in ten 7% or less, and the widest was 26% (Redis, 100,000 vectors, &lt;code&gt;ef&lt;/code&gt; 300, 50 clients). The report lists every trial.&lt;/p&gt;

&lt;p&gt;Recall was measured once per index build. Three independent builds of each engine on 100,000 vectors differed by up to 0.013 at the same depth, so HotKV's higher recall is clear up to &lt;code&gt;ef&lt;/code&gt; 300 and within build-to-build variation at &lt;code&gt;ef&lt;/code&gt; 500 on the smaller index.&lt;/p&gt;

&lt;h2&gt;
  
  
  Loading and memory
&lt;/h2&gt;

&lt;p&gt;Loaded over 32 connections each, HotKV took 188 seconds for the 999,000 vectors (5,325 per second) and Redis 935 seconds (1,069 per second), including the time the load generator spent formatting each vector. On 100,000 vectors it was 15 seconds against 57. Redis loaded faster with &lt;code&gt;CAS&lt;/code&gt; than without in a check on 20,000 vectors (2,279 against 1,488 vectors per second), so we used it. The Redis load ran in an earlier step with Redis pinned to four vCPUs while other checks ran on the machine; HotKV loaded alone on 128 vCPUs. Treat the Redis loading time as a lower bound on its speed, not a like-for-like comparison.&lt;/p&gt;

&lt;p&gt;After loading 999,000 vectors the HotKV process held 6.77 GB and the Redis process 7.01 GB.&lt;/p&gt;

&lt;h2&gt;
  
  
  What limits Redis 8.10.2 here
&lt;/h2&gt;

&lt;p&gt;Redis vector sets run each search on its own thread, but the HNSW code has a fixed number of thread slots (32, set when Redis is compiled), and vectors are added on the main thread. In our runs, from 32 clients up, Redis kept between 6 and 30 of the machine's vCPUs busy and its throughput had levelled off. HotKV kept about 92 vCPUs busy at 100 clients on &lt;code&gt;ef&lt;/code&gt; 80 and its throughput was still growing. That is how each engine behaves on this machine, not something the benchmark configured.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;p&gt;These are HotKV Ltd's measurements of the versions and configuration above, not a claim about every Redis deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  The test setup
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A development build.&lt;/strong&gt; Commit &lt;code&gt;c8dafd37&lt;/code&gt; is a development build, not a release.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One dataset, one machine.&lt;/strong&gt; 1,536-dimension OpenAI embeddings, top 10 only, float32, cosine. Other dimensions, data or hardware can give different ratios.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The client shares the machine.&lt;/strong&gt; The load generators ran on separate vCPUs but shared the memory system and the last-level cache with the servers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persistence off.&lt;/strong&gt; Neither server wrote snapshots or an append-only file.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What was not measured
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Redis's 8-bit mode.&lt;/strong&gt; Redis stores 8-bit quantized vectors by default, which uses less memory. We compared float32 against float32.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Redis Query Engine.&lt;/strong&gt; Redis also offers vector search through &lt;code&gt;FT.CREATE&lt;/code&gt; and &lt;code&gt;FT.SEARCH&lt;/code&gt;. We tested vector sets only, so the results say nothing about the Query Engine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redis loading and reload.&lt;/strong&gt; The Redis indexes were built in an earlier run with Redis pinned to four vCPUs, saved, and reloaded for the measurements, so the Redis load times are a lower bound and are not comparable like for like with HotKV's. Searching a reloaded index was about 10 percent slower than a freshly built one in a check on 20,000 vectors, so Redis's query figures may be low by about that much.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;Vector search is built into the same server as HotKV's prompt cache, and the same vector index backs its semantic cache and agent memory. Vector search is included on every HotKV Cloud plan. The prompt cache, semantic cache and agent memory come with the Performance plan and above. &lt;a href="https://console.hotkv.com/register" rel="noopener noreferrer"&gt;Start on HotKV Cloud&lt;/a&gt;, or &lt;a href="mailto:sales@hotkv.com?subject=HotKV%20vector%20search"&gt;talk to sales&lt;/a&gt; to benchmark it against your own embeddings.&lt;/p&gt;

</description>
      <category>redis</category>
      <category>vectordatabase</category>
      <category>ai</category>
      <category>performance</category>
    </item>
    <item>
      <title>HotKV cut Claude token use by 70% in our Banking77 benchmark</title>
      <dc:creator>HotKV Ltd</dc:creator>
      <pubDate>Mon, 19 Oct 2026 02:15:41 +0000</pubDate>
      <link>https://dev.to/hotkv-ltd/hotkv-cut-claude-token-use-by-70-in-our-banking77-benchmark-2j1f</link>
      <guid>https://dev.to/hotkv-ltd/hotkv-cut-claude-token-use-by-70-in-our-banking77-benchmark-2j1f</guid>
      <description>&lt;p&gt;A semantic cache promises to cut LLM spend by answering repeated and similar questions from memory instead of calling the model. We measured that end to end: the same 3,000 customer support requests, sent to each of four Claude models twice, once straight to the model and once with HotKV in front, with Anthropic's own prompt caching left on in both runs. Here is exactly what we ran and what it found, including where it falls short.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;In short.&lt;/strong&gt; HotKV cut model calls, input plus output tokens and API cost by about 70% on each of the four models. Most of that comes from questions that repeat exactly. The semantic layer adds roughly 12 points on top. At the default 0.81 similarity threshold, cached answers were judged to fit the exact question 5.8 to 10.7 percentage points less often than fresh answers. On the one model we swept (Sonnet 5.5), a threshold of 0.88 or higher showed no such gap.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Updated 12 October 2026: this article now reports our larger run on four current Claude models. It replaces an earlier 1,500-request run on GPT and Claude Sonnet 5 that measured about 60% fewer tokens, which we no longer present.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What we tested
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The workload
&lt;/h3&gt;

&lt;p&gt;We replayed customer support questions from the test split of &lt;a href="https://github.com/PolyAI-LDN/task-specific-datasets" rel="noopener noreferrer"&gt;Banking77&lt;/a&gt; (PolyAI, CC BY 4.0), a public dataset of short banking questions labelled with 77 intents. It was introduced in &lt;a href="https://arxiv.org/abs/2003.04807" rel="noopener noreferrer"&gt;Casanueva et al., 2020&lt;/a&gt;. The 3,000 requests were drawn with a fixed seed. Intent popularity follows a Zipf distribution with exponent 1.0, a synthetic skew in which a few intents come up far more often than the rest, and the question within an intent is picked uniformly, with repeats. All 77 intents appear, and 1,264 of the 3,000 requests are distinct questions (counted by replaying the seeded request generator). The bank and its support policy are fictional. We wrote a policy of about 2,200 tokens, sent as the system prompt on every request, that asks for two to four short sentences.&lt;/p&gt;

&lt;h3&gt;
  
  
  Models and settings
&lt;/h3&gt;

&lt;p&gt;We ran &lt;code&gt;claude-fable-5-1&lt;/code&gt;, &lt;code&gt;claude-opus-5-5&lt;/code&gt;, &lt;code&gt;claude-sonnet-5-5&lt;/code&gt; and &lt;code&gt;claude-haiku-5-5&lt;/code&gt;. Fable 5.1 and Opus 5.5 ran at their lowest effort setting, because their thinking cannot be switched off. Sonnet 5.5 ran with up-front thinking off, its lowest setting, and Haiku 5.5 with thinking disabled. Maximum output was 2,000 tokens for Fable and Opus and 400 for Sonnet and Haiku, and every answer finished normally rather than being cut off. Eight requests ran at a time in both modes, calls were not streamed, and each condition ran once.&lt;/p&gt;

&lt;h3&gt;
  
  
  The two runs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Baseline:&lt;/strong&gt; every request goes straight to the model, with &lt;a href="https://platform.claude.com/docs/en/build-with-claude/prompt-caching" rel="noopener noreferrer"&gt;Anthropic's prompt caching&lt;/a&gt; on (&lt;code&gt;cache_control&lt;/code&gt; on the system prompt, default five-minute lifetime). This is the configured baseline used here, not a claim that every provider-side optimization was exhausted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;With HotKV:&lt;/strong&gt; HotKV sits in front of the same traffic and the same system prompt, with the cache starting empty.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What we counted
&lt;/h3&gt;

&lt;p&gt;Every token count comes from the &lt;code&gt;usage&lt;/code&gt; block of the API response: uncached input, cache reads and writes, and output (thinking included). Embedding tokens are separate. Costs use Anthropic's list prices of 11 October 2026, include the embedding calls for semantic lookups, and exclude HotKV hosting and operations. They are not a quote for current pricing.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the cache works
&lt;/h2&gt;

&lt;p&gt;For each question, HotKV tries two lookups before the model is called:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Exact match:&lt;/strong&gt; a &lt;code&gt;GET&lt;/code&gt; on a SHA-256 key built from the model, the system prompt version and the normalized question (lower-cased, whitespace collapsed). It catches a question asked in identical words.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Semantic match:&lt;/strong&gt; an &lt;code&gt;SCACHE.GET&lt;/code&gt; call with an embedding of the question (OpenAI &lt;code&gt;text-embedding-3-small&lt;/code&gt;, cosine similarity). It looks for a similar question. A similarity score alone cannot guarantee the cached answer fits.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Only a miss on both reaches the model, and its answer is written back with &lt;code&gt;SET&lt;/code&gt; and &lt;code&gt;SCACHE.SET&lt;/code&gt;. The similarity threshold for a semantic hit was fixed at 0.81 before the run. We chose it on a separate Banking77 train split as the lowest value, in steps of 0.01, whose semantic hits pointed at the same intent at least 98% of the time (98.2% there). In this run, on the untouched test split, 96.7% to 96.8% of semantic hits matched the intent of the question asked: 30 or 31 wrong-intent hits per model out of 926 to 936.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Calls, tokens and cost
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Model calls&lt;/th&gt;
&lt;th&gt;Tokens (input plus output)&lt;/th&gt;
&lt;th&gt;API cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Claude Fable 5.1&lt;/td&gt;
&lt;td&gt;3,000 to 896&lt;/td&gt;
&lt;td&gt;7.25M to 2.16M (70% lower)&lt;/td&gt;
&lt;td&gt;$30.31 to $9.18 (70% lower)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Opus 5.5&lt;/td&gt;
&lt;td&gt;3,000 to 898&lt;/td&gt;
&lt;td&gt;7.34M to 2.20M (70% lower)&lt;/td&gt;
&lt;td&gt;$14.60 to $4.50 (69% lower)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Sonnet 5.5&lt;/td&gt;
&lt;td&gt;3,000 to 897&lt;/td&gt;
&lt;td&gt;7.16M to 2.14M (70% lower)&lt;/td&gt;
&lt;td&gt;$5.51 to $1.66 (70% lower)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Haiku 5.5&lt;/td&gt;
&lt;td&gt;3,000 to 897&lt;/td&gt;
&lt;td&gt;7.08M to 2.11M (70% lower)&lt;/td&gt;
&lt;td&gt;$0.27 to $0.08 (70% lower)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Across the four models, calls fell from 12,000 to 3,588, tokens by 70.1% and cost by 69.6%. About 70% of requests were answered from the cache on every model: roughly 39% by exact match and 31% by semantic match.&lt;/p&gt;

&lt;p&gt;Calls, tokens and dollars fall together because HotKV removes whole calls. Read the token figure with care: 90% to 93% of the counted tokens are cache reads of the same 2,200-token policy prompt, which Anthropic bills at a small fraction of the normal input price. Output tokens are only 6% to 9% of the tokens but 73% to 92% of the baseline cost.&lt;/p&gt;

&lt;h3&gt;
  
  
  Speed
&lt;/h3&gt;

&lt;p&gt;The median response time across the whole run fell from 2.7 seconds to 127 ms on Fable 5.1, from 2.9 seconds to 126 ms on Opus 5.5, from 1.8 seconds to 128 ms on Sonnet 5.5 and from 1.4 seconds to 125 ms on Haiku 5.5, which is 11 to 23 times faster. A repeated question came back in a median of about 0.05 ms, measured by a Python client over loopback on the same machine as HotKV, so it is a local figure rather than a network one. A paraphrased question, served from the semantic cache, took about 130 ms, almost all of it the embedding API call.&lt;/p&gt;

&lt;p&gt;The whole-run median sits inside that semantic-hit band because exact hits (about 39% of requests) are too few to carry the median on their own, while exact and semantic hits together (70%) pass the halfway mark. The slow end moves less: 30% of requests still call the model. The 99th percentile was about 6.4 seconds with HotKV against 6.6 seconds without it on Fable 5.1, and about the same on Haiku 5.5. It was lower on Opus 5.5 (4.7 seconds against about 6) and on Sonnet 5.5 (2.7 seconds against 3.3). Calls were not streamed, so these are times to the complete answer, not to the first token.&lt;/p&gt;

&lt;h3&gt;
  
  
  Warm-up
&lt;/h3&gt;

&lt;p&gt;The cache starts empty, so early requests still reach the model. The share of requests served from the cache was about 52% in the first thousand requests and about 81% in the last thousand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the saving comes from
&lt;/h2&gt;

&lt;p&gt;Most of the saving is plain repetition. An exact-match cache alone would have needed at most 1,264 model calls out of 3,000, one for each distinct question, which is about 58% fewer. The semantic layer took that to about 70%, so it contributes roughly 12 points on this workload. It is also the part that carries the answer-quality risk, as the next section shows. This is derived from the request sequence and the logs, not a separate measured run.&lt;/p&gt;

&lt;h2&gt;
  
  
  Answer quality
&lt;/h2&gt;

&lt;p&gt;A semantic hit means the same intent, not the same correct answer. To measure correctness we had a different Claude model judge every semantic hit. The judge saw the customer's question and two answers in random order: the cached answer HotKV served, and the fresh answer the same model gave to that exact question in the baseline run. It said whether each answer correctly answered that exact question. Opus 5.5 judged the answers of Fable 5.1, Sonnet 5.5 and Haiku 5.5, and Fable 5.1 judged Opus 5.5, so no model graded its own output.&lt;/p&gt;

&lt;h3&gt;
  
  
  At the default threshold
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Semantic hits judged&lt;/th&gt;
&lt;th&gt;Cached answer fits&lt;/th&gt;
&lt;th&gt;Fresh answer fits&lt;/th&gt;
&lt;th&gt;Gap&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Claude Fable 5.1&lt;/td&gt;
&lt;td&gt;926&lt;/td&gt;
&lt;td&gt;83.3%&lt;/td&gt;
&lt;td&gt;90.2%&lt;/td&gt;
&lt;td&gt;6.9 points&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Opus 5.5&lt;/td&gt;
&lt;td&gt;935&lt;/td&gt;
&lt;td&gt;93.3%&lt;/td&gt;
&lt;td&gt;99.0%&lt;/td&gt;
&lt;td&gt;5.8 points&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Sonnet 5.5&lt;/td&gt;
&lt;td&gt;936&lt;/td&gt;
&lt;td&gt;77.9%&lt;/td&gt;
&lt;td&gt;86.1%&lt;/td&gt;
&lt;td&gt;8.2 points&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Haiku 5.5&lt;/td&gt;
&lt;td&gt;936&lt;/td&gt;
&lt;td&gt;67.9%&lt;/td&gt;
&lt;td&gt;78.6%&lt;/td&gt;
&lt;td&gt;10.7 points&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;At 0.81, a cached answer fit the exact question 5.8 to 10.7 percentage points less often than a fresh answer from the same model. Semantic hits are about 31% of requests, so across all responses, and counting exact hits as neutral, that is roughly 2 to 3 points (1.8 to 3.3). The judges differ in strictness, so compare cached with fresh only within one model.&lt;/p&gt;

&lt;h3&gt;
  
  
  Raising the threshold
&lt;/h3&gt;

&lt;p&gt;We reran Sonnet 5.5 at four more thresholds, each from an empty cache, with the same judge. The baseline cost was $5.51.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Threshold&lt;/th&gt;
&lt;th&gt;API cost&lt;/th&gt;
&lt;th&gt;Lower by&lt;/th&gt;
&lt;th&gt;Model calls&lt;/th&gt;
&lt;th&gt;Semantic hits&lt;/th&gt;
&lt;th&gt;Cached answer fits&lt;/th&gt;
&lt;th&gt;Fresh answer fits&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0.81&lt;/td&gt;
&lt;td&gt;$1.66&lt;/td&gt;
&lt;td&gt;70%&lt;/td&gt;
&lt;td&gt;897&lt;/td&gt;
&lt;td&gt;936&lt;/td&gt;
&lt;td&gt;77.9%&lt;/td&gt;
&lt;td&gt;86.1%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.85&lt;/td&gt;
&lt;td&gt;$1.88&lt;/td&gt;
&lt;td&gt;66%&lt;/td&gt;
&lt;td&gt;1,024&lt;/td&gt;
&lt;td&gt;609&lt;/td&gt;
&lt;td&gt;80.3%&lt;/td&gt;
&lt;td&gt;85.6%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.88&lt;/td&gt;
&lt;td&gt;$1.99&lt;/td&gt;
&lt;td&gt;64%&lt;/td&gt;
&lt;td&gt;1,110&lt;/td&gt;
&lt;td&gt;382&lt;/td&gt;
&lt;td&gt;89.5%&lt;/td&gt;
&lt;td&gt;83.8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.90&lt;/td&gt;
&lt;td&gt;$2.13&lt;/td&gt;
&lt;td&gt;61%&lt;/td&gt;
&lt;td&gt;1,160&lt;/td&gt;
&lt;td&gt;281&lt;/td&gt;
&lt;td&gt;87.9%&lt;/td&gt;
&lt;td&gt;86.5%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.95&lt;/td&gt;
&lt;td&gt;$2.22&lt;/td&gt;
&lt;td&gt;60%&lt;/td&gt;
&lt;td&gt;1,247&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;92.0%&lt;/td&gt;
&lt;td&gt;90.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;From 0.88 upward cached answers did not show a deficit against fresh ones, while still cutting cost by 64% at 0.88 and 61% at 0.90. The evidence is thin. At 0.90 the 95% interval for the difference runs from about 4 points worse to 7 points better, the 0.95 row has only 50 hits, and each row judges a different subset of hits. This is one model, one judge and one run per threshold, so it is not proof of equivalent quality or a universal safe threshold.&lt;/p&gt;

&lt;h3&gt;
  
  
  Near-identical questions
&lt;/h3&gt;

&lt;p&gt;The real risk is questions that look almost identical but need different answers, such as depositing versus withdrawing. We had Opus 5.5 write 119 pairs, each a real training-split question plus a version with one decisive detail changed, and counted how many changed questions would clear the threshold against a cache holding only the original. These pairs are built to be hard, were not reviewed by a person, and show a worst case rather than how often it happens in real traffic.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Threshold&lt;/th&gt;
&lt;th&gt;0.81&lt;/th&gt;
&lt;th&gt;0.85&lt;/th&gt;
&lt;th&gt;0.88&lt;/th&gt;
&lt;th&gt;0.90&lt;/th&gt;
&lt;th&gt;0.95&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Changed questions that would match&lt;/td&gt;
&lt;td&gt;62%&lt;/td&gt;
&lt;td&gt;45%&lt;/td&gt;
&lt;td&gt;30%&lt;/td&gt;
&lt;td&gt;25%&lt;/td&gt;
&lt;td&gt;10%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;True paraphrases that would match&lt;/td&gt;
&lt;td&gt;39%&lt;/td&gt;
&lt;td&gt;23%&lt;/td&gt;
&lt;td&gt;7%&lt;/td&gt;
&lt;td&gt;4%&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Raising the threshold reduces the risk but does not remove it. Even at 0.90, 25% of the deliberately close pairs would match, and fewer true paraphrases match too.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means at scale
&lt;/h2&gt;

&lt;p&gt;Extrapolating the measured cost per request to 1 million requests a day over a 30-day month, and assuming the same traffic pattern, gives these monthly figures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;claude-fable-5-1&lt;/code&gt;: about $303,100 without HotKV, $91,800 with it, roughly $211,300 saved.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;claude-opus-5-5&lt;/code&gt;: about $146,000 without HotKV, $45,000 with it, roughly $101,000 saved.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;claude-sonnet-5-5&lt;/code&gt;: about $55,100 without HotKV, $16,600 with it, roughly $38,500 saved.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;claude-haiku-5-5&lt;/code&gt;: about $2,700 without HotKV, $800 with it, roughly $1,900 saved.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is arithmetic on the measured cost per request, not another measured run. It excludes hosting, and the capacity needed for that volume was not measured. At the 3,000 requests we ran, the saving is only $0.19 for Haiku 5.5 and $21.12 for Fable 5.1. The four models ran with short answers, and Fable 5.1 and Opus 5.5 at their lowest effort, so longer or reasoning-heavy answers would make each avoided call worth more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;p&gt;This is not a general "HotKV saves you 70%" claim. It is what we measured on this workload, and the workload does the heavy lifting.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Savings track repetition.&lt;/strong&gt; With every intent equally likely instead of Zipf-skewed, cost fell 56% on Sonnet 5.5 and Haiku 5.5. With 3,000 all-different questions it fell 38%, entirely from semantic matches between different questions of the same intent, which Banking77 has plenty of. A workload with no repeated or similar questions saves nothing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Synthetic traffic.&lt;/strong&gt; Draws are independent: no bursts, sessions or multi-turn context. One public dataset of short banking questions, a fictional policy written for this test, and a finite pool of about 3,080 test questions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A model judges the answers.&lt;/strong&gt; No human reviewed them, there was no second judge, and every judge is a Claude model. Fresh answers failed the judge's "fits" test between 1% and 21% of the time, so it is a strict bar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Same intent is not same answer.&lt;/strong&gt; The 0.81 threshold was calibrated on intent labels, not answer quality. The threshold sweep and the near-identical test cover one model and one embedding model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Small test rig.&lt;/strong&gt; One run per condition, a single four-vCPU server with the client on the same machine, and a cache that was not warmed before the HotKV runs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Costs are API costs.&lt;/strong&gt; They exclude HotKV hosting and operations. Validate answer quality on your own questions, and use exact caching or fresh answers where semantic reuse is unsuitable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The per-model figures are also on the &lt;a href="https://hotkv.com/ai#token-savings" rel="noopener noreferrer"&gt;AI page&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;The exact-match cache in this test uses plain &lt;code&gt;GET&lt;/code&gt; and &lt;code&gt;SET&lt;/code&gt;, which every HotKV plan includes. The semantic cache (&lt;code&gt;SCACHE.*&lt;/code&gt;) comes with the Performance plan and above (&lt;a href="https://hotkv.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;). &lt;a href="https://console.hotkv.com/register?plan=performance" rel="noopener noreferrer"&gt;Start on HotKV Cloud&lt;/a&gt; and point your existing traffic at it, or &lt;a href="mailto:sales@hotkv.com?subject=HotKV%20sales%20inquiry"&gt;talk to sales&lt;/a&gt; if you want to work through the numbers for your own workload first.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://hotkv.com/blog/token-savings-benchmark" rel="noopener noreferrer"&gt;hotkv.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>redis</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
