{"id":1722,"date":"2026-09-23T12:49:53","date_gmt":"2026-09-23T15:49:53","guid":{"rendered":"https:\/\/www.linuxpro.com.br\/?p=1722"},"modified":"2026-09-23T12:49:53","modified_gmt":"2026-09-23T15:49:53","slug":"keydb-fork-multithread-do-redis","status":"publish","type":"post","link":"https:\/\/www.linuxpro.com.br\/en\/2026\/09\/keydb-fork-multithread-do-redis\/","title":{"rendered":"KeyDB: the multithreaded Redis fork, tested on 2026"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/09\/keydb-fork-multithread-redis.webp\" alt=\"Mascote LinuxPro conectando dois servidores KeyDB com um cabo, com o cachorro caramelo cyborg deitado ao lado e o logo do KeyDB na parede\" width=\"1486\" height=\"856\" \/><\/p>\n<p>KeyDB was born with a simple promise: take Redis, which executes commands on a single thread, and make it use all the cores on the machine. It worked, became a product, was acquired by Snap, and gained features Redis never had, such as active replication between two masters and member expiration within a set. The catch is that in September 2026 the latest KeyDB version is almost three years old. Before putting KeyDB into production, it's worth knowing what it does well, what breaks, and where the project stands. This post installs, configures, replicates, and benchmarks KeyDB in containers, and ends with a recommendation.<\/p>\n<h2>Where KeyDB came from<\/h2>\n<p>KeyDB started in early 2019 as an experiment by <strong>John Sully<\/strong> and <strong>Ben Schermel<\/strong>, in Toronto, to add multithreading to Redis. The project grew, went through Y Combinator (2020 summer batch) and became EQ Alpha Technology, which maintained two editions: the open one and KeyDB Pro, closed and paid.<\/p>\n<p>In <strong>12 May 2022<\/strong> KeyDB <a href=\"https:\/\/docs.keydb.dev\/news\/2022\/05\/12\/keydb-joins-snap\">announced that it became part of Snap<\/a>, owner of Snapchat. With the acquisition, the code from the Pro edition was opened and version 6.3.0 merged everything into a single project under the <strong>BSD-3-Clause<\/strong>. license. The repository moved from <code data-no-translation=\"\">EQ-Alpha\/KeyDB<\/code> to <a href=\"https:\/\/github.com\/Snapchat\/KeyDB\">Snapchat\/KeyDB<\/a>, and Snap began using KeyDB in part of its own cache layer.<\/p>\n<p>The stated reason for the fork is in the README: the authors felt that Redis prioritized code simplicity over simplicity for the user, who ended up needing external components (Sentinel, proxies, scripts) to solve common problems. KeyDB wanted to be Redis \u201cwith batteries included\u201d, maintaining compatibility with the protocol, modules, and Lua scripts.<\/p>\n<h2>How the multithreaded architecture works<\/h2>\n<p>The classic Redis executes all commands on a main thread. Since version 6 it can use <code data-no-translation=\"\">io-threads<\/code> to read and write to sockets in parallel, but command execution remains serialized. KeyDB went another way: it runs <strong>the entire event loop on multiple threads<\/strong>. Each connection is assigned to a thread on <code data-no-translation=\"\">accept()<\/code>, and parsing and network I\/O happen in parallel. Access to the key table is protected by a <strong>spinlock<\/strong>, and transactions hold that lock for the entire duration of the <code data-no-translation=\"\">EXEC<\/code>, which preserves the atomicity that applications expect from Redis (<a href=\"https:\/\/docs.keydb.dev\/blog\/2019\/10\/07\/blog-post\/\">the authors' explanation<\/a>).<\/p>\n<p>In practice, this is controlled by two directives in the <code data-no-translation=\"\">keydb.conf<\/code>:<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">server-threads 4              # threads que atendem clientes (padr\u00e3o do pacote: 2)\nserver-thread-affinity true   # fixa cada thread num n\u00facleo<\/code><\/pre>\n<p>The README recommends relating <code data-no-translation=\"\">server-threads<\/code> to the number of NIC queues, not to the number of cores, and suggests 4 as a starting point: because KeyDB uses spinlocks, too many threads increase lock contention. In the benchmark below, 8 threads still performed better than 4 with 6 cores dedicated to the server, so measure on your own hardware.<\/p>\n<p>The diagram shows the two nodes used in this post's lab, each with four threads, and active replication between them:<\/p>\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/09\/keydb-arquitetura-replicacao-ativa.webp\" width=\"1200\" height=\"730\" alt=\"Diagrama da arquitetura do KeyDB: aplica\u00e7\u00f5es, HAProxy e dois n\u00f3s com quatro threads cada, replicando escritas nos dois sentidos\" \/><\/figure>\n<h2>Features Redis does not have<\/h2>\n<p>According to Oracle's <a href=\"https:\/\/docs.keydb.dev\/\">official documentation<\/a>, KeyDB adds to Redis' feature set:<\/p>\n<ul>\n<li><strong>Active replication<\/strong>: two or more nodes are replicas of each other and accept reads and writes at the same time. There is no replica promotion or Sentinel on failover; just a TCP load balancer pointing to the healthy nodes. With multiple nodes in a mesh, the feature becomes <strong>multi-master<\/strong>. The documentation promises that, after a network partition, \u201cthe newer write wins\u201d (<em>last write wins<\/em>). In the tests below, that did not happen.<\/li>\n<li><strong>Subkey expires<\/strong>: the command <code data-no-translation=\"\">EXPIREMEMBER<\/code> gives a TTL to a member of a set, hash, or sorted set, not to the entire key. In Redis, this feature only arrived in version 7.4, and only for hash fields.<\/li>\n<li><strong>MVCC<\/strong>: a <a href=\"https:\/\/docs.keydb.dev\/docs\/mvcc\/\">documentation<\/a> describes snapshots that allow executing <code data-no-translation=\"\">KEYS<\/code> and <code data-no-translation=\"\">SCAN<\/code> without blocking the database, and a <em>background save<\/em> without <code data-no-translation=\"\">fork()<\/code>, which avoids duplicating memory pages during the snapshot.<\/li>\n<li><strong>FLASH storage<\/strong>: with <code data-no-translation=\"\">storage-provider flash \/caminho<\/code>, KeyDB writes everything to a RocksDB on SSD\/NVMe and keeps only hot data in RAM. The <a href=\"https:\/\/docs.keydb.dev\/docs\/flash\/\">documentation itself<\/a> classifies the feature as <strong>beta\/experimental<\/strong>.<\/li>\n<li><strong>Direct backup to S3<\/strong> with <code data-no-translation=\"\">db-s3-object<\/code>, and <strong>ModJS<\/strong>, a module for writing commands in JavaScript on top of V8.<\/li>\n<\/ul>\n<h2>The state of the project in September 2026<\/h2>\n<p>I consulted the project's GitHub, Docker Hub, and APT repository in 23 September of 2026:<\/p>\n<table>\n<thead>\n<tr>\n<th>Indicator<\/th>\n<th>Status<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Latest release<\/td>\n<td><strong>v6.3.4<\/strong>, published on 30\/10\/2023<\/td>\n<\/tr>\n<tr>\n<td>Last commit on branch <code data-no-translation=\"\">main<\/code><\/td>\n<td>April 2024 (build tweaks)<\/td>\n<\/tr>\n<tr>\n<td>Docker image <code data-no-translation=\"\">eqalpha\/keydb:latest<\/code><\/td>\n<td>6.3.4 from 30\/10\/2023, Ubuntu base 20.04<\/td>\n<\/tr>\n<tr>\n<td>APT repository<\/td>\n<td>Ubuntu 20.04\/22.04 and Debian 11\/12; <strong>without<\/strong> Ubuntu 24.04 nor Debian 13<\/td>\n<\/tr>\n<tr>\n<td>Open issues<\/td>\n<td>292<\/td>\n<\/tr>\n<tr>\n<td>Codebase<\/td>\n<td>Redis 6.2 (the server itself advertises as <code data-no-translation=\"\">redis_version:6.3.4<\/code>)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>In <a href=\"https:\/\/github.com\/Snapchat\/KeyDB\/issues\/895\">31 of January 2025<\/a>, John Sully, KeyDB's lead author, posted a farewell issue: it was his last day at Snap, he did not know what the company would do with the project and suggested that development effort move to the <strong>Valkey<\/strong>, which, in his tests, had already matched KeyDB's performance. Since then, the issue <a href=\"https:\/\/github.com\/Snapchat\/KeyDB\/issues\/923\">\u201cIs KeyDB abandoned by Snap Inc?\u201d<\/a> has remained unanswered by any maintainer.<\/p>\n<p>The most serious piece of data is security-related. The <a href=\"https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2025-49844\">CVE-2025-49844<\/a> (CVSS 9.9 no NVD) is a <em>use-after-free<\/em> in Lua that allows remote code execution by an authenticated user, and according to NVD it affects \u201call versions of Redis with Lua scripting\u201d. KeyDB inherited this code. The <a href=\"https:\/\/github.com\/Snapchat\/KeyDB\/pull\/918\">PR that ports the fix<\/a> has been open since October 2025: it received approvals from community users, but no maintainer merged it.<\/p>\n<p><strong>Honest conclusion: KeyDB is stalled.<\/strong> The repository has not been archived and Snap may continue using an internal version, but the public project receives no releases, security fixes, or packages for current distributions.<\/p>\n<h2>Installation on Ubuntu and Debian<\/h2>\n<p>The project maintains its own APT repository. I tested the procedure in containers with systemd, and it worked on <strong>Ubuntu 22.04<\/strong> and in the <strong>Debian 12<\/strong>:<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">echo \"deb https:\/\/download.keydb.dev\/open-source-dist $(lsb_release -sc) main\" \\\n  | sudo tee \/etc\/apt\/sources.list.d\/keydb.list\nsudo wget -O \/etc\/apt\/trusted.gpg.d\/keydb.gpg \\\n  https:\/\/download.keydb.dev\/open-source-dist\/keyring.gpg\nsudo apt update\nsudo apt install keydb\nsudo systemctl enable --now keydb-server<\/code><\/pre>\n<p>The package <code data-no-translation=\"\">keydb<\/code> installs the <code data-no-translation=\"\">keydb-server<\/code> (systemd service running as user <code data-no-translation=\"\">keydb<\/code>, configuration in <code data-no-translation=\"\">\/etc\/keydb\/keydb.conf<\/code>) and its <code data-no-translation=\"\">keydb-tools<\/code> (<code data-no-translation=\"\">keydb-cli<\/code>, <code data-no-translation=\"\">keydb-benchmark<\/code>, <code data-no-translation=\"\">keydb-check-aof<\/code> and <code data-no-translation=\"\">keydb-check-rdb<\/code>). To review the service commands, see <a href=\"\/en\/2026\/09\/dominando-o-systemd-comandos-essenciais\/\">Mastering systemd<\/a>.<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">systemctl is-active keydb-server\n# active\nkeydb-cli ping\n# PONG\nkeydb-cli set curso linuxpro &amp;&amp; keydb-cli get curso\n# OK\n# \"linuxpro\"<\/code><\/pre>\n<p>On <strong>Ubuntu 24.04<\/strong> and in the <strong>Debian 13<\/strong>, the <code data-no-translation=\"\">apt update<\/code> fails because the repository doesn't have the suites <code data-no-translation=\"\">noble<\/code> and <code data-no-translation=\"\">trixie<\/code>. On Ubuntu 24.04, switch <code data-no-translation=\"\">$(lsb_release -sc)<\/code> by <code data-no-translation=\"\">jammy<\/code> installed and started the service without error in my test. This is a workaround, not official support, and Debian 13 still has no package (there is an <a href=\"https:\/\/github.com\/Snapchat\/KeyDB\/issues\/920\">issue requesting<\/a>, with no response).<\/p>\n<h2>Running with Docker<\/h2>\n<p>The official image is <code data-no-translation=\"\">eqalpha\/keydb<\/code>. It brings <code data-no-translation=\"\">protected-mode no<\/code> and no password in <code data-no-translation=\"\">keydb.conf<\/code> default, so never publish the port without setting up authentication. A minimal instance, only on localhost and with a password:<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">docker run -d --name keydb \\\n  -p 127.0.0.1:6379:6379 \\\n  -v keydb-data:\/data \\\n  eqalpha\/keydb:x86_64_v6.3.4 \\\n  keydb-server \/etc\/keydb\/keydb.conf \\\n    --requirepass 'TroqueEstaSenha' \\\n    --server-threads 4 \\\n    --appendonly yes\n\ndocker exec -it keydb keydb-cli -a 'TroqueEstaSenha' ping<\/code><\/pre>\n<p>Any Redis client works without change, including the <code data-no-translation=\"\">redis-cli<\/code> and the language libraries, because the protocol is the same. If you don't use containers in your day to day, <a href=\"\/en\/2026\/09\/a-historia-do-docker\/\">the history of Docker<\/a> explains where the tool comes from.<\/p>\n<h2>Active replication between two nodes<\/h2>\n<p>The lab uses two containers, <code data-no-translation=\"\">keydb-lab-a<\/code> and <code data-no-translation=\"\">keydb-lab-b<\/code>, on a Docker network. Each node points to the other with <code data-no-translation=\"\">replicaof<\/code> and starts <code data-no-translation=\"\">active-replica<\/code>:<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\"># keydb-a.conf  (no keydb-b.conf, troque para: replicaof keydb-lab-a 6379)\nport 6379\nbind 0.0.0.0\nprotected-mode yes\nrequirepass SenhaForte123\nmasterauth SenhaForte123\nserver-threads 4\nactive-replica yes\nreplicaof keydb-lab-b 6379\nappendonly yes\ndir \/data<\/code><\/pre>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">docker network create keydb-lab-net\nfor n in a b; do\n  docker run -d --name keydb-lab-$n --network keydb-lab-net \\\n    -v $PWD\/keydb-$n.conf:\/etc\/keydb\/keydb.conf:ro \\\n    eqalpha\/keydb:x86_64_v6.3.4 keydb-server \/etc\/keydb\/keydb.conf\ndone\n\nA=\"docker exec keydb-lab-a keydb-cli -a SenhaForte123 --no-auth-warning\"\nB=\"docker exec keydb-lab-b keydb-cli -a SenhaForte123 --no-auth-warning\"\n\n$A info replication | grep -E 'role|link_status'\n# role:active-replica\n# master_global_link_status:up\n# master_link_status:up\n\n$A set site linuxpro.com.br ; $B get site     # \"linuxpro.com.br\"\n$B set autor nilton         ; $A get autor    # \"nilton\"<\/code><\/pre>\n<p>The log confirms the four threads (<code data-no-translation=\"\">Thread 0 alive<\/code> up to <code data-no-translation=\"\">Thread 3 alive<\/code>) and the warning that <code data-no-translation=\"\">active-replica yes<\/code> implies <code data-no-translation=\"\">replica-read-only no<\/code>. Writes made on any node appeared on the other in less than a second.<\/p>\n<p>The scenario highlighted in the documentation also worked: with node B stopped, I wrote a new value to A. When I brought B back up, it synchronized and started showing the new value, without overwriting A with the old data from its AOF.<\/p>\n<h3>The network partition test<\/h3>\n<p>Then I simulated a network partition. I lowered the <code data-no-translation=\"\">repl-timeout<\/code> to 5 seconds, disconnected node B from the Docker network and waited for the <code data-no-translation=\"\">master_link_status<\/code> to move to <code data-no-translation=\"\">down<\/code>. With the nodes isolated, I wrote the same key on both and reconnected B:<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">$A config set repl-timeout 5 ; $B config set repl-timeout 5\ndocker network disconnect keydb-lab-net keydb-lab-b\n# ... aguarda master_link_status:down em B ...\n$B set k6 azul-antigo      # escrita mais velha, em B\n$A set k6 verde-novo       # escrita mais nova, em A (2 s depois)\ndocker network connect keydb-lab-net keydb-lab-b\n# ... aguarda master_link_status:up ...\n$A get k6    # \"azul-antigo\"\n$B get k6    # \"verde-novo\"<\/code><\/pre>\n<p>Instead of converging to the newest write, <strong>the nodes swapped values and ended up diverged<\/strong>. The log showed a partial resynchronization (<code data-no-translation=\"\">Successful partial resynchronization<\/code>), and each node applied the other's write on top. I repeated the test seven times, with partitions ranging from 3 to 15 seconds, both with the replication link going down and without it actually going down, and the result was always the same. The divergence persisted until a <code data-no-translation=\"\">docker restart keydb-lab-b<\/code> forced a full synchronization, and at that point both nodes ended up with <code data-no-translation=\"\">azul-antigo<\/code>: <strong>the newest write was lost<\/strong>.<\/p>\n<p>This behavior is known. The <a href=\"https:\/\/github.com\/Snapchat\/KeyDB\/issues\/366\">issue #366<\/a> reports the same problem since September of 2021, and in December of 2023 another user confirmed that it continued in 6.3.4. Since active replication is the main reason to choose KeyDB, this weighs: <strong>do not use active-replica where a silent data divergence is unacceptable<\/strong>.<\/p>\n<h2>Member expiration with EXPIREMEMBER<\/h2>\n<p>This feature worked as documented, including being replicated to the other node:<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">$A sadd sessoes u1 u2 u3\n$A expiremember sessoes u1 3          # u1 expira em 3 s\n$A ttl sessoes                        # -1: a chave em si n\u00e3o expira\nsleep 4\n$A smembers sessoes                   # u2, u3\n$B smembers sessoes                   # u2, u3\n\n$A hset carrinho item1 a item2 b\n$A expiremember carrinho item1 2000 ms   # unidade opcional: s ou ms<\/code><\/pre>\n<p>For caches with tags or session lists, this avoids the trick of keeping a parallel sorted set just to manage the validity of each member.<\/p>\n<h2>Simple benchmark: KeyDB, Valkey, and Redis<\/h2>\n<p>KeyDB's README warns that the <code data-no-translation=\"\">keydb-benchmark<\/code> and the <code data-no-translation=\"\">redis-benchmark<\/code> are too slow to saturate a multithreaded server and recommends the <a href=\"https:\/\/github.com\/RedisLabs\/memtier_benchmark\">memtier_benchmark<\/a>. That's what I used, in containers on the same machine.<\/p>\n<p><strong>Environment:<\/strong> AMD Ryzen 9 9900X (12 cores\/24 threads), 186 GB of RAM, Docker on a bridge network. The server was pinned to 6 physical cores (<code data-no-translation=\"\">--cpuset-cpus 0-5,12-17<\/code>) and memtier to the other 6 (<code data-no-translation=\"\">6-11,18-23<\/code>), without sharing a kernel. No persistence (<code data-no-translation=\"\">--save \"\" --appendonly no<\/code>), 200 thousand 100-byte keys preloaded, 8 threads \u00d7 50 connections in memtier, 1 SETs to 10 GETs, random keys, 20 seconds per round. I ran three rounds per configuration, and the table shows the median. The machine was running other containers at the same time, so compare rows against each other, not against numbers from other environments.<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">docker run --rm --network keydb-lab-net --cpuset-cpus 6-11,18-23 \\\n  redislabs\/memtier_benchmark:latest -s keydb-lab-srv -p 6379 \\\n  --protocol=redis --threads=8 --clients=50 --ratio=1:10 \\\n  --data-size=100 --key-maximum=200000 --key-pattern=R:R \\\n  --test-time=20 --hide-histogram<\/code><\/pre>\n<table>\n<thead>\n<tr>\n<th>Server and configuration<\/th>\n<th>ops\/s (median)<\/th>\n<th>average latency<\/th>\n<th>p99<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>KeyDB 6.3.4, <code data-no-translation=\"\">server-threads 1<\/code><\/td>\n<td>213 thousand<\/td>\n<td>1,88 ms<\/td>\n<td>2,78 ms<\/td>\n<\/tr>\n<tr>\n<td>Valkey 9.1.2, <code data-no-translation=\"\">io-threads 1<\/code><\/td>\n<td>214 thousand<\/td>\n<td>1,86 ms<\/td>\n<td>3,81 ms<\/td>\n<\/tr>\n<tr>\n<td>KeyDB 6.3.4, <code data-no-translation=\"\">server-threads 4<\/code><\/td>\n<td>833 thousand<\/td>\n<td>0,48 ms<\/td>\n<td>1,01 ms<\/td>\n<\/tr>\n<tr>\n<td>Valkey 9.1.2, <code data-no-translation=\"\">io-threads 4<\/code><\/td>\n<td>633 thousand<\/td>\n<td>0,63 ms<\/td>\n<td>1,01 ms<\/td>\n<\/tr>\n<tr>\n<td>KeyDB 6.3.4, <code data-no-translation=\"\">server-threads 8<\/code><\/td>\n<td>1,30 million<\/td>\n<td>0,31 ms<\/td>\n<td>0,81 ms<\/td>\n<\/tr>\n<tr>\n<td>Valkey 9.1.2, <code data-no-translation=\"\">io-threads 8<\/code><\/td>\n<td>1,25 million<\/td>\n<td>0,32 ms<\/td>\n<td>0,58 ms<\/td>\n<\/tr>\n<tr>\n<td>Redis 8.10.2, <code data-no-translation=\"\">io-threads 8<\/code><\/td>\n<td>1,28 million<\/td>\n<td>0,31 ms<\/td>\n<td>0,65 ms<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>What the numbers show:<\/p>\n<ul>\n<li>With one thread, KeyDB and Valkey are tied, which makes sense: they are essentially the same engine inherited from Redis.<\/li>\n<li>With 4 threads, KeyDB is about 30% ahead of Valkey. Running commands across multiple threads still pays off when there are few threads.<\/li>\n<li>With 8 threads, all three are within 4% of each other, and Valkey and Redis have the lowest p99. At that point, the bottleneck is likely memtier itself or the Docker network stack, no longer the server.<\/li>\n<\/ul>\n<p>In short, the performance advantage that justified KeyDB in 2019 is now small, and only shows up with few threads. This matches what John Sully himself wrote when leaving Snap.<\/p>\n<h2>Redis vs. Valkey vs. KeyDB<\/h2>\n<p>Data verified in the official repositories in 23\/09\/2026:<\/p>\n<table>\n<thead>\n<tr>\n<th><\/th>\n<th>Redis<\/th>\n<th>Valkey<\/th>\n<th>KeyDB<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>License<\/td>\n<td>tripled since 8.0: RSALv2, SSPLv1 or <strong>AGPLv3<\/strong> (7.4 was only RSALv2\/SSPL)<\/td>\n<td><strong>BSD-3-Clause<\/strong><\/td>\n<td><strong>BSD-3-Clause<\/strong><\/td>\n<\/tr>\n<tr>\n<td>Who maintains<\/td>\n<td>Redis Ltd.<\/td>\n<td>community, under the Linux Foundation<\/td>\n<td>Snap (no public activity)<\/td>\n<\/tr>\n<tr>\n<td>Latest stable version<\/td>\n<td>8.10.2 (17\/09\/2026)<\/td>\n<td>9.1.2 (01\/09\/2026)<\/td>\n<td>6.3.4 (30\/10\/2023)<\/td>\n<\/tr>\n<tr>\n<td>Codebase<\/td>\n<td>own<\/td>\n<td>fork of the latest BSD Redis (7.2 series)<\/td>\n<td>fork of Redis 6.2<\/td>\n<\/tr>\n<tr>\n<td>Multithread<\/td>\n<td>I\/O threads; commands on a single thread<\/td>\n<td>I\/O threads; commands on a single thread<\/td>\n<td>event loop and commands across multiple threads<\/td>\n<\/tr>\n<tr>\n<td>Cluster with sharding<\/td>\n<td>yes<\/td>\n<td>yes<\/td>\n<td>yes (Redis 6.2 cluster mode)<\/td>\n<\/tr>\n<tr>\n<td>Multi-master replication<\/td>\n<td>no in the open source edition<\/td>\n<td>no<\/td>\n<td>yes, with the split-brain bug above<\/td>\n<\/tr>\n<tr>\n<td>Per-member expiration<\/td>\n<td>hash fields (since 7.4)<\/td>\n<td>hash fields (since 9.0)<\/td>\n<td>set, hash, and sorted set<\/td>\n<\/tr>\n<tr>\n<td>Fix for CVE-2025-49844<\/td>\n<td>yes (8.2.2 and backports)<\/td>\n<td>yes<\/td>\n<td><strong>no<\/strong><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The Redis license change was announced on <a href=\"https:\/\/redis.io\/blog\/redis-adopts-dual-source-available-licensing\/\">20 de March de 2024<\/a>. The Linux Foundation <a href=\"https:\/\/www.linuxfoundation.org\/press\/linux-foundation-launches-open-source-valkey-community\">launched Valkey in 28 de March de 2024<\/a> from the last BSD code, and in <a href=\"https:\/\/redis.io\/blog\/agplv3\/\">1st of May of 2025<\/a> Redis 8 added AGPLv3 as a third option, returning to having an OSI-approved license.<\/p>\n<p>A caution with the comparisons circulating on the internet: there are articles that attribute to KeyDB the Apache license 2.0 (the license is BSD-3-Clause) and performance tables without environment or method described. Always check the repository and measure on your hardware.<\/p>\n<h2>Which one to choose<\/h2>\n<ul>\n<li><strong>New project: use Valkey.<\/strong> It is BSD, has frequent releases, security fixes, packages in current distributions, and is the recommended alternative by KeyDB's own author. With <code data-no-translation=\"\">io-threads<\/code> it already takes advantage of multiple cores.<\/li>\n<li><strong>Need the Redis Ltd. ecosystem.<\/strong> (integrated Redis 8 modules, commercial support)? Use Redis, knowing the license is AGPLv3 or source-available.<\/li>\n<li><strong>Already running KeyDB in production?<\/strong> Plan the migration to Valkey. While it does not happen, block Lua scripts for those who do not need them (<code data-no-translation=\"\">ACL SETUSER &lt;usuario&gt; -@scripting<\/code>, which I tested in 6.3.4), do not expose the port outside the internal network, and treat active replication as subject to divergence. <code data-no-translation=\"\">EXPIREMEMBER<\/code> and active replication do not exist in Valkey, so review the code that uses those features.<\/li>\n<li><strong>KeyDB in a new project:<\/strong> I do not recommend it. The performance that justified it has fallen behind, and the lack of maintenance weighs more.<\/li>\n<\/ul>\n<h2>Conclusion<\/h2>\n<p>KeyDB proved a thesis: a Redis-compatible cache could use all cores, and that pressure helped push Redis and Valkey toward I\/O multithreading. But a database without a maintainer, without a fix for a critical RCE, and with active replication that loses writes after a partition should not receive new data in 2026. For those who need high availability, the path is Valkey, and the post <a href=\"\/en\/2026\/09\/valkey-em-cluster-primarios-replicas-failover\/\">Valkey in a cluster<\/a> shows how to set up three primaries and three replicas, with tested failover. If the cache is going into production, monitor it properly, with <a href=\"\/en\/2026\/09\/monitorando-servidores-linux-com-prometheus\/\">Prometheus and Node Exporter<\/a> or with a simple checker like the <a href=\"\/en\/2026\/09\/go-uptime-monitoramento-self-hosted-derivado-do-gatus\/\">Go Uptime<\/a>. And if your Go application already uses Redis for queues, the post about <a href=\"\/en\/2026\/09\/asynq-filas-de-tarefas-em-go-com-redis-e-asynqmon\/\">Asynq<\/a> works the same way with Valkey.<\/p>","protected":false},"excerpt":{"rendered":"<p>KeyDB installed, replicated, and benchmarked in containers: the multithreaded Redis fork still runs, but has been stalled since 2023, loses writes after a network partition, and did not fix CVE-2025-49844. Comparison with Redis and Valkey, plus a recommendation.<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[46,21,2,111,120],"tags":[501,500,156,499,496,497],"class_list":["post-1722","post","type-post","status-publish","format-standard","hentry","category-devops","category-infra","category-linux","category-opensource","category-servidores","tag-banco-de-dados","tag-cache","tag-docker","tag-keydb","tag-redis","tag-valkey"],"_links":{"self":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts\/1722","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/comments?post=1722"}],"version-history":[{"count":3,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts\/1722\/revisions"}],"predecessor-version":[{"id":1727,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts\/1722\/revisions\/1727"}],"wp:attachment":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/media?parent=1722"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/categories?post=1722"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/tags?post=1722"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}