Configuration
Korrel8r loads configuration from a file or URL specified by the --config option or the KORREL8R_CONFIG environment variable.
korrel8r --config <file_or_url>Built-in configuration
The released korrel8r container image includes default configuration at /etc/korrel8r/,
mirroring the etc/korrel8r/ directory in the source repository:
/etc/korrel8r/
├── openshift-route.yaml # Out-of-cluster: connect to stores via OpenShift routes
├── openshift-svc.yaml # In-cluster: connect to stores via service URLs
└── rules/
└── all.yaml # Placeholder for additional rulesKorrel8r’s built-in correlation and status rules are compiled into the executable from
pkg/rules/quickrules/; they do not need to be included from configuration.
- openshift-route.yaml
- Run korrel8r outside the cluster, connect to stores via routes.
- openshift-svc.yaml
- Run korrel8r as an in-cluster service, connect to stores via service URLs.
The default deployment uses --config=/etc/korrel8r/openshift-svc.yaml.
Custom configuration
Pass a local file or URL to --config, or set KORREL8R_CONFIG. For an in-cluster deployment,
store custom configuration in a ConfigMap and mount it below /etc/korrel8r without replacing
that directory. See Configuring Stores
for a complete deployment example.
Custom rules can be defined directly or loaded with include. They supplement the compiled
built-in rules; configuration does not select or disable built-in quickrules.
The configuration file supports the following sections:
include
Other configuration fragments to include:
include:
- "path_or_url"stores
Connections to data stores:
stores:
- domain: "domain_name" # 1. Domain name of the store (required)
# Domain-specific fields # 2. See Domain ReferenceEvery entry in the stores section has a domain field to identify the domain.
Other fields depend on the domain, see the Domain Reference.
Store fields may contain templates that expand to URLs.
Example: configuring a store URL from an OpenShift Route resource:
stores:
- domain: log
lokiStack: >-
{{$r := query "k8s:Route.route.openshift.io/v1:{namespace: openshift-logging, name: logging-loki}" -}}
https://{{ (first $r).Spec.Host -}}- Get a list of routes in “openshift-logging” named “logging-loki”.
- Use the
.Spec.Hostfield of the first route as the host for the store URL.
rules
Runtime correlation rules use Go templates to turn start objects into goal queries. See Configuration Rules for the complete schema, examples, and template behavior. Built-in rules are compiled into the executable; this section is for additional user-defined rules.
statusRules
Rules that generate status for objects in a correlation graph:
statusRules:
- name: "rule_name" # 1. Identifies the rule in log output
start: # 2. Start objects must belong to one of these classes
domain: "domain_name"
classes: # Optional — omit for all classes in the domain
- "class_name"
status: "status_template" # 3. Go template that outputs labels, one per lineSee Status for details and examples.
aliases
Short-hand alias names for groups of classes:
aliases:
- name: "alias_name" # 1. Can be used wherever a class name is allowed
domain: "domain_name" # 2. Domain for classes in this alias
classes: # 3. Classes belonging to this alias
- "class_name"templates
Named templates that can be reused from rule, status, or store templates:
templates:
- name: "template_name" # 1. Name used to invoke the template
template: "template_body" # 2. Go template bodyNamed templates are invoked from rule or status templates using the standard Go template syntax:
{{template "template_name" <data>}}The <data> expression becomes . inside the named template.
Use the sprig dict function to pass named parameters:
templates:
- name: myHelper
template: 'k8s:{{.class}}:{"namespace":"{{index .labels "namespace"}}"}'
rules:
- name: MyRule
start: {domain: alert}
goal: {domain: k8s, classes: [Pod]}
result:
query: '{{template "myHelper" (dict "labels" .Labels "class" "Pod")}}'Named templates defined in any configuration file (including included files) are available to all rules across all files.
tuning
Limits and optimizations:
tuning:
totalLimit: 10000 # 1. Unique result objects retained per traversal
totalQueryLimit: 5000 # 2. Unique queries accepted per traversal
# memoryLimit: 768Mi # 3. Optional absolute memory-pressure override
memoryPressureLimit: 80 # 4. Cancel searches at this percentage of available memory
memoryPressureReset: 70 # 5. Clear memory pressure below this percentage
requestTimeout: 1m # Timeout for incoming and outgoing requests
sessionTimeout: 5m # Idle timeout for per-user sessions
storeRetryInterval: 10s # Minimum time between store re-creation attemptsDurations use Go duration syntax, for example 30s, 1m, 2h.
totalLimit- Maximum number of unique result objects retained across a traversal. This complements the
per-query
limit. A request may specify a lowertotalLimit, but cannot raise this server limit. If omitted or 0, there is no traversal-wide object limit. totalQueryLimit- Maximum number of unique queries accepted across a traversal. This complements the per-class
queryLimit. A request may specify a lowertotalQueryLimit, but cannot raise this server limit. If omitted or 0, there is no traversal-wide query limit.
When either total limit is exceeded, traversal stops and returns a successful partial graph.
REST and MCP graph responses include truncation metadata naming the exhausted condition and
its effective limit. REST responses also include X-Korrel8r-Truncated,
X-Korrel8r-Truncated-By, and X-Korrel8r-Truncated-Limit headers.
requestTimeout- Cancels incoming or outgoing requests that take longer than this. Long-lived SSE subscriptions are exempt. If omitted or 0, requests never time out.
memoryPressureLimit- Cancels active searches when process cgroup or Go runtime memory reaches this percentage of its
finite limit, whichever is under greater pressure.
Searches are still admitted, but are canceled immediately while pressure remains high. Cancellation
returns a successful partial graph with truncation condition
memoryPressure. Defaults to80. memoryLimit- Overrides percentage-based detection with an absolute byte quantity such as
768Mi. The guard still uses cgroup usage when available and Go runtime usage otherwise. Set to-1to disable the guard. memoryPressureReset- Clears memory pressure at this lower percentage, providing hysteresis. It must be lower than
memoryPressureLimit. If omitted, it defaults to 10 percentage points below the limit.
Memory is sampled every 200ms, with the first sample occurring immediately.
Set Go’s GOMEMLIMIT below the container memory limit as an additional safeguard. The guard monitors
it when finite, but it remains a soft garbage-collection target rather than an OOM cap.
Library embedders can create the same guard with memory.NewFromTuning, run it with an
application-lifetime context, and install it using engine.Builder.SearchGuard.
sessionTimeout- Idle timeout for sessions. In server mode each authenticated user gets a session with its own engine, configuration and state – see Security. If omitted or 0, sessions never time out.
storeRetryInterval- Minimum time between attempts to re-create a store after an error.
Prevents a storm of expensive re-creation (DNS lookups, API discovery) on every failed query.
Defaults to
10sif omitted or 0. unsafeSharedSession- Skips authentication and uses a single shared session for all requests.
This disables per-user session isolation. Use only for development or testing.
Sizing the total limits for a memory limit
As a starting point, for a container memory limit M and at most N concurrent traversals:
totalLimit = (0.8 × M - 95MiB) / (N × 11KiB)
totalQueryLimit = totalLimit / 10| Memory limit | Concurrency | totalLimit |
totalQueryLimit |
|---|---|---|---|
| 256 MiB | 1 | 10000 | 1000 |
| 512 MiB | 1 | 29000 | 2900 |
| 512 MiB | 2 | 14000 | 1400 |
| 1 GiB | 1 | 67000 | 6700 |
| 2 GiB | 1 | 143000 | 14000 |
The 95MiB term is the baseline server footprint before any traversal state, and the 11KiB term is the measured peak RSS per retained object; both come from OpenShift Kubernetes and log workloads with a single session. A server with many concurrent user sessions holds one engine per session, so measure your own baseline in that case. These are sizing heuristics, not memory guarantees: verify peak container memory with your own workloads and re-check after changing stores, rules, or payload sizes.
About Templates
Korrel8r rules and store configuration can include Go templates. Korrel8r provides additional template functions, domains may provide additional functions – see the Domain Reference