redis/redis · critical

FATAL: Failed to start thread %d.

Error message

FATAL: Failed to start thread %d.

What it means

startBenchmarkThreads calls pthread_create for worker i; if it returns non-zero the benchmark prints 'FATAL: Failed to start thread %d.' and exit(1). The OS refused to spawn another thread.

Source

Thrown at src/redis-benchmark.c:951

    }
}

static void initBenchmarkThreads(void) {
    int i;
    if (config.threads) freeBenchmarkThreads();
    config.threads = zmalloc(config.num_threads * sizeof(benchmarkThread*));
    for (i = 0; i < config.num_threads; i++) {
        benchmarkThread *thread = createBenchmarkThread(i);
        config.threads[i] = thread;
    }
}

static void startBenchmarkThreads(void) {
    int i;
    for (i = 0; i < config.num_threads; i++) {
        benchmarkThread *t = config.threads[i];
        if (pthread_create(&(t->thread), NULL, execBenchmarkThread, t)){
            fprintf(stderr, "FATAL: Failed to start thread %d.\n", i);
            exit(1);
        }
    }
    for (i = 0; i < config.num_threads; i++)
        pthread_join(config.threads[i]->thread, NULL);
}

static void benchmark(const char *title, char *cmd, int len) {
    client c;

    config.title = title;
    config.requests_issued = 0;
    config.requests_finished = 0;
    config.previous_requests_finished = 0;
    config.last_printed_bytes = 0;
    hdr_init(
        CONFIG_LATENCY_HISTOGRAM_MIN_VALUE,  // Minimum value
        CONFIG_LATENCY_HISTOGRAM_MAX_VALUE,  // Maximum value

View on GitHub (pinned to 4f20cb4893)

Solutions

  1. Lower --threads (start with 1-4 per CPU core)
  2. Raise the limit: ulimit -u unlimited (or nproc in systemd unit)
  3. For containers, raise pids.max (docker --pids-limit) and check kernel.threads-max
  4. Check dmesg for 'cgroup out of memory' or pthread EAGAIN reports

Example fix

// before
redis-benchmark --threads 500 -c 500 -n 1000000
// after
ulimit -u
ulimit -u 65536
redis-benchmark --threads 8 -c 50 -n 1000000
Defensive patterns

Strategy: validation

Validate before calling

# Pre-flight: ensure we can spawn the requested thread count
ulimit -u                     # RLIMIT_NPROC
[ "$(ulimit -u)" -ge $((THREADS * 4)) ] || { echo 'raise ulimit -u' >&2; exit 1; }
# Container check
grep -E 'pids\.max|^pids' /sys/fs/cgroup/pids.max 2>/dev/null || true

Try / catch

# Cannot recover inside the tool (it exits); catch at the shell and retry with fewer threads
if ! redis-benchmark --threads "$THREADS" -c "$C" -n "$N"; then
  echo "thread spawn failed; retrying with fewer threads" >&2
  THREADS=$(( THREADS / 2 ))
  redis-benchmark --threads "$THREADS" -c "$C" -n "$N"
fi

Prevention

When it happens

Trigger: pthread_create(&(t->thread), NULL, execBenchmarkThread, t) returns non-zero at src/redis-benchmark.c:950. Caused by EAGAIN (RLIMIT_NPROC / kernel.threads-max / cgroup pid limit hit) or ENOMEM (stack allocation failure).

Common situations: --threads set very high, low ulimit -u in the shell, container with a small pids limit, very large -c combined with --threads so per-thread client count explodes, memory pressure preventing stack allocation.

Related errors


AI-assisted analysis of redis/redis@4f20cb4893 (2026-08-10). Data as JSON: /api/errors/ac54682e7d27d59e. Report an issue: GitHub.