Configuration

June 3, 2026 · View on GitHub

A Pingora configuration file is a list of Pingora settings in yaml format.

Example

---
version: 1
threads: 2
pid_file: /run/pingora.pid
upgrade_sock: /tmp/pingora_upgrade.sock
user: nobody
group: webusers

Settings

Keymeaningvalue type
versionthe version of the conf, currently it is a constant 1number
pid_fileThe path to the pid filestring
daemonwhether to run the server in the backgroundbool
error_logthe path to error log output file. STDERR is used if not setstring
upgrade_sockthe path to the upgrade socket.string
threadsnumber of threads per servicenumber
userthe user the pingora server should be run under after daemonizationstring
groupthe group the pingora server should be run under after daemonizationstring
working_directorythe working directory for the daemonized processstring
client_bind_to_ipv4source IPv4 addresses to bind to when connecting to serverlist of string
client_bind_to_ipv6source IPv6 addresses to bind to when connecting to serverlist of string
ca_fileThe path to the root CA filestring
s2n_config_cache_sizeThe maximum number of unique s2n configs to cache. A value of 0 disables the cache. Default: 10 (s2n-tls only)number
work_stealingEnable work stealing runtime (default true). See Pingora runtime (WIP) section for more infobool
runtime_enable_alt_timerEnable Tokio's experimental alternative timer on work-stealing service runtimes. Requires building with --cfg tokio_unstable. Ignored when work_stealing is disabled. Default: falsebool
fast_timeout_to_tokio_threshold_secondsTimeout durations greater than this value use Tokio's native timeout instead of Pingora's fast timeout. Default: 900. Set to null to disable the Tokio fallback.number
runtime_metrics_poll_time_histogramEnable Tokio poll-time histograms on service runtimes. Requires building with --cfg tokio_unstable; adds two timestamp reads to every task poll. Default: falsebool
runtime_metrics_poll_time_histogram_scaleBucket scale for Tokio poll-time histograms. Valid values: linear, log. Ignored unless runtime_metrics_poll_time_histogram is enabled.string
runtime_metrics_poll_time_histogram_resolution_microsWidth of the first Tokio poll-time histogram bucket in microseconds. Must be greater than 0. Ignored unless runtime_metrics_poll_time_histogram is enabled.number
runtime_metrics_poll_time_histogram_bucketsNumber of Tokio poll-time histogram buckets. Must be greater than 0 and at most 1024. Memory usage scales with runtimes × workers × buckets. Ignored unless runtime_metrics_poll_time_histogram is enabled.number
upstream_keepalive_pool_sizeThe number of idle upstream connections to keep per tokio worker. The pool's effective ceiling is upstream_keepalive_pool_size × threads. Eviction is globally consistent across workers.number
daemon_wait_for_readyWhen true and daemon is true, the parent process waits for the daemon to signal readiness (via SIGUSR1) before exiting. This causes systemd to delay sending SIGQUIT to the old process until the new instance is fully bootstrapped. Default: falsebool
daemon_ready_timeout_secondsHow long (in seconds) the parent waits for the daemon to signal readiness when daemon_wait_for_ready is true. If the daemon does not signal in time the parent exits with a non-zero code, causing systemd to abort the reload. Default: 600number
daemon_notify_timeout_secondsHow long (in seconds) the daemon retries sending SIGUSR1 to the parent when the attempt fails with a permission error. This covers the brief window after the fork where the parent has not yet dropped its UID to match the daemon. Default: 60number

dial9

dial9 Tokio runtime telemetry is configured programmatically, not through the YAML configuration file. This avoids applying experimental telemetry to every service runtime and lets services provide non-serializable options such as a pre-built S3 client.

dial9 is only available when Pingora is built with the dial9 feature and --cfg tokio_unstable. Services can override the global runtime options with runtime_opts_override():

use pingora::server::{Dial9RuntimeOpts, RuntimeOpts};
use pingora::services::Service;

struct MyService;

impl Service for MyService {
    fn name(&self) -> &str {
        "my-service"
    }

    fn runtime_opts_override(&self, global: &RuntimeOpts) -> Option<RuntimeOpts> {
        let mut opts = global.clone();
        opts.dial9 = Some(
            Dial9RuntimeOpts::new("/var/lib/pingora/dial9/my-service/trace.bin")
                .with_max_file_size(100 * 1024 * 1024)
                .with_max_total_size(512 * 1024 * 1024),
        );
        Some(opts)
    }
}

When built with the dial9-worker-s3 feature, sealed trace segments can also be uploaded to an S3-compatible bucket:

use pingora::server::{Dial9RuntimeOpts, Dial9S3UploadOpts, RuntimeOpts};
use pingora::services::Service;

struct MyService {
    s3_client: aws_sdk_s3::Client,
}

impl Service for MyService {
    fn name(&self) -> &str {
        "my-service"
    }

    fn runtime_opts_override(&self, global: &RuntimeOpts) -> Option<RuntimeOpts> {
        let mut opts = global.clone();
        opts.dial9 = Some(
            Dial9RuntimeOpts::new("/var/lib/pingora/dial9/my-service/trace.bin")
                .with_s3_upload(
                    Dial9S3UploadOpts::new("my-trace-bucket", "my-service")
                        .with_prefix("traces/my-service")
                        .with_region("us-east-1")
                        .with_client(self.s3_client.clone()),
                ),
        );
        Some(opts)
    }
}

The S3 client is optional. When omitted, dial9 uses the AWS SDK default configuration chain and its bucket-region detection.

Extension

Any unknown settings will be ignored. This allows extending the conf file to add and pass user defined settings. See User defined configuration section.