{
  "schema_version": 2,
  "id": "operate/oss_and_stack/management/optimization/benchmarks/index",
  "title": "Redis benchmark",
  "url": "https://redis.io/docs/latest/operate/oss_and_stack/management/optimization/benchmarks/",
  "summary": "Use the redis-benchmark utility on a Redis server",
  "aliases": [
    "/manual/optimization/benchmarks/",
    "/management/optimization/benchmarks/"
  ],
  "tags": [
    "docs",
    "operate",
    "stack",
    "oss"
  ],
  "last_updated": "2026-09-21T15:59:03+01:00",
  "page_type": "content",
  "content_hash": "25431e117ab60f292ba4616e79392d7dfeadc1de6c9206a0d1079c7481971240",
  "sections": [
    {
      "id": "how-fast-is-redis",
      "title": "How fast is Redis?",
      "role": "overview",
      "text": "Redis includes the `redis-benchmark` utility that simulates running commands done\nby N clients at the same time sending M total queries (it is similar to the\nApache's `ab` utility). Below you'll find the full output of a benchmark executed\nagainst a Linux box.\n\nThe following options are supported:\n\n[code example]\n\nOptions:\n\n- `-h <hostname>`: Server hostname (default 127.0.0.1)\n- `-p <port>`: Server port (default 6379)\n- `-s <socket>`: Server socket (overrides host and port)\n- `-a <password>`: Password for Redis Auth\n- `--user <username>`: Used to send ACL style 'AUTH username pass'. Needs -a.\n- `-c <clients>`: Number of parallel connections (default 50)\n- `-n <requests>`: Total number of requests (default 100000)\n- `-d <size>`: Data size of SET/GET value in bytes (default 3)\n- `--dbnum <db>`: SELECT the specified db number (default 0)\n- `--threads <num>`: Enable multi-thread mode.\n- `--cluster`: Enable cluster mode.\n- `--enable-tracking`: Send CLIENT TRACKING on before starting benchmark.\n- `-k <boolean>`: 1=keep alive 0=reconnect (default 1)\n- `-r <keyspacelen>`: Use random keys for SET/GET/INCR, random values for SADD, random members and scores for ZADD. Using this option the benchmark will expand the string __rand_int__ inside an argument with a 12 digits number in the specified range from 0 to keyspacelen-1. The substitution changes every time a command is executed. Default tests use this to hit random keys in the specified range.\n- `-P <numreq>`: Pipeline `<numreq>` requests. Default 1 (no pipeline).\n- `-e`: If server replies with errors, show them on stdout. (No more than 1 error per second is displayed.)\n- `-q`: Quiet. Just show query/sec values\n- `--precision`: Number of decimal places to display in latency output (default 0)\n- `--csv`: Output in CSV format\n- `-l`: Loop. Run the tests forever\n- `-t <tests>`: Only run the comma separated list of tests. The test names are the same as the ones produced as output.\n- `-I`: Idle mode. Just open N idle connections and wait.\n- `--help`: Output this help and exit.\n- `--version`: Output version and exit.\n\nYou need to have a running Redis instance before launching the benchmark.\nA typical example would be:\n\n    redis-benchmark -q -n 100000\n\nUsing this tool is quite easy, and you can also write your own benchmark,\nbut as with any benchmarking activity, there are some pitfalls to avoid.\n\nRunning only a subset of the tests\n---\n\nYou don't need to run all the default tests every time you execute redis-benchmark.\nThe simplest thing to select only a subset of tests is to use the `-t` option\nlike in the following example:\n\n    $ redis-benchmark -t set,lpush -n 100000 -q\n    SET: 180180.17 requests per second, p50=0.143 msec                    \n    LPUSH: 188323.91 requests per second, p50=0.135 msec\n\nIn the above example we asked to just run test the SET and LPUSH commands,\nin quiet mode (see the `-q` switch).\n\nIt is also possible to specify the command to benchmark directly like in the\nfollowing example:\n\n    $ redis-benchmark -n 100000 -q script load \"redis.call('set','foo','bar')\"\n    script load redis.call('set','foo','bar'): 69881.20 requests per second\n\nSelecting the size of the key space\n---\n\nBy default the benchmark runs against a single key. In Redis the difference\nbetween such a synthetic benchmark and a real one is not huge since it is an\nin-memory system, however it is possible to stress cache misses and in general\nto simulate a more real-world work load by using a large key space.\n\nThis is obtained by using the `-r` switch. For instance if I want to run\none million SET operations, using a random key for every operation out of\n100k possible keys, I'll use the following command line:\n\n    $ redis-cli flushall\n    OK\n\n    $ redis-benchmark -t set -r 100000 -n 1000000\n    ====== SET ======\n      1000000 requests completed in 13.86 seconds\n      50 parallel clients\n      3 bytes payload\n      keep alive: 1\n\n    99.76% `<=` 1 milliseconds\n    99.98% `<=` 2 milliseconds\n    100.00% `<=` 3 milliseconds\n    100.00% `<=` 3 milliseconds\n    72144.87 requests per second\n\n    $ redis-cli dbsize\n    (integer) 99993\n\nUsing pipelining\n---\n\nBy default every client (the benchmark simulates 50 clients if not otherwise\nspecified with `-c`) sends the next command only when the reply of the previous\ncommand is received, this means that the server will likely need a read call\nin order to read each command from every client. Also RTT is paid as well.\n\nRedis supports [pipelining](https://redis.io/docs/latest/develop/using-commands/pipelining), so it is possible to send\nmultiple commands at once, a feature often exploited by real world applications.\nRedis pipelining is able to dramatically improve the number of operations per\nsecond a server is able to deliver.\n\nThis is an example of running the benchmark in a MacBook Air 11\" using a\npipelining of 16 commands:\n\n    $ redis-benchmark -n 1000000 -t set,get -P 16 -q\n    SET: 1536098.25 requests per second, p50=0.479 msec                     \n    GET: 1811594.25 requests per second, p50=0.391 msec\n\nUsing pipelining results in a significant increase in performance.\n\nPitfalls and misconceptions\n---------------------------\n\nThe first point is obvious: the golden rule of a useful benchmark is to\nonly compare apples and apples. Different versions of Redis can be compared\non the same workload for instance. Or the same version of Redis, but with\ndifferent options. If you plan to compare Redis to something else, then it is\nimportant to evaluate the functional and technical differences, and take them\nin account.\n\n+ Redis is a server, hence, all commands involve network round trips. Embedded data stores do not involve network and protocol management. When comparing such products to Redis, command execution times should be used instead of end-to-end times.\n+ Redis commands return an acknowledgment for all usual commands. Some other data stores do not. Comparing Redis to stores involving one-way queries is only mildly useful.\n+ Naively iterating on synchronous Redis commands does not benchmark Redis itself, but rather measure your network (or IPC) latency and the client library intrinsic latency. To really test Redis, you need multiple connections (like redis-benchmark) and/or to use pipelining to aggregate several commands and/or multiple threads or processes.\n+ Redis is an in-memory data store with some optional persistence options. If you plan to compare it to transactional servers (MySQL, PostgreSQL, etc ...), then you should consider activating AOF and decide on a suitable fsync policy.\n+ Redis is, mostly, a single-threaded server from the POV of commands execution (actually modern versions of Redis use threads for different things). It is not designed to benefit from multiple CPU cores. People are supposed to launch several Redis instances to scale out on several cores if needed. It is not really fair to compare one single Redis instance to a multi-threaded data store.\n\nA common misconception is that redis-benchmark is designed to make Redis\nperformances look stellar, the throughput achieved by redis-benchmark being\nsomewhat artificial, and not achievable by a real application. This is\nactually not true.\n\nThe `redis-benchmark` program is a quick and useful way to get some figures and\nevaluate the performance of a Redis instance on a given hardware. However,\nby default, it does not represent the maximum throughput a Redis instance can\nsustain. Actually, by using pipelining and a fast client (hiredis), it is fairly\neasy to write a program generating more throughput than redis-benchmark. The\ndefault behavior of redis-benchmark is to achieve throughput by exploiting\nconcurrency only (i.e. it creates several connections to the server).\nIt does not use pipelining or any parallelism at all (one pending query per\nconnection at most, and no multi-threading), if not explicitly enabled via\nthe `-P` parameter. So in some way using `redis-benchmark` and, triggering, for\nexample, a `BGSAVE` operation in the background at the same time, will provide\nthe user with numbers more near to the *worst case* than to the best case.\n\nTo run a benchmark using pipelining mode (and achieve higher throughput),\nyou need to explicitly use the -P option. Please note that it is still a\nrealistic behavior since a lot of Redis based applications actively use\npipelining to improve performance. However you should use a pipeline size that\nis more or less the average pipeline length you'll be able to use in your\napplication in order to get realistic numbers.\n\nFinally, the benchmark should apply the same operations, and work in the same way\nwith the multiple data stores you want to compare. It is absolutely pointless to\ncompare the result of redis-benchmark to the result of another benchmark\nprogram and extrapolate.\n\nFor instance, Redis and memcached in single-threaded mode can be compared on\nGET/SET operations. Both are in-memory data stores, working mostly in the same\nway at the protocol level. Provided their respective benchmark application is\naggregating queries in the same way (pipelining) and use a similar number of\nconnections, the comparison is actually meaningful.\n\nThis perfect example is illustrated by the dialog between Redis (antirez) and\nmemcached (dormando) developers.\n\n[antirez 1 - On Redis, Memcached, Speed, Benchmarks and The Toilet](http://antirez.com/post/redis-memcached-benchmark.html)\n\n[dormando - Redis VS Memcached (slightly better bench)](http://dormando.livejournal.com/525147.html)\n\n[antirez 2 - An update on the Memcached/Redis benchmark](http://antirez.com/post/update-on-memcached-redis-benchmark.html)\n\nYou can see that in the end, the difference between the two solutions is not\nso staggering, once all technical aspects are considered. Please note both\nRedis and memcached have been optimized further after these benchmarks.\n\nFinally, when very efficient servers are benchmarked (and stores like Redis\nor memcached definitely fall in this category), it may be difficult to saturate\nthe server. Sometimes, the performance bottleneck is on client side,\nand not server-side. In that case, the client (i.e. the benchmark program itself)\nmust be fixed, or perhaps scaled out, in order to reach the maximum throughput.\n\nFactors impacting Redis performance\n-----------------------------------\n\nThere are multiple factors having direct consequences on Redis performance.\nWe mention them here, since they can alter the result of any benchmarks.\nPlease note however, that a typical Redis instance running on a low end,\nuntuned box usually provides good enough performance for most applications.\n\n+ Network bandwidth and latency usually have a direct impact on the performance.\nIt is a good practice to use the ping program to quickly check the latency\nbetween the client and server hosts is normal before launching the benchmark.\nRegarding the bandwidth, it is generally useful to estimate\nthe throughput in Gbit/s and compare it to the theoretical bandwidth\nof the network. For instance a benchmark setting 4 KB strings\nin Redis at 100000 q/s, would actually consume 3.2 Gbit/s of bandwidth\nand probably fit within a 10 Gbit/s link, but not a 1 Gbit/s one. In many real\nworld scenarios, Redis throughput is limited by the network well before being\nlimited by the CPU. To consolidate several high-throughput Redis instances\non a single server, it worth considering putting a 10 Gbit/s NIC\nor multiple 1 Gbit/s NICs with TCP/IP bonding.\n+ CPU is another very important factor. Being single-threaded, Redis favors\nfast CPUs with large caches and not many cores. At this game, Intel CPUs are\ncurrently the winners. It is not uncommon to get only half the performance on\nan AMD Opteron CPU compared to similar Nehalem EP/Westmere EP/Sandy Bridge\nIntel CPUs with Redis. When client and server run on the same box, the CPU is\nthe limiting factor with redis-benchmark.\n+ Speed of RAM and memory bandwidth seem less critical for global performance\nespecially for small objects. For large objects (>10 KB), it may become\nnoticeable though. Usually, it is not really cost-effective to buy expensive\nfast memory modules to optimize Redis.\n+ Redis runs slower on a VM compared to running without virtualization using\nthe same hardware. If you have the chance to run Redis on a physical machine\nthis is preferred. However this does not mean that Redis is slow in\nvirtualized environments, the delivered performances are still very good\nand most of the serious performance issues you may incur in virtualized\nenvironments are due to over-provisioning, non-local disks with high latency,\nor old hypervisor software that have slow `fork` syscall implementation.\n+ When the server and client benchmark programs run on the same box, both\nthe TCP/IP loopback and unix domain sockets can be used. Depending on the\nplatform, unix domain sockets can achieve around 50% more throughput than\nthe TCP/IP loopback (on Linux for instance). The default behavior of\nredis-benchmark is to use the TCP/IP loopback.\n+ The performance benefit of unix domain sockets compared to TCP/IP loopback\ntends to decrease when pipelining is heavily used (i.e. long pipelines).\n+ When an ethernet network is used to access Redis, aggregating commands using\npipelining is especially efficient when the size of the data is kept under\nthe ethernet packet size (about 1500 bytes). Actually, processing 10 bytes,\n100 bytes, or 1000 bytes queries almost result in the same throughput.\nSee the graph below.\n\n![Data size impact](https://github.com/dspezia/redis-doc/raw/client_command/topics/Data_size.png)\n\n+ On multi CPU sockets servers, Redis performance becomes dependent on the\nNUMA configuration and process location. The most visible effect is that\nredis-benchmark results seem non-deterministic because client and server\nprocesses are distributed randomly on the cores. To get deterministic results,\nit is required to use process placement tools (on Linux: taskset or numactl).\nThe most efficient combination is always to put the client and server on two\ndifferent cores of the same CPU to benefit from the L3 cache.\nHere are some results of 4 KB SET benchmark for 3 server CPUs (AMD Istanbul,\nIntel Nehalem EX, and Intel Westmere) with different relative placements.\nPlease note this benchmark is not meant to compare CPU models between themselves\n(CPUs exact model and frequency are therefore not disclosed).\n\n![NUMA chart](https://github.com/dspezia/redis-doc/raw/6374a07f93e867353e5e946c1e39a573dfc83f6c/topics/NUMA_chart.gif)\n\n+ With high-end configurations, the number of client connections is also an\nimportant factor. Being based on epoll/kqueue, the Redis event loop is quite\nscalable. Redis has already been benchmarked at more than 60000 connections,\nand was still able to sustain 50000 q/s in these conditions. As a rule of thumb,\nan instance with 30000 connections can only process half the throughput\nachievable with 100 connections. Here is an example showing the throughput of\na Redis instance per number of connections:\n\n![connections chart](https://github.com/dspezia/redis-doc/raw/system_info/topics/Connections_chart.png)\n\n+ With high-end configurations, it is possible to achieve higher throughput by\ntuning the NIC(s) configuration and associated interruptions. Best throughput\nis achieved by setting an affinity between Rx/Tx NIC queues and CPU cores,\nand activating RPS (Receive Packet Steering) support. More information in this\n[thread](https://groups.google.com/forum/#!msg/redis-db/gUhc19gnYgc/BruTPCOroiMJ).\nJumbo frames may also provide a performance boost when large objects are used.\n+ Depending on the platform, Redis can be compiled against different memory\nallocators (libc malloc, jemalloc, tcmalloc), which may have different behaviors\nin term of raw speed, internal and external fragmentation.\nIf you did not compile Redis yourself, you can use the INFO command to check\nthe `mem_allocator` field. Please note most benchmarks do not run long enough to\ngenerate significant external fragmentation (contrary to production Redis\ninstances).\n\nOther things to consider\n------------------------\n\nOne important goal of any benchmark is to get reproducible results, so they\ncan be compared to the results of other tests.\n\n+ A good practice is to try to run tests on isolated hardware as much as possible.\nIf it is not possible, then the system must be monitored to check the benchmark\nis not impacted by some external activity.\n+ Some configurations (desktops and laptops for sure, some servers as well)\nhave a variable CPU core frequency mechanism. The policy controlling this\nmechanism can be set at the OS level. Some CPU models are more aggressive than\nothers at adapting the frequency of the CPU cores to the workload. To get\nreproducible results, it is better to set the highest possible fixed frequency\nfor all the CPU cores involved in the benchmark.\n+ An important point is to size the system accordingly to the benchmark.\nThe system must have enough RAM and must not swap. On Linux, do not forget\nto set the `overcommit_memory` parameter correctly. Please note 32 and 64 bit\nRedis instances do not have the same memory footprint.\n+ If you plan to use RDB or AOF for your benchmark, please check there is no other\nI/O activity in the system. Avoid putting RDB or AOF files on NAS or NFS shares,\nor on any other devices impacting your network bandwidth and/or latency\n(for instance, EBS on Amazon EC2).\n+ Set Redis logging level (loglevel parameter) to warning or notice. Avoid putting\nthe generated log file on a remote filesystem.\n+ Avoid using monitoring tools which can alter the result of the benchmark. For\ninstance using INFO at regular interval to gather statistics is probably fine,\nbut MONITOR will impact the measured performance significantly."
    },
    {
      "id": "benchmark-results-on-bare-metal-servers-across-different-redis-versions",
      "title": "Benchmark results on bare-metal servers across different Redis versions",
      "role": "performance",
      "text": "It is critically important that Redis performance is retained or improved seamlessly on every released version. \n\nTo assess it, we've conducted benchmarks on the released versions of Redis (starting on v2.6.0) using `redis-benchmark` on a series of command types over a standalone redis-server, repeating the same benchmark multiple times, ensuring its statistical significance, and measuring the run-to-run variance.\n\nThe used hardware platform was a stable bare-metal HPE ProLiant DL380 Gen10 Server, with one Intel(R) Xeon(R) Gold 6230 CPU @ 2.10GHz, disabling Intel HT Technology, disabling CPU Frequency scaling, with all configurable BIOS and CPU system settings set to performance. \n\nThe box was running Ubuntu 18.04 Linux release 4.15.0-123, and Redis was compiled with gcc 7.5.0.\nThe used benchmark client (`redis-benchmark`) was kept stable across all tests, with version `redis-benchmark 6.2.0 (git:445aa844)`.\nBoth the redis-server and redis-benchmark processes were pinned to specific physical cores.\n\nThe following benchmark options were used across tests:\n\n\n* The tests were done with 50 simultaneous clients performing 5 million requests.\n* Tests were executed using the loopback interface.\n* Tests were executed without pipelining.\n* The used payload size was 256 Bytes.\n* For each redis-benchmark process, 2 threads were used to ensure that the benchmark client was not the bottleneck.\n* Strings, Hashes, Sets, and Sorted Sets data types were benchmarked.\n\nBelow we present the obtained results, broken by data type.\n\n\n![Strings performance over versions](./performance-strings.png)\n\n![Hashes performance over versions](./performance-hashes.png)\n\n![Sets performance over versions](./performance-sets.png)\n\n![Sorted sets performance over versions](./performance-sorted-sets.png)"
    },
    {
      "id": "other-redis-benchmarking-tools",
      "title": "Other Redis benchmarking tools",
      "role": "content",
      "text": "There are several third-party tools that can be used for benchmarking Redis. Refer to each tool's\ndocumentation for more information about its goals and capabilities.\n\n* [memtier_benchmark](https://github.com/redislabs/memtier_benchmark) from [Redis Labs](https://twitter.com/RedisLabs) is a NoSQL Redis and Memcache traffic generation and benchmarking tool.\n* [rpc-perf](https://github.com/twitter/rpc-perf) from [Twitter](https://twitter.com/twitter) is a tool for benchmarking RPC services that supports Redis and Memcache.\n* [YCSB](https://github.com/brianfrankcooper/YCSB) from [Yahoo @Yahoo](https://twitter.com/Yahoo) is a benchmarking framework with clients to many databases, including Redis."
    }
  ],
  "examples": [
    {
      "id": "how-fast-is-redis-ex0",
      "language": "text",
      "code": "Usage: redis-benchmark [-h <host>] [-p <port>] [-c <clients>] [-n <requests]> [-k <boolean>]",
      "section_id": "how-fast-is-redis"
    }
  ]
}
