Kubernetes metrics installation
Contents
Note: Metrics is in alpha. Setup details, including the ingestion endpoint, may change before general availability.
If your Kubernetes workloads already expose Prometheus-format /metrics endpoints, the PostHog metrics agent scrapes them and forwards everything to PostHog. One helm install, no application changes.
The agent runs as a single-replica Deployment by design – two replicas would double-scrape every target and double-count all metrics.
- 1
Prerequisites
RequiredYou need:
- A running Kubernetes cluster with
helmv3 installed - Pods that expose Prometheus metrics (the standard
prometheus.io/scrape: "true"annotation pattern) - Your PostHog project token
The chart creates a ClusterRole and ClusterRoleBinding so the agent can discover pods across all namespaces. If your cluster uses strict RBAC policies, confirm you have permission to create cluster-scoped roles.
- A running Kubernetes cluster with
- 2
Get your project token
RequiredYou'll need your PostHog project token to authenticate metrics requests. This is the same token you use for capturing events with the PostHog SDK.
Important: Use your project token, which starts with
phc_. Do not use a personal API key (which starts withphx_).You can find your project token in Project Settings.
- 3
Install the Helm chart
RequiredTerminalFor EU Cloud, set the host explicitly:
TerminalIf you manage secrets separately, point the chart at an existing Kubernetes Secret containing a
posthog-api-keykey instead of passing the token directly:TerminalThe API key is stored in a Secret and injected as an environment variable – it never appears in the ConfigMap.
- 4
Configure metric discovery
RequiredAnnotation discovery (default)
By default, the agent discovers and scrapes any pod annotated with
prometheus.io/scrape: "true". Two optional annotations control the scrape target:Annotation Default Description prometheus.io/scrape– Set to "true"to opt a pod inprometheus.io/path/metricsOverride the metrics path prometheus.io/portPod's container port Override the scrape port Example pod annotation:
YAMLStatic targets
For services that don't carry Prometheus annotations, add fixed
host:porttargets:TerminalYou can combine annotation discovery with static targets. To disable annotation discovery entirely and only use static targets, set
scrape.annotationDiscovery=false.Extra scrape configs
For advanced use cases, pass raw Prometheus
scrape_configsYAML viascrape.extraScrapeConfigs. This is appended verbatim to the collector configuration. - 5
Verify metrics are flowing
Recommended- Confirm the agent pod is running:
Terminal- Open Metrics in PostHog and pick a metric from the name picker
- Data points should appear within a minute of the agent starting
If nothing shows up, check the agent logs for connection or authentication errors:
Terminal Next steps
CheckpointWhat you can do with your metricsAction Description Why you need metrics What metrics show you that events and logs don't Getting started guide Pick the right metric type, add attributes carefully, and chart what matters Group and filter Group by an attribute for one line per value, or filter with key=valuechipsHow metrics works How metrics are ingested, stored, and queried Query with SQL Every metric lands in the posthog.metricstable, queryable from the SQL tab
Configuration reference
| Value | Default | Description |
|---|---|---|
posthog.apiKey | '' | Project token (phc_...). Stored in a chart-managed Secret |
posthog.existingSecret | '' | Name of an existing Secret with a posthog-api-key key. Takes precedence over apiKey |
posthog.host | https://us.i.posthog.com | PostHog ingestion origin. Set to https://eu.i.posthog.com for EU Cloud |
scrape.interval | 15s | How often to scrape targets |
scrape.annotationDiscovery | true | Discover pods via prometheus.io/scrape annotations |
scrape.staticTargets | [] | Fixed host:port targets, e.g. ['my-svc:9090'] |
scrape.extraScrapeConfigs | '' | Raw Prometheus scrape_configs YAML appended verbatim |
resources.requests.cpu | 100m | CPU request |
resources.requests.memory | 256Mi | Memory request |
resources.limits.memory | 512Mi | Memory limit |
rbac.create | true | Create a ClusterRole for pod discovery |
serviceAccount.create | true | Create a dedicated ServiceAccount |
serviceAccount.name | '' | Override the ServiceAccount name. Required when serviceAccount.create is false |
nodeSelector | {} | Kubernetes node selector |
tolerations | [] | Kubernetes tolerations |
affinity | {} | Kubernetes affinity rules |