Configuration Specification

March 22, 2026 ยท View on GitHub

This document provides the complete specification for resp-bench configuration files.

Overview

resp-bench uses two JSON configuration files:

  1. Driver Config - Specifies which client library to use
  2. Workload Config - Defines the benchmark phases and traffic patterns

Driver Configuration

Schema

{
  "schema_version": "1.0",
  "description": "Human-readable description",
  "driver_id": "string",
  "mode": "standalone|cluster|sentinel",
  "tls": { ... },
  "auth": { ... },
  "specific_driver_config": { ... }
}

Fields

FieldTypeRequiredDescription
schema_versionstringYesSchema version, currently "1.0"
descriptionstringNoHuman-readable description
driver_idstringYesClient library identifier
modestringYesServer topology: standalone, cluster, or sentinel
tlsobjectNoTLS/SSL configuration
authobjectNoAuthentication configuration
specific_driver_configobjectNoDriver-specific options

Driver IDs by Language

Java:

  • jedis - Jedis client
  • lettuce - Lettuce client
  • valkey-glide - Valkey GLIDE client
  • redisson - Redisson async client
  • spring-data-valkey - Spring Data Valkey (requires secondary_driver_id)
  • spring-data-redis - Spring Data Redis (requires secondary_driver_id)

Ruby:

  • redis-rb - redis-rb client
  • valkey-glide-ruby - Valkey GLIDE Ruby client

C#:

  • stackexchange-redis - StackExchange.Redis client
  • valkey-glide-csharp - Valkey GLIDE C# client

Python (planned):

  • redis-py - redis-py synchronous client
  • redis-py-async - redis-py async client
  • valkey-glide - Valkey GLIDE Python client

TLS Configuration

{
  "tls": {
    "enabled": true,
    "cert_path": "/path/to/client.crt",
    "key_path": "/path/to/client.key",
    "ca_path": "/path/to/ca.crt",
    "verify_hostname": true
  }
}
FieldTypeDefaultDescription
enabledbooleanfalseEnable TLS
cert_pathstring-Path to client certificate
key_pathstring-Path to client private key
ca_pathstring-Path to CA certificate
verify_hostnamebooleantrueVerify server hostname

Authentication Configuration

{
  "auth": {
    "username": "default",
    "password": "secret"
  }
}
FieldTypeDescription
usernamestringUsername for ACL authentication
passwordstringPassword for authentication

Driver-Specific Configuration

{
  "specific_driver_config": {
    "secondary_driver_id": "valkey-glide",
    "pool_size": 10,
    "timeout_ms": 5000
  }
}

Used for framework drivers (e.g., Spring Data) that wrap other clients.

Examples

Jedis Standalone:

{
  "schema_version": "1.0",
  "description": "Jedis client - standalone mode",
  "driver_id": "jedis",
  "mode": "standalone"
}

Spring Data Valkey with GLIDE:

{
  "schema_version": "1.0",
  "description": "Spring Data Valkey with Valkey-Glide driver",
  "driver_id": "spring-data-valkey",
  "mode": "standalone",
  "specific_driver_config": {
    "secondary_driver_id": "valkey-glide"
  }
}

With TLS and Authentication:

{
  "schema_version": "1.0",
  "description": "Secure Lettuce client",
  "driver_id": "lettuce",
  "mode": "cluster",
  "tls": {
    "enabled": true,
    "ca_path": "/etc/ssl/certs/ca.crt"
  },
  "auth": {
    "password": "secret123"
  }
}

Workload Configuration

Schema

{
  "schema_version": "1.0",
  "benchmark_profile": {
    "name": "string",
    "description": "string",
    "version": "string"
  },
  "phases": [
    { ... }
  ]
}

Top-Level Fields

FieldTypeRequiredDescription
schema_versionstringYesSchema version, currently "1.0"
benchmark_profileobjectYesMetadata about this benchmark
phasesarrayYesList of benchmark phases

Benchmark Profile

{
  "benchmark_profile": {
    "name": "GET/SET Workload",
    "description": "Standard read-heavy workload",
    "version": "1.0.0"
  }
}
FieldTypeRequiredDescription
namestringYesName of the benchmark
descriptionstringNoDetailed description
versionstringNoVersion identifier

Phase Configuration

{
  "id": "WARMUP",
  "description": "Warmup phase",
  "connections": 10,
  "cps_limit": -1,
  "rps_limit": -1,
  "pipeline_depth": 1,
  "warmup_requests": 1,
  "completion": { ... },
  "keyspace": { ... },
  "commands": [ ... ]
}
FieldTypeRequiredDefaultDescription
idstringYes-Phase identifier (appears in output)
descriptionstringNo-Human-readable description
connectionsintegerYes-Number of client connections
cps_limitintegerNo-1Connections per second limit (-1 = unlimited)
rps_limitintegerNo-1Requests per second limit (-1 = unlimited)
pipeline_depthintegerNo1Max in-flight requests per connection
warmup_requestsintegerNo1Warmup PINGs per connection (0 = disabled)
completionobjectYes-Phase completion criteria
keyspaceobjectYes-Key generation configuration
commandsarrayYes-Commands to execute

Completion Criteria

By Request Count:

{
  "completion": {
    "type": "requests",
    "requests": 100000
  }
}

By Duration:

{
  "completion": {
    "type": "duration",
    "seconds": 60
  }
}
TypeFieldDescription
requestsrequestsStop after this many requests
durationsecondsRun for this many seconds

Keyspace Configuration

{
  "keyspace": {
    "keys_count": 10000,
    "key_size_bytes": 16,
    "key_prefix": "bench:",
    "generation_alg": "uniform_rand",
    "seed": 12345
  }
}
FieldTypeRequiredDefaultDescription
keys_countintegerYes-Total unique keys
key_size_bytesintegerNo16Target key size (excluding prefix)
key_prefixstringYes-Prefix for all keys
generation_algstringYes-Key generation algorithm
seedintegerConditional-Random seed (required for uniform_rand)

Key Generation Algorithms

AlgorithmDescriptionSeed Required
sequential_intKeys 0, 1, 2, ... N-1 (wraps)No
uniform_randUniform random distributionYes

Command Configuration

{
  "commands": [
    {"command": "get", "weight": 0.8},
    {"command": "set", "weight": 0.2, "data_size_bytes": 256}
  ]
}
FieldTypeRequiredDescription
commandstringYesCommand name
weightnumberYesSelection weight (0.0-1.0)
data_size_bytesintegerConditionalValue size for write commands

Supported Commands

CommandDescriptionRequires data_size_bytes
pingPING commandNo
getGET keyNo
setSET key valueYes
hgetHGET key fieldNo
hsetHSET key field valueYes
lpushLPUSH key valueYes
lpopLPOP keyNo
saddSADD key memberYes
smembersSMEMBERS keyNo

Note: Command availability may vary by language engine.

Complete Workload Example

{
  "schema_version": "1.0",
  "benchmark_profile": {
    "name": "Standard GET/SET Benchmark",
    "description": "Two-phase benchmark: warmup then steady-state",
    "version": "1.0.0"
  },
  "phases": [
    {
      "id": "WARMUP",
      "description": "Populate keys with sequential SET",
      "connections": 10,
      "cps_limit": -1,
      "rps_limit": -1,
      "completion": {
        "type": "requests",
        "requests": 10000
      },
      "keyspace": {
        "keys_count": 10000,
        "key_size_bytes": 16,
        "key_prefix": "bench:",
        "generation_alg": "sequential_int"
      },
      "commands": [
        {"command": "set", "weight": 1.0, "data_size_bytes": 256}
      ]
    },
    {
      "id": "STEADY",
      "description": "80/20 read/write workload",
      "connections": 50,
      "cps_limit": -1,
      "rps_limit": 10000,
      "pipeline_depth": 1,
      "completion": {
        "type": "duration",
        "seconds": 60
      },
      "keyspace": {
        "keys_count": 10000,
        "key_size_bytes": 16,
        "key_prefix": "bench:",
        "generation_alg": "uniform_rand",
        "seed": 42
      },
      "commands": [
        {"command": "get", "weight": 0.8},
        {"command": "set", "weight": 0.2, "data_size_bytes": 256}
      ]
    }
  ]
}

Metrics Output Format

All language engines produce NDJSON (one JSON object per line):

{
  "phase": {
    "id": "STEADY",
    "status": "COMPLETED",
    "start_timestamp": "2024-01-15T10:30:00.000Z",
    "finish_timestamp": "2024-01-15T10:31:00.000Z",
    "duration_ms": 60000,
    "connections": 50
  },
  "totals": {
    "requests": 600000,
    "errors": 5
  },
  "metrics": {
    "GET": {
      "requests": 480000,
      "errors": 3,
      "latency": {
        "unit": "us",
        "count": 479997,
        "summary": {
          "min": 45,
          "p50": 120,
          "p95": 250,
          "p99": 400,
          "p999": 800,
          "max": 15000
        },
        "hdr": {
          "format": "hdr",
          "sigfig": 3,
          "payload_b64": "HISTFAAAAEx..."
        }
      }
    },
    "SET": {
      "requests": 120000,
      "errors": 2,
      "latency": {
        "unit": "us",
        "count": 119998,
        "summary": {
          "min": 55,
          "p50": 140,
          "p95": 280,
          "p99": 450,
          "p999": 1000,
          "max": 18000
        },
        "hdr": {
          "format": "hdr",
          "sigfig": 3,
          "payload_b64": "HISTFAAAAEx..."
        }
      }
    }
  }
}

Metrics Fields

FieldDescription
phase.idPhase identifier from config
phase.statusCOMPLETED or ERROR
phase.start_timestampISO-8601 UTC timestamp
phase.finish_timestampISO-8601 UTC timestamp
phase.duration_msPhase duration in milliseconds
phase.connectionsNumber of connections used
totals.requestsTotal requests across all commands
totals.errorsTotal errors across all commands
metrics.<CMD>.requestsRequests for this command
metrics.<CMD>.errorsErrors for this command
metrics.<CMD>.latency.unitAlways us (microseconds)
metrics.<CMD>.latency.countSuccessful latency samples
metrics.<CMD>.latency.summaryPercentile statistics
metrics.<CMD>.latency.hdrHdrHistogram for full analysis

HdrHistogram Payload

The payload_b64 is a base64-encoded compressed HdrHistogram that can be decoded for detailed analysis:

Java:

byte[] compressed = Base64.getDecoder().decode(payload_b64);
ByteBuffer buffer = ByteBuffer.wrap(compressed);
Histogram histogram = Histogram.decodeFromCompressedByteBuffer(buffer, 0);

Python:

import base64
from hdrhistogram import HdrHistogram

data = base64.b64decode(payload_b64)
histogram = HdrHistogram.decode(data)