Datadog and New Relic are powerful, but expensive. For teams that want full-stack observability (traces, metrics, logs) without the per-seat or per-GB billing, SigNoz is the strongest open-source alternative. It’s built on ClickHouse for fast analytical queries and natively supports OpenTelemetry, so instrumentation is vendor-neutral.

This guide deploys SigNoz on Google Kubernetes Engine (GKE) using Helm, with persistent ClickHouse storage on GCP disks and an OTel Collector endpoint your applications can send telemetry to immediately.

Architecture

Your App (OTel SDK)

        ▼ gRPC :4317 / HTTP :4318
  OTel Collector  ◄── bundled inside SigNoz


  SigNoz Query Service + Frontend (:3301)


  ClickHouse (traces, metrics, logs storage)

SigNoz ships everything as a single Helm chart. ClickHouse runs as a StatefulSet inside the same namespace with a persistent volume per pod.

Prerequisites

Step 1: Create a GKE Cluster

A standard cluster with a dedicated node pool for observability workloads:

gcloud container clusters create signoz-cluster \
  --project <your-project> \
  --zone us-central1-a \
  --num-nodes 3 \
  --machine-type e2-standard-4 \
  --disk-size 50 \
  --enable-autoscaling \
  --min-nodes 2 \
  --max-nodes 6 \
  --release-channel regular

# Get credentials
gcloud container clusters get-credentials signoz-cluster \
  --zone us-central1-a \
  --project <your-project>

Node sizing: ClickHouse is memory-hungry. e2-standard-4 (4 vCPU / 16 GB) is the minimum for a comfortable production setup. Use e2-standard-8 for higher ingestion rates.

Step 2: Add the SigNoz Helm Repository

helm repo add signoz https://charts.signoz.io
helm repo update

# Confirm the chart is available
helm search repo signoz
# NAME                    CHART VERSION   APP VERSION
# signoz/signoz           0.x.x           ...

Step 3: Configure Values for GCP

Create a signoz-values.yaml to set GCP-specific storage and resource limits:

# signoz-values.yaml

global:
  storageClass: "standard-rwo"   # GCP persistent disk (ReadWriteOnce)
  cloud: gcp

clickhouse:
  replicaCount: 1                 # increase to 3 for HA
  persistence:
    enabled: true
    storageClass: "standard-rwo"
    size: 50Gi
  resources:
    requests:
      cpu: "1"
      memory: "4Gi"
    limits:
      cpu: "4"
      memory: "8Gi"

queryService:
  resources:
    requests:
      cpu: "200m"
      memory: "512Mi"
    limits:
      cpu: "1"
      memory: "1Gi"

frontend:
  resources:
    requests:
      cpu: "100m"
      memory: "128Mi"
    limits:
      cpu: "500m"
      memory: "512Mi"

otelCollector:
  resources:
    requests:
      cpu: "200m"
      memory: "256Mi"
    limits:
      cpu: "1"
      memory: "1Gi"

otelCollectorMetrics:
  resources:
    requests:
      cpu: "100m"
      memory: "128Mi"

# Expose the OTel collector endpoint as a LoadBalancer
# so applications outside GKE can send telemetry
otelCollector:
  serviceType: LoadBalancer

For internal-only access (apps on the same GKE cluster), keep serviceType: ClusterIP and use the Kubernetes service DNS name.

Step 4: Install SigNoz

kubectl create namespace monitoring

helm install signoz signoz/signoz \
  --namespace monitoring \
  --values signoz-values.yaml \
  --wait --timeout 15m

Watch the pods come up:

kubectl get pods -n monitoring -w

# Expected (all Running):
# signoz-clickhouse-0                    1/1   Running
# signoz-query-service-xxx               1/1   Running
# signoz-frontend-xxx                    1/1   Running
# signoz-otel-collector-xxx              1/1   Running
# signoz-otel-collector-metrics-xxx      1/1   Running
# signoz-alertmanager-xxx                1/1   Running

ClickHouse may take 3–5 minutes to initialise its schema on first boot. That is normal.

Step 5: Access the SigNoz UI

Port-forward locally to verify everything works before exposing publicly:

kubectl port-forward svc/signoz-frontend 3301:3301 -n monitoring

Open http://localhost:3301. You will see the SigNoz dashboard. Create your admin account on first login.

Expose via GCP Load Balancer (optional)

To make the UI accessible from a browser without port-forwarding:

kubectl patch svc signoz-frontend -n monitoring \
  -p '{"spec": {"type": "LoadBalancer"}}'

# Get the external IP (takes ~60s)
kubectl get svc signoz-frontend -n monitoring

Protect the UI with Cloud Armor or an IAP-enabled ingress before exposing it publicly.

Step 6: Get the OTel Collector Endpoint

# Internal (from within GKE)
kubectl get svc signoz-otel-collector -n monitoring

# The service name inside the cluster:
# signoz-otel-collector.monitoring.svc.cluster.local:4317 (gRPC)
# signoz-otel-collector.monitoring.svc.cluster.local:4318 (HTTP)

# External IP (if you set LoadBalancer above)
kubectl get svc signoz-otel-collector -n monitoring
# EXTERNAL-IP: 34.xx.xx.xx

Step 7: Instrument Your Application

Point your app’s OTel SDK at the collector. No code changes are needed if you already use OpenTelemetry. Just update the endpoint.

Environment variables (any language):

OTEL_EXPORTER_OTLP_ENDPOINT=http://<collector-ip>:4318
OTEL_SERVICE_NAME=my-service
OTEL_RESOURCE_ATTRIBUTES=deployment.environment=production

Python example:

from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace.export import BatchSpanProcessor

provider = TracerProvider()
exporter = OTLPSpanExporter(endpoint="http://<collector-ip>:4318/v1/traces")
provider.add_span_processor(BatchSpanProcessor(exporter))
trace.set_tracer_provider(provider)

Node.js example:

import { NodeSDK } from '@opentelemetry/sdk-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';

const sdk = new NodeSDK({
  traceExporter: new OTLPTraceExporter({
    url: 'http://<collector-ip>:4318/v1/traces',
  }),
  serviceName: 'my-service',
});
sdk.start();

Kubernetes workload (inject via env):

env:
  - name: OTEL_EXPORTER_OTLP_ENDPOINT
    value: "http://signoz-otel-collector.monitoring.svc.cluster.local:4318"
  - name: OTEL_SERVICE_NAME
    value: "my-service"
  - name: OTEL_RESOURCE_ATTRIBUTES
    value: "deployment.environment=production,team=platform"

Step 8: Send Logs via OTel Collector

To forward Kubernetes pod logs to SigNoz, deploy the OTel Collector as a DaemonSet using the filelog receiver:

# otel-logs-config.yaml
config:
  receivers:
    filelog:
      include: ["/var/log/pods/*/*/*.log"]
      include_file_path: true
      operators:
        - type: json_parser
          timestamp:
            parse_from: attributes.time
            layout: "%Y-%m-%dT%H:%M:%S.%fZ"

  exporters:
    otlp:
      endpoint: "signoz-otel-collector.monitoring.svc.cluster.local:4317"
      tls:
        insecure: true

  service:
    pipelines:
      logs:
        receivers: [filelog]
        exporters: [otlp]

Step 9: Verify Data in SigNoz

  1. Open the SigNoz UI at http://localhost:3301 (or your Load Balancer IP)
  2. Go to Services. Your instrumented services should appear within 30 seconds of sending the first trace
  3. Go to Traces. Search by service name, filter by duration or status code
  4. Go to Logs. Query by service, severity, or keyword
  5. Go to Metrics. View RED metrics (Rate, Errors, Duration) per service

Upgrading SigNoz

helm repo update
helm upgrade signoz signoz/signoz \
  --namespace monitoring \
  --values signoz-values.yaml \
  --wait

ClickHouse schema migrations run automatically on upgrade.

Cost Estimate (GCP)

For a small team (< 10 services, ~10M spans/day):

Compare to Datadog at $15 to $31 per host per month. For a 20-host environment that’s $300 to $620/month before ingestion costs.

Summary

SigNoz on GKE gives you a production-grade observability stack (traces, metrics, and logs) with no per-seat pricing and full data ownership. The setup is a one-time Helm install; after that, onboarding a new service is just pointing its OTel SDK at the collector endpoint. ClickHouse handles the heavy analytical workload efficiently, and the OTel-native design means your instrumentation works with any backend without rewrites.

Was this article helpful?

Need help setting this up for your team?

nerdSolv designs and deploys cloud-native infrastructure on Azure, AWS, and GCP.

Talk to us →