MEMTIER_BENCHMARK(1)

πŸ“¦
version 2.5.2 Β· 2 versions
, in nixpkgs unstable

πŸ¦‹ memtier_benchmark β€” the manual, but make it make sense πŸ¦‹

okay bestie, welcome to MEMTIER_BENCHMARK(1) β€” the user-commands girlies. this is the whole page, every flag, every default, nothing skipped. grab a strawberry drink πŸ“ and let's go.


✨ NAME ✨

memtier_benchmark β€” the NoSQL benchmark tool. that's it, that's the name, no cap.


🌸 SYNOPSIS 🌸

memtier_benchmark [options]

literally just the command and then options. iconic behavior honestly.


πŸ’œ DESCRIPTION πŸ’œ

it's a memcache / redis NoSQL traffic generator and performance benchmarking tool. think of it as the gym buddy that makes your server do cardio and then tells you how sweaty it got πŸ’€


πŸ”Œ Connection and General Options:

  • -h, --host=ADDR β€” the server address (default: localhost). yes she's got two meanings for -h on this page, we'll get there, don't come for her πŸ™ˆ
  • -s, --server=ADDR β€” literally the same thing as --host. twin energy.
  • -p, --port=PORT β€” the server port (default: 6379)
  • -S, --unix-socket=SOCKET β€” UNIX Domain socket name (default: none)
  • -4, --ipv4 β€” force IPv4 address resolution.
  • -6, --ipv6 β€” force IPv6 address resolution.
  • -P, --protocol=PROTOCOL β€” which protocol to use (default: redis). the other supported protocols are resp2, resp3, memcache_text and memcache_binary. when you use one of resp2 or resp3, the redis protocol version gets set via the HELLO command. cute, right?
  • -a, --authenticate=CREDENTIALS β€” authenticate with the creds you give. a simple password is what's used for memcache_text and Redis <= 5.x. you can specify <USER>:<PASSWORD> for memcache_binary or Redis 6.x or newer with ACL user support πŸ’…
  • -u, --uri=URI β€” server URI in the format redis://user:password@host:port/dbnum. user, password and dbnum are all optional. for authentication without a username, use username default. for TLS, use the scheme rediss πŸŽ€
  • --tls β€” enable SSL/TLS transport security
  • --cert=FILE β€” use the specified client certificate for TLS
  • --key=FILE β€” use the specified private key for TLS
  • --cacert=FILE β€” use the specified CA certs bundle for TLS
  • --tls-skip-verify β€” skip verification of the server certificate (yes, she's trusting, be careful)
  • --tls-protocols β€” specify the tls protocol version to use, comma delemited (their spelling, not mine 🫢). use a combination of 'TLSv1', 'TLSv1.1', 'TLSv1.2' and 'TLSv1.3'.
  • --sni=STRING β€” add an SNI header
  • -x, --run-count=NUMBER β€” how many full-test iterations to perform
  • -D, --debug β€” print debug output
  • --cluster-mode β€” run the client in cluster mode
  • --transaction β€” treat one full rotation of --command entries as a transactional unit (like WATCH/GET/MULTI/SETEX/EXEC/UNWATCH). every __key__ in a rotation resolves to the same key (taken from the first keyed command's --command-key-pattern), so all the keyed commands hit one key and one slot: the WATCH guards the key the SETEX writes and the unit runs without CROSSSLOT errors β€” no hash-tag needed. this same-key behavior applies in every mode, so it also works against a single endpoint fronting a sharded backend (e.g. a Redis Enterprise proxy) where keyed commands have to share a slot. in --cluster-mode it additionally pins the whole rotation to the owning shard connection so the keyless commands (MULTI/EXEC/UNWATCH) stay with the keyed ones. caveat bestie: keep the literal text around __key__ (including any {tag}) identical across keyed commands; differing affixes still hash to different slots. requires at least one --command. --pipeline > 1 is supported: in --cluster-mode each rotation is sent contiguously on its pinned connection, so multiple whole transactions can be in flight without interleaving MULTI/EXEC. note: if --reconnect-on-error triggers mid-rotation, the interrupted rotation's stats will be inaccurate (server-side WATCH/MULTI state is lost on reconnect). 😭
this one's a whole saga, I know. read it twice, it's giving "final boss of flags".
  • -h, --help β€” display this help. (yes. -h again. she contains multitudes.)
  • -v, --version β€” display version information

πŸ“Š Results Output Options:

  • -o, --out-file=FILE β€” name of the output file (default: stdout)
  • --json-out-file=FILE β€” name of the JSON output file; if it's not set, nothing gets printed to json
  • --client-stats=FILE β€” produce a per-client stats file
  • --hdr-file-prefix=FILE β€” prefix of the HDR Latency Histogram output files; if it's not set, latency histogram files won't be saved
  • --show-config β€” print the detailed configuration before running
  • --hide-histogram β€” don't print the detailed latency histogram
  • --print-percentiles β€” specify which percentiles info to print on the results table (by default it prints percentiles: 50,99,99.9)
  • --print-all-runs β€” when performing multiple test iterations, print and save results for all iterations ✨
  • --realtime-latencies β€” replace the periodic single-line progress output with a per-tick block: line 1 = throughput + miss ratio, then one or more latency lines carrying the percentiles configured by --print-percentiles (immediate and overall, side-by-side). it redraws in place on a TTY; it appends cleanly when stderr is redirected to a file.
  • --command-stats-breakdown=command|line β€” how to group command statistics in the output (default: command). command: aggregate by command name (first word, e.g., SET, GET). line: show each command line separately.
  • --command-miss-tracking=auto|off β€” track per-key cache misses for arbitrary commands (default: auto). auto: enable for commands with a known reply shape (GET, MGET, HGET, HMGET, GETEX, EXISTS, ...). off: disable; mb.json will not contain per-arbitrary-command Hits/Misses fields.
  • --miss-rate-threshold=PERCENTAGE β€” warn when the miss rate exceeds this percentage (default: 1.0). accepts fractional values, e.g. 0.5 for half a percent. 0 warns on any miss.
  • --cpu-warn-threshold=PERCENTAGE β€” warn when a memtier worker thread's CPU exceeds this percentage of a core (default: 95.0), indicating memtier itself may be the bottleneck and results may be unreliable. 0 warns on any CPU usage.
  • --statsd-host=HOST β€” StatsD server hostname to send real-time metrics to (default: none, disabled)
  • --statsd-port=PORT β€” StatsD server UDP port (default: 8125)
  • --statsd-prefix=PREFIX β€” prefix for StatsD metric names (default: memtier)
  • --statsd-run-label=LABEL β€” label for this benchmark run, used to distinguish runs in dashboards (default: default)
  • --graphite-port=PORT β€” Graphite HTTP port for event annotations (default: 8080 for host access; use 80 when running inside the Docker network)
  • --prometheus-port=PORT β€” serve Prometheus metrics on this port at /metrics (default: disabled; 0 = ephemeral port)
  • --prometheus-bind-addr=ADDR β€” numeric IPv4/IPv6 address to bind the Prometheus exporter to (default: 127.0.0.1; hostnames not supported 🚫)
  • --prometheus-run-label=KEY=VALUE β€” add a constant label to every Prometheus metric (repeatable; max 16)
  • --prometheus-latency-buckets=LIST β€” comma-separated, strictly ascending latency histogram bounds in seconds (default: built-in 26-bound list). bounds closer than 1% of their value collapse to the same histogram slot and are rejected πŸ’€

πŸ§ͺ Test Options:

  • -n, --requests=NUMBER β€” number of total requests per client (default: 10000). use 'allkeys' to run on the entire key-range πŸ‘‘
  • --rate-limiting=NUMBER β€” the max number of requests to make per second from an individual connection (default is unlimited rate). if you use --rate-limiting and enter a very large rate that can't be met, memtier will do as many requests as possible per second.
  • -c, --clients=NUMBER β€” number of clients per thread (default: 50)
  • -t, --threads=NUMBER β€” number of threads (default: 4)
  • --test-time=SECS β€” number of seconds to run the test
  • --clients-start=NUMBER β€” starting number of clients per thread for staircase ramp-up. must be less than --clients. requires --clients-step and --step-duration. πŸ“ˆ
  • --clients-step=NUMBER β€” number of clients to add per step in staircase ramp-up.
  • --step-duration=SECS β€” duration in seconds of each step before adding more clients.
  • --ratio=RATIO β€” Set:Get ratio (default: 1:10)
  • --pipeline=NUMBER β€” number of concurrent pipelined requests (default: 1)
  • --reconnect-interval=NUM β€” number of requests after which re-connection is performed
  • --reconnect-on-error β€” enable automatic reconnection on connection errors (default: disabled)
  • --max-reconnect-attempts=NUM β€” maximum number of reconnection attempts (default: 0, unlimited)
  • --reconnect-backoff-factor=NUM β€” backoff factor for reconnection delays (default: 0, no backoff)
  • --retry-on-error β€” resend a request when the server returns a transient error or the connection drops mid-flight. excludes permanent errors (WRONGTYPE, NOAUTH, NOPERM, syntax/argcount/unknown-command). default: disabled.
  • --max-retries=N β€” maximum retries per request when --retry-on-error is set. -1 = unlimited (default), 0 = disable retries even with the master switch on, N>0 = bounded. MOVED/ASK redirects count toward this.
  • --retry-backoff-ms=NUM β€” delay between retries in milliseconds (default: 0, immediate).
  • --retry-backoff-factor=NUM β€” exponential multiplier applied to retry-backoff-ms on each successive retry (default: 0, constant backoff).
  • --retry-on=LIST β€” restrict retries to error-status prefixes in this comma list (e.g. LOADING,BUSY,TRYAGAIN). default: retry everything not classified as permanent.
  • --max-retry-queue=NUM β€” hard cap on per-connection retry queue depth. when full, the pipeline stops accepting new work until the queue drains. default: 0 (auto = max(pipeline * 4, 64)).
  • --failed-keys-file=PATH β€” append every request that ultimately fails (retries exhausted or permanent error) as CSV: timestamp,command,key,status,retries. off by default. the benchmark continues if the file is unwritable. 🫢
  • --connection-timeout=SECS β€” connection timeout in seconds, 0 to disable (default: 0)
  • --connection-stage-timeout=SECS β€” abort with exit code 2 if no thread reaches steady state within SECS, or if connection-setup failures (AUTH / HELLO / SELECT / CLUSTER SLOTS / -ERR during initial probe) persist for SECS without a successful handshake. this bounds the startup phase; --test-time still bounds the steady-state run. default: 30, 0 disables the supervisor.
  • --thread-conn-start-min-jitter-micros=NUM β€” minimum jitter in microseconds between connection creation (default: 0)
  • --thread-conn-start-max-jitter-micros=NUM β€” maximum jitter in microseconds between connection creation (default: 0)

and that's part one, bestie β€” more coming, don't go anywhere πŸ’–

  • --multi-key-get=NUM β€” turns on multi-key get commands, up to NUM keys at once (default: 0 = off). In cluster mode the keys get probed straight out of the key space so every key in one batch routes to the same shard (and no, you don't need a hash-tag prefix πŸ’…).
  • --select-db=DB β€” the DB number to select, for when you're testing a redis server.
  • --distinct-client-seed β€” gives each client its own different random seed. no more twinning ✨
  • --randomize β€” seeds the random off the timestamp (default is just a constant value, so yes, this one makes your runs actually differ).

🎯 Arbitrary command

  • --command=COMMAND β€” drop in a command to send, wrapped in quotes. every command you specify runs with its own ratio and key-pattern options. like, for real for real:
--command="set __key__ 5" --command-ratio=2 --command-key-pattern=G

and if you wanna use a generated key or object, you plug in:

  • __key__ β€” use a key generated from Key Options.
  • __data__ β€” use data generated from Object Options.
  • --command-ratio β€” how many times the command is sent in sequence (default: 1).
  • --command-key-pattern β€” the key pattern for the command (default: R):
    • G for Gaussian distribution.
    • R for uniform Random.
    • Z for zipf distribution (this one limits keys to positive).
    • S for Sequential.
    • P for Parallel (that's Sequential where each client has a subset of the key-range).
  • --monitor-input=FILE β€” reads commands from a Redis MONITOR output file 🫢. you can reference commands as __monitor_line1__, __monitor_line2__, etc., and use __monitor_line@__ to select commands from the file. by default the selection is sequential β€” switch it up with --monitor-pattern=R for random. example time:
--monitor-input=monitor.txt --command="__monitor_line1__"
  • --monitor-pattern=S|R β€” the pattern for picking monitor commands (default: S for Sequential). S = Sequential selection. R = Random selection. pick your fighter ✨
  • --scan-incremental-iteration β€” enables SCAN cursor iteration mode πŸ”. when you use it with --command="SCAN 0 [MATCH pattern] [COUNT count] [TYPE type]", it automatically follows the cursor that comes back in each SCAN response. it sends SCAN 0 ... first, then SCAN <cursor> ... until the cursor comes back as 0, then it restarts. requires --pipeline 1. stats get reported separately for SCAN 0 and SCAN <cursor> β€” love that for us.
  • --scan-incremental-max-iterations=NUMBER β€” max number of continuation SCANs per iteration cycle (default: 0, which means follow the cursor until it returns 0).
  • --command-is-read β€” flags the preceding --command as a read operation for --read-preference routing (it's a per-command override, iykyk).

🌈 Read Preference Options

  • --read-preference=MODE β€” which node class gets the read commands (default: primary). the modes:
    • primary β€” all reads go to the master/primary node.
    • secondary β€” all reads go to replica nodes only.
    • secondaryPreferred β€” replicas preferred; fall back to primary.
    • nearest β€” EWMA-based selection: seed cold replicas round-robin until warm, then route reads to the lowest-EWMA endpoint among warm replicas (the primary may participate if it has accumulated samples).
  • --read-server=HOST:PORT β€” the replica endpoint for standalone (non-cluster) mode. it's repeatable; each occurrence adds one replica endpoint. IPv6 addresses can be written as [::1]:6380. NOTE: this is parsed but read dispatch is currently cluster-only β€” peep the README "Read Preference" section πŸ‘€.
  • --replica-clients=N β€” connections per replica per client thread (default: 0 = inherit --clients). heads up: parsed but not yet wired β€” again, see the README "Read Preference" section.
  • --replicas-per-shard=K β€” cap on replicas used per shard (default: 0 = all). also parsed but not yet wired, same README situation.
  • --read-preference-fallback=MODE β€” what to do when the target node class is unavailable (default: error). the options:
    • error β€” return an error.
    • queue β€” (reserved; currently treated as error β€” request queuing not yet implemented) πŸ™ˆ.
    • primary β€” fall back silently to the primary.

πŸ“ Object Options

  • -d, --data-size=SIZE β€” object data size in bytes (default: 32).
  • --data-offset=OFFSET β€” the actual size of the value will be data-size + data-offset, and it'll use SETRANGE / GETRANGE (default: 0).
  • -R, --random-data β€” says the data should be randomized 🎲.
  • --data-size-range=RANGE β€” use random-sized items in the specified range (min-max).
  • --data-size-list=LIST β€” use sizes from a weight list, formatted like size1:weight1,..sizeN:weightN.
  • --data-size-pattern=R|S β€” use this alongside data-size-range. when it's set to R, a random size from the defined data sizes gets used; when it's set to S, the defined data sizes are evenly distributed across the key range, see --key-maximum (default R).
  • --expiry-range=RANGE β€” use random expiry values from the specified range ⏰.

✨ Imported Data Options

  • --data-import=FILE β€” read object data from a file.
  • --data-verify β€” enable data verification once the test is complete βœ….
  • --verify-only β€” only perform --data-verify, without any other test.
  • --generate-keys β€” generate keys for imported objects πŸ”‘.
  • --no-expiry β€” ignore expiry info in the imported data.

πŸ”‘ Key Options

  • --key-prefix=PREFIX β€” prefix for keys (default: "memtier-").
  • --key-minimum=NUMBER β€” key ID minimum value (default: 0).
  • --key-maximum=NUMBER β€” key ID maximum value (default: 10000000).
  • --key-pattern=PATTERN β€” the Set:Get pattern (default: R:R):
    • G for Gaussian distribution.
    • R for uniform Random.
    • Z for zipf distribution (limits keys to positive).
    • S for Sequential.
    • P for Parallel (that's Sequential where each client has a subset of the key-range).
  • --key-stddev β€” the standard deviation used in the Gaussian distribution (default is the key range / 6).
  • --key-median β€” the median point used in the Gaussian distribution (default is the center of the key range).
  • --key-zipf-exp β€” the exponent used in the zipf distribution, limited to (0, 5). higher exponents mean higher concentration in the top keys (default is 1 β€” though ngl, any number >2 seems insane πŸ’€).

⏳ WAIT Options

  • --wait-ratio=RATIO β€” the Set:Wait ratio (default is no WAIT commands at all β€” 1:0).
  • --num-slaves=RANGE β€” WAIT for a random number of slaves in the specified range.
  • --wait-timeout=RANGE β€” WAIT for a random number of milliseconds in the specified range (normal distribution with the center in the middle of the range).

Copyright © 2011-2026 Redis Ltd. 🌸

This is free software. You may redistribute copies of it under the terms of the GNU General Public License http://www.gnu.org/licenses/gpl.html. There is NO WARRANTY, to the extent permitted by law β€” like, none, bestie, read the fine print 🫢.


and that's the whole page, periodt πŸŽ€ this was memtier_benchmark v=2.5.2 sha=... from October 2026 β€” go slay some benchmarks for me πŸ’…βœ¨

πŸ“¦ where this page comes from