Basic Configuration

Sentinel uses KDL (KDL Document Language) as its primary configuration format. KDL is a human-friendly document language with a clean syntax that’s easy to read and write.

Minimal Configuration

Here’s the simplest configuration that gets Sentinel running as a reverse proxy:

server {
    worker-threads 0
}

listeners {
    listener "http" {
        address "0.0.0.0:8080"
        protocol "http"
    }
}

routes {
    route "default" {
        matches {
            path-prefix "/"
        }
        upstream "backend"
    }
}

upstreams {
    upstream "backend" {
        targets {
            target {
                address "127.0.0.1:3000"
            }
        }
    }
}

This configuration:

  • Starts Sentinel on port 8080
  • Forwards all requests to a backend service on port 3000
  • Uses automatic worker thread detection

Configuration Sections

A Sentinel configuration file consists of several top-level sections:

SectionRequiredDescription
serverYesGlobal server settings
listenersYesNetwork listeners (at least one)
routesNoRequest routing rules
upstreamsNoBackend server pools
filtersNoRequest/response processing
agentsNoExternal processor connections
limitsNoResource limits
observabilityNoMetrics, logging, and tracing

Server Configuration

The server block controls global behavior:

server {
    worker-threads 4              // 0 = auto-detect CPU cores
    max-connections 10000         // Total connection limit
    graceful-shutdown-timeout-secs 30
}

Server Options

OptionDefaultDescription
worker-threads0Number of worker threads (0 = auto)
max-connections10000Maximum concurrent connections
graceful-shutdown-timeout-secs30Seconds to wait for connections to drain
daemonfalseRun as a background daemon
pid-file-Path to PID file
auto-reloadfalseReload config on file changes

Listeners

Listeners define how Sentinel accepts incoming connections:

listeners {
    listener "http" {
        address "0.0.0.0:8080"
        protocol "http"
        request-timeout-secs 60
        keepalive-timeout-secs 75
    }
}

Listener Options

OptionDefaultDescription
address-Socket address (required)
protocol-http, https, h2, or h3
request-timeout-secs60Request timeout
keepalive-timeout-secs75Keep-alive timeout
default-route-Fallback route if no match

HTTPS Listener

For TLS, add a tls block:

listeners {
    listener "https" {
        address "0.0.0.0:443"
        protocol "https"

        tls {
            cert-file "/etc/sentinel/certs/server.crt"
            key-file "/etc/sentinel/certs/server.key"
            min-version "TLS1.2"
        }
    }
}

Routes

Routes match incoming requests and direct them to upstreams:

routes {
    route "api" {
        priority "high"

        matches {
            path-prefix "/api/"
            method "GET" "POST" "PUT" "DELETE"
        }

        upstream "api-backend"
        service-type "api"
    }

    route "static" {
        priority "normal"

        matches {
            path-prefix "/static/"
        }

        service-type "static"
        static-files {
            root "/var/www/static"
            compress true
        }
    }
}

Match Conditions

ConditionExampleDescription
path-prefix"/api/"URL path prefix
path"/health"Exact path match
path-regex"^/v[0-9]+/"Regex path match
host"api.example.com"Host header
method"GET" "POST"HTTP methods
header"Authorization" "Bearer *"Header match
query-param"key" "value"Query parameter

Service Types

TypeDescription
webTraditional web service (default)
apiREST API with JSON error responses
staticStatic file serving
builtinBuilt-in handlers (health, metrics)

Upstreams

Upstreams define backend server pools:

upstreams {
    upstream "backend" {
        targets {
            target {
                address "10.0.1.10:8080"
                weight 3
            }
            target {
                address "10.0.1.11:8080"
                weight 1
            }
        }

        load-balancing "round_robin"

        health-check {
            type "http" {
                path "/health"
                expected-status 200
            }
            interval-secs 10
            timeout-secs 5
            healthy-threshold 2
            unhealthy-threshold 3
        }
    }
}

Load Balancing Algorithms

AlgorithmDescription
round_robinSequential distribution (default)
least_connectionsFewest active connections
ip_hashClient IP sticky sessions
consistent_hashConsistent hashing
p2cPower of Two Choices

Resource Limits

Control resource usage with the limits block:

limits {
    max-header-size-bytes 8192
    max-header-count 100
    max-body-size-bytes 10485760    // 10MB
    max-connections-per-client 100
}

Observability

Enable metrics and logging:

observability {
    metrics {
        enabled true
        address "0.0.0.0:9090"
        path "/metrics"
    }

    logging {
        level "info"           // trace, debug, info, warn, error
        format "json"          // json or pretty
    }
}

Complete Example

Here’s a production-ready configuration:

server {
    worker-threads 0
    max-connections 10000
    graceful-shutdown-timeout-secs 30
}

listeners {
    listener "http" {
        address "0.0.0.0:8080"
        protocol "http"
        request-timeout-secs 60
    }
}

routes {
    route "api" {
        priority "high"
        matches {
            path-prefix "/api/"
        }
        upstream "api-backend"
        service-type "api"
        policies {
            timeout-secs 30
        }
    }

    route "default" {
        priority "low"
        matches {
            path-prefix "/"
        }
        upstream "web-backend"
    }
}

upstreams {
    upstream "api-backend" {
        targets {
            target { address "127.0.0.1:3000" }
        }
        load-balancing "round_robin"
        health-check {
            type "http" {
                path "/health"
            }
            interval-secs 10
        }
    }

    upstream "web-backend" {
        targets {
            target { address "127.0.0.1:3001" }
        }
    }
}

limits {
    max-header-size-bytes 8192
    max-body-size-bytes 10485760
}

observability {
    metrics {
        enabled true
        address "0.0.0.0:9090"
    }
    logging {
        level "info"
        format "json"
    }
}

Next Steps