Operations¶
Deployment, configuration, scaling, and day-2 operations for OpenObserve.
Deployment¶
Single-Node (Docker)¶
docker run -d --name openobserve \
-p 5080:5080 \
-e ZO_ROOT_USER_EMAIL=[email protected] \
-e ZO_ROOT_USER_PASSWORD=ComplexPass#123 \
-e ZO_LOCAL_MODE=true \
-v $PWD/data:/data \
openobserve/openobserve:latest
# UI: http://localhost:5080
Kubernetes (Helm) — HA Mode¶
helm repo add openobserve https://charts.openobserve.ai
helm repo update
helm install openobserve openobserve/openobserve \
-n openobserve --create-namespace \
-f values.yaml
Kubernetes Operator¶
The OpenObserve Operator provides a declarative, GitOps-ready approach:
apiVersion: openobserve.ai/v1
kind: OpenObserve
metadata:
name: my-o2
spec:
ingester:
replicas: 3
querier:
replicas: 2
compactor:
replicas: 1
storage:
type: s3
bucket: my-o2-data
Configuration¶
Key Environment Variables¶
| Variable | Default | Description |
|---|---|---|
ZO_ROOT_USER_EMAIL |
— | Initial admin email |
ZO_ROOT_USER_PASSWORD |
— | Initial admin password |
ZO_LOCAL_MODE |
false |
Single-node local storage mode |
ZO_NODE_ROLE |
all |
Node role (router/ingester/querier/compactor/alertmanager) |
ZO_NODE_ROLE_GROUP |
default |
Workload separation group |
ZO_S3_BUCKET_NAME |
— | Object storage bucket |
ZO_S3_REGION_NAME |
— | S3 region |
ZO_META_STORE |
sqlite |
Metadata store (sqlite/postgresql) |
ZO_INGEST_FLATTEN_LEVEL |
3 |
JSON nesting depth to flatten |
ZO_WAL_MAX_FILE_SIZE |
256MB |
WAL file size before flush |
ZO_COMPACT_ENABLED |
true |
Enable background compaction |
Production Configuration (HA)¶
# values.yaml for Helm HA deployment
ingester:
replicas: 3
resources:
requests:
cpu: "2"
memory: "4Gi"
env:
ZO_NODE_ROLE: ingester
ZO_WAL_MAX_FILE_SIZE: "512MB"
querier:
replicas: 2
resources:
requests:
cpu: "4"
memory: "8Gi"
env:
ZO_NODE_ROLE: querier
ZO_DISK_CACHE_ENABLED: "true"
ZO_DISK_CACHE_MAX_SIZE: "50GB"
compactor:
replicas: 1
env:
ZO_NODE_ROLE: compactor
storage:
type: s3
s3:
bucket: openobserve-data
region: us-east-1
meta:
store: postgresql
postgresql:
host: pg.example.com
database: openobserve
Scaling¶
Horizontal Scaling¶
| Component | Scale Strategy |
|---|---|
| Ingester | Add replicas for write throughput |
| Querier | Add replicas for concurrent queries |
| Compactor | Usually 1-2 (background process) |
| Router | Add replicas behind LB |
Performance Tuning¶
| Tuning Target | Environment Variable | Guidance |
|---|---|---|
| Write throughput | ZO_WAL_MAX_FILE_SIZE |
Increase for larger batches |
| Query speed | ZO_DISK_CACHE_ENABLED |
Enable on querier nodes |
| Nested JSON | ZO_INGEST_FLATTEN_LEVEL |
Reduce for deep nesting |
| Bloom filters | Per-field config | Enable for high-cardinality fields |
Monitoring¶
# Health check
curl http://localhost:5080/healthz
# API status
curl http://localhost:5080/api/default/status
# Kubernetes pods
kubectl get pods -n openobserve
O2 CLI (Enterprise)¶
The o2 CLI is available for Enterprise edition:
# Configure profile
o2 configure --profile prod
# List organizations
o2 org list --profile prod
# Export dashboards
o2 dashboard export --org default --profile prod
# Import alerts
o2 alert import --org default --file alerts.json --profile prod
Upgrades¶
# Docker
docker pull public.ecr.aws/zinclabs/openobserve:latest
docker compose up -d
# Helm
helm repo update openobserve
helm upgrade openobserve openobserve/openobserve -n openobserve -f values.yaml
Sources¶
Commands & Recipes¶
Runnable commands, configuration snippets, and troubleshooting recipes for OpenObserve.
Installation¶
Docker (Single Node)¶
docker run -d --name openobserve \
-p 5080:5080 \
-e ZO_ROOT_USER_EMAIL=[email protected] \
-e ZO_ROOT_USER_PASSWORD=ComplexPass#123 \
-e ZO_LOCAL_MODE=true \
-v $PWD/data:/data \
openobserve/openobserve:latest
Docker Compose¶
version: '3'
services:
openobserve:
image: openobserve/openobserve:latest
ports:
- "5080:5080"
environment:
ZO_ROOT_USER_EMAIL: [email protected]
ZO_ROOT_USER_PASSWORD: ComplexPass#123
ZO_LOCAL_MODE: "true"
volumes:
- o2data:/data
volumes:
o2data:
Helm (Kubernetes HA)¶
helm repo add openobserve https://charts.openobserve.ai
helm repo update
helm install openobserve openobserve/openobserve \
-n openobserve --create-namespace \
-f values.yaml
Data Ingestion¶
Send Logs via curl¶
# JSON log ingestion
curl -u [email protected]:ComplexPass#123 \
-X POST http://localhost:5080/api/default/mystream/_json \
-H "Content-Type: application/json" \
-d '[{"level":"info","message":"Hello from curl","ts":"2026-04-11T00:00:00Z"}]'
Send Logs via Elasticsearch Bulk API¶
# ES Bulk compatible endpoint
curl -u [email protected]:ComplexPass#123 \
-X POST "http://localhost:5080/es/default/mystream/_bulk" \
-H "Content-Type: application/x-ndjson" \
--data-binary @logs.ndjson
OTel Collector Config¶
exporters:
otlphttp:
endpoint: http://openobserve:5080/api/default
headers:
Authorization: "Basic <base64(email:password)>"
stream-name: otel-logs
service:
pipelines:
logs:
receivers: [otlp]
exporters: [otlphttp]
Query Examples¶
SQL Queries (Logs)¶
-- Search for errors in last 1 hour
SELECT * FROM logs
WHERE body LIKE '%error%'
AND _timestamp >= NOW() - INTERVAL '1 hour'
ORDER BY _timestamp DESC
LIMIT 100;
-- Top error messages
SELECT body, count(*) as cnt
FROM logs
WHERE severity_text = 'ERROR'
AND _timestamp >= NOW() - INTERVAL '24 hours'
GROUP BY body
ORDER BY cnt DESC
LIMIT 20;
-- Log volume by stream
SELECT stream_name, count(*) as cnt,
pg_size_pretty(sum(length(body))) as total_size
FROM logs
WHERE _timestamp >= NOW() - INTERVAL '1 hour'
GROUP BY stream_name;
Operational Recipes¶
Health Check¶
Check Storage Usage¶
curl -u [email protected]:ComplexPass#123 \
http://localhost:5080/api/default/streams
Kubernetes Operations¶
# Check pods
kubectl get pods -n openobserve
# View ingester logs
kubectl logs -n openobserve -l role=ingester --tail=50
# View querier logs
kubectl logs -n openobserve -l role=querier --tail=50
# Restart ingesters
kubectl rollout restart statefulset openobserve-ingester -n openobserve
Upgrade¶
# Docker
docker pull public.ecr.aws/zinclabs/openobserve:latest
docker stop openobserve && docker rm openobserve
# Re-run docker run command with same volumes
# Helm
helm repo update openobserve
helm upgrade openobserve openobserve/openobserve -n openobserve -f values.yaml