Skip to content

Architecture

1. Default Topology / Flow

flowchart TB
    subgraph Sources["Data Sources"]
        APP["Application\n+ OTel SDK"]
        PROM["Prometheus\nTargets"]
        LEGACY["Jaeger /\nZipkin Clients"]
        FB["FluentBit /\nFluentD"]
        RUM["Browser\n(RUM SDK)"]
    end

    subgraph CollectorFleet["OTel Collector Fleet"]
        direction TB
        GW["Gateway Collectors\n(load-balanced)"]
        AGT["Agent Collectors\n(DaemonSet, optional)"]
    end

    subgraph Backend["SigNoz Backend"]
        direction TB
        QS["Query Service\n(Go API)"]
        Rule["Ruler +\nAlertmanager"]
        OpAMP["OpAMP Server\n(dynamic config)"]
        EE["Enterprise Extensions\n(SSO, RBAC, SAML)"]
        FE["React Frontend\n(SPA)"]
    end

    subgraph CHCluster["ClickHouse Cluster"]
        direction TB
        Shard1["Shard 1\n(Replica A + B)"]
        Shard2["Shard 2\n(Replica A + B)"]
        ZK["ZooKeeper /\nClickHouse Keeper"]

        subgraph Tables["Core Tables"]
            T_Traces["signoz_traces\n.signoz_index_v2"]
            T_Logs["signoz_logs\n.logs"]
            T_Metrics["signoz_metrics\n.samples_v4"]
        end
    end

    subgraph Meta["Metadata"]
        PG["PostgreSQL\n(metadata, auth)"]
    end

    Sources --> CollectorFleet
    GW -->|"ClickHouse\nexporter"| CHCluster
    AGT -->|"forward"| GW
    QS -->|"query"| CHCluster
    Rule -->|"eval"| CHCluster
    QS --> FE
    QS --> PG
    OpAMP -.->|"reconfigure"| CollectorFleet

    style Backend fill:#7b1fa2,color:#fff
    style CHCluster fill:#1565c0,color:#fff

Component breakdown, deployment topologies, and data flow for SigNoz.

System Architecture

Component Responsibility Matrix

Component Language Role Scales Via
OTel Collector (Gateway) Go Ingestion, processing, routing Horizontal (replicas behind LB)
OTel Collector (Agent) Go Per-node collection, forwarding DaemonSet (1 per node)
Query Service Go API layer, ClickHouse queries Horizontal (stateless)
Ruler / Alertmanager Go Alert evaluation, notifications Single leader
OpAMP Server Go Dynamic collector reconfiguration Single instance
React Frontend TypeScript UI, dashboards, query builder Static assets (CDN/replicas)
ClickHouse C++ Columnar storage for all signals Sharding + replication
ZooKeeper / Keeper Java/C++ ClickHouse coordination 3-node ensemble
PostgreSQL C Metadata, user auth, settings Standard HA (for example, RDS)

Deployment Topologies

Small (< 50 GB/day)

flowchart LR
    OTel["OTel Collector\n(single)"]
    QS["Query Service"]
    FE["Frontend"]
    CH["ClickHouse\n(single node)"]
    PG["PostgreSQL"]

    OTel --> CH
    QS --> CH
    QS --> PG
    QS --> FE

Production (50–200 GB/day)

flowchart LR
    subgraph Collectors["Collector Fleet"]
        C1["Collector 1"]
        C2["Collector 2"]
        C3["Collector 3"]
    end

    LB["Load Balancer"]
    subgraph QSPool["Query Service Pool"]
        QS1["QS 1"]
        QS2["QS 2"]
    end

    subgraph CHCluster["ClickHouse (2×2)"]
        S1R1["Shard1 Rep1"]
        S1R2["Shard1 Rep2"]
        S2R1["Shard2 Rep1"]
        S2R2["Shard2 Rep2"]
    end

    Collectors --> LB --> CHCluster
    QSPool --> CHCluster

ClickHouse Storage Schema Detail

Trace Index Table

Column Type Purpose
timestamp DateTime64(9) Nanosecond precision timestamp
traceID FixedString(32) 128-bit trace identifier
spanID String Span identifier
parentSpanID String Parent span link
serviceName LowCardinality(String) Service name
name LowCardinality(String) Operation name
kind Int8 Span kind (server/client and more)
durationNano UInt64 Span duration
statusCode Int16 Status code
httpMethod LowCardinality(String) HTTP method
httpRoute LowCardinality(String) HTTP route
resourceAttributes Map(String, String) Resource attributes

Log Table

Column Type Purpose
timestamp UInt64 Unix nanoseconds
body String Log message body
severityText LowCardinality(String) ERROR, WARN, INFO, and more
severityNumber UInt8 Numeric severity
traceID String Correlation to traces
spanID String Correlation to spans
resourceAttributes Map(String, String) Resource context
logAttributes Map(String, String) Log-specific attributes

Sources

Data Model

1. Default Topology / Flow

erDiagram
    Signoz_CORE ||--o{ CONFIG : requires
    Signoz_CORE ||--o{ STATE : writes
    CONFIG {
        string runtime_params
        string limits
    }
    STATE {
        string metric_id
        json payload
    }

How It Works

How SigNoz processes telemetry through its OTel-native pipeline, stores data in ClickHouse, and provides unified observability.

Data Pipeline

Ingestion Flow

flowchart LR
    subgraph Sources["Data Sources"]
        APP["App + OTel SDK"]
        PROM["Prometheus"]
        JAEG["Jaeger / Zipkin"]
        FB["FluentBit / FluentD"]
    end

    subgraph Collector["SigNoz OTel Collector"]
        Recv["Receivers\n(OTLP, Jaeger, Zipkin,\nPrometheus)"]
        Proc["Processors\n(batch, memory_limiter,\nattribute, tail_sampling)"]
        Exp["Exporters\n(ClickHouse)"]
    end

    subgraph Backend["SigNoz Backend"]
        QS["Query Service\n(Go API)"]
        FE["React Frontend"]
        Rule["Ruler /\nAlertmanager"]
        OpAMP["OpAMP Server\n(dynamic config)"]
    end

    subgraph CH["ClickHouse Cluster"]
        T["signoz_traces"]
        L["signoz_logs"]
        M["signoz_metrics"]
    end

    Sources --> Recv --> Proc --> Exp --> CH
    QS --> CH
    Rule --> CH
    QS --> FE
    OpAMP -.->|reconfigure| Collector

OTel Collector Distribution

SigNoz ships a custom OpenTelemetry Collector distribution that includes:

Component Purpose
OTLP Receiver Primary ingestion (gRPC + HTTP)
Prometheus Receiver Scrape Prometheus targets
Jaeger/Zipkin Receiver Legacy trace format support
FluentForward Receiver FluentBit/FluentD log ingestion
Batch Processor Batches data for efficient ClickHouse writes
Memory Limiter Prevents OOM under load
Tail Sampling Sample traces based on latency/error criteria
ClickHouse Exporter Writes all signals to ClickHouse

OpAMP (Open Agent Management Protocol)

SigNoz uses OpAMP for dynamic reconfiguration of the OTel Collector:

  • Log pipelines: Add/modify log processing rules without collector restart
  • Sampling rules: Adjust tail sampling dynamically
  • Collector health: Monitor collector instances from the SigNoz UI

Storage Schema (ClickHouse)

Traces

-- signoz_traces.signoz_index_v2
-- Core trace/span index with columnar storage
-- Columns: traceID, spanID, serviceName, name, kind, durationNano,
--          statusCode, httpMethod, httpRoute, resourceAttributes, ...
-- Engine: MergeTree, partitioned by toDate(timestamp)
-- TTL: Configurable (default 7 days self-hosted, 15 days cloud)

Logs

-- signoz_logs.logs
-- Columnar log storage with full-text indexing
-- Columns: timestamp, body, severityText, severityNumber,
--          traceID, spanID, resourceAttributes, logAttributes
-- Engine: MergeTree, partitioned by toDate(timestamp)
-- Supports: JSON expansion, attribute indexing

Metrics

-- signoz_metrics.samples_v4
-- Time-series samples with metric metadata
-- Columns: metric_name, fingerprint, timestamp_ms, value,
--          labels (Map), temporality, type
-- Engine: MergeTree, partitioned by toDate(timestamp_ms)
-- Query: PromQL translated to ClickHouse SQL

Query Execution

Dual Query Language Support

Signal Query Language How It Works
Metrics PromQL Translated to ClickHouse SQL by the query service
Logs ClickHouse SQL Direct columnar queries with filter pushdown
Traces ClickHouse SQL Span-level queries with attribute filtering
All Query Builder Visual query builder generates optimized CH SQL

Query Builder → ClickHouse Translation

The React frontend's visual query builder generates structured query payloads that the Go query service translates into optimized ClickHouse SQL:

  1. User builds query visually (aggregation, filters, group-by)
  2. Frontend sends structured JSON payload to API
  3. Query Service compiles to ClickHouse SQL with proper materialized column usage
  4. ClickHouse executes with columnar vectorized processing
  5. The Query Service returns results as time-series or table data

Cross-Signal Correlation

SigNoz enables correlation between signals using shared identifiers:

flowchart LR
    Trace["Trace\n(traceID)"] <-->|traceID in log| Log["Log\n(traceID, spanID)"]
    Trace <-->|service + timestamp| Metric["Metric\n(service, operation)"]
    Log <-->|service + timestamp| Metric
  • Trace → Log: Click a span to see logs with matching traceID
  • Log → Trace: Click a log with traceID to jump to the trace waterfall
  • Metric → Trace: Drill down from a latency spike to exemplar traces

Alerting Pipeline

flowchart LR
    Rule["Alert Rule\n(PromQL / CH SQL)"] --> Eval["Ruler\n(periodic eval)"]
    Eval -->|threshold breach| AM["Alertmanager"]
    AM --> Slack["Slack"]
    AM --> PD["PagerDuty"]
    AM --> WH["Webhook"]
    AM --> Email["Email"]
    AM --> MST["MS Teams"]
  • Rules can be defined on any signal type (metrics, logs, traces)
  • Anomaly detection available for automated threshold learning
  • Alert history tracked with state transitions

Sources


Benchmarks

Performance characteristics, capacity planning data, and scale limits for SigNoz.

ClickHouse Performance

vs ELK Stack

Metric SigNoz (ClickHouse) ELK Stack Advantage
Log ingestion speed Baseline ~2.5x slower SigNoz 2.5x faster
Resource consumption Baseline ~2x more SigNoz 50% less
Aggregate query speed Baseline ~13x slower SigNoz up to 13x faster
Ingestion capacity 10+ TB/day Similar Comparable
Compression ratio 10–30x (columnar) 1.5x (Lucene) SigNoz 7–20x better

Source: SigNoz vendor benchmarks. Cross-validated against ClickHouse engineering blog data on columnar efficiency.

High Cardinality Handling

Aspect Detail
Approach Columnar storage — no inverted index explosion
Impact Adding a dimension with billions of unique values is trivial
Best for Logs and traces with rich metadata
Caution Do not use high-cardinality attributes as metric labels

Capacity Planning

Resource Matrix (from SigNoz Official Docs)

Component Small (< 10 GB/day) Medium (10–50 GB/day) Large (50–200 GB/day)
OTel Collectors 1 replica, 1 CPU, 2 GB 2 replicas, 2 CPU, 4 GB 4+ replicas, 4 CPU, 8 GB
Query Service 1 replica, 0.5 CPU, 1 GB 2 replicas, 1 CPU, 2 GB 2 replicas, 2 CPU, 4 GB
ClickHouse 1 node, 4 CPU, 16 GB 2 shards × 2 replicas, 8 CPU, 32 GB 4+ shards × 2 replicas, 16 CPU, 64 GB
ZooKeeper / Keeper 1 node, 0.5 CPU, 1 GB 3 nodes, 1 CPU, 2 GB 3 nodes, 2 CPU, 4 GB
PostgreSQL 1 node, 0.5 CPU, 1 GB Managed DB (RDS) Managed DB (RDS)

Cloud Instance Recommendations

Cloud General Purpose (Collectors, QS) Compute-Optimized (ClickHouse)
AWS T3 family+ (Intel), T4g+ (ARM) C5+ (Intel), C6g/C7g+ (ARM)
GCP E2 family+ C3 / C3D+

Storage Sizing

Signal Daily Volume 15-Day Retention 30-Day Retention
Logs (10:1 compression) 50 GB raw/day ~75 GB disk ~150 GB disk
Traces (15:1 compression) 20 GB raw/day ~20 GB disk ~40 GB disk
Metrics (30:1 compression) 5 GB raw/day ~2.5 GB disk ~5 GB disk

Scale Limits

Dimension Practical Limit Notes
Daily ingestion 10+ TB/day Requires multi-shard ClickHouse
Active time series 10M+ ClickHouse handles high cardinality well
Concurrent queries 50–100 Depends on ClickHouse node count
Trace span retention 15–90 days typical Storage cost-limited
Log retention 15–90 days typical ClickHouse TTL-managed

Known Performance Considerations

  1. System tables growth: ClickHouse's query_log and zookeeper_log can grow rapidly. Monitor and set TTLs.
  2. ClickHouse parts merges: Under very high ingestion, make sure that there is sufficient CPU for background merges.
  3. ZooKeeper latency: In multi-shard setups, ZooKeeper latency directly impacts replication lag.

Caveats

  • Benchmarks are from SigNoz vendor testing and ClickHouse engineering publications.
  • Actual performance varies significantly based on data patterns, cardinality, and query complexity.
  • Managed ClickHouse providers can exhibit different resource profiles.

Sources


Security

Security model for SigNoz covering OTLP ingestion authentication, ClickHouse security, SSO integration, API tokens, service accounts, and data retention. See also: observability/signoz/index, observability/signoz/explanation, observability/signoz/how-to-guides.

Security Architecture Overview

SigNoz uses a multi-layer security model with the SigNoz Query Service as the central authorization point. ClickHouse stores the data. OpenTelemetry Collectors (SigNoz Otel Collector) ingest the telemetry.

flowchart TD
    subgraph "External"
        Apps[Instrumented Applications]
        Users[Browser / API Users]
        IdP[Identity Provider<br/>SAML / OIDC / Google]
    end

    subgraph "Ingestion Layer"
        Collector[SigNoz Otel Collector<br/>OTLP Receiver]
    end

    subgraph "SigNoz Platform"
        QS[Query Service<br/>Auth / RBAC / API]
        Frontend[Frontend UI]
    end

    subgraph "Data Store"
        CH[(ClickHouse<br/>Traces / Logs / Metrics)]
    end

    Apps -->|OTLP + ingestion key| Collector
    Collector -->|Write| CH
    Users -->|Login / SSO| Frontend
    Frontend --> QS
    QS -->|Validate auth| IdP
    QS -->|Read/Write| CH

OTLP Ingestion Authentication

Ingestion Keys

All telemetry data sent to SigNoz must include an ingestion key for authentication. Two header formats are supported:

SigNoz Cloud:

# OpenTelemetry Collector OTLP exporter
exporters:
  otlp:
    endpoint: "ingest.us.signoz.cloud:443"
    tls:
      insecure: false
    headers:
      "signoz-ingestion-key": "<your-ingestion-key>"

Self-hosted (via API key):

exporters:
  otlphttp:
    endpoint: https://signoz.YOUR_DOMAIN:443
    headers:
      signoz-access-token: "<your-api-key>"

Ingestion Key vs API Key

Ingestion keys grant write-only access to the data pipeline. API keys (used for management APIs) have broader permissions depending on the associated role. Use ingestion keys for collectors and API keys for management automation.

Query Service Authentication

The Query Service validates all API requests:

GET /api/v1/service_accounts/me
SIGNOZ-API-KEY: <your-service-account-key>

ClickHouse Security

Connection Security

SigNoz connects to ClickHouse using the native TCP protocol (port 9000) or HTTP interface (port 8123). Security hardening:

  • Dedicated user: Create a ClickHouse user specifically for SigNoz with access limited to signoz_metrics, signoz_logs, and signoz_traces databases.
  • Password authentication: Required by default. Configure it in the SigNoz ClickHouse connection settings.
  • TLS: Enable ClickHouse native TLS (<tcp_port_secure>9440</tcp_port_secure>) or HTTPS for the HTTP interface.
# ClickHouse user configuration
users:
  signoz:
    password: "<secure-password>"
    networks:
      ip:
        - "10.0.0.0/8"    # Restrict to internal network
        - "172.16.0.0/12"
    profile: default
    quota: default
    databases:
      signoz_metrics: ["SELECT", "INSERT", "CREATE", "ALTER"]
      signoz_logs: ["SELECT", "INSERT", "CREATE", "ALTER"]
      signoz_traces: ["SELECT", "INSERT", "CREATE", "ALTER"]

Schema Migrations

SigNoz manages ClickHouse schema through a migration system with three phases:

# Bootstrap migration (initial setup)
./signoz-otel-collector migrate bootstrap \
    --clickhouse-dsn="tcp://localhost:9000?password=password" \
    --clickhouse-replication=true

# Synchronous migration (schema changes)
./signoz-otel-collector migrate sync up \
    --clickhouse-dsn="tcp://localhost:9000?password=password" \
    --clickhouse-replication=true

# Asynchronous migration (data backfill)
./signoz-otel-collector migrate async up \
    --clickhouse-dsn="tcp://localhost:9000?password=password" \
    --clickhouse-replication=true

Migration Privileges

The migration system requires CREATE and ALTER permissions on the ClickHouse databases. For production, run migrations with an elevated user and use a restricted user for the Query Service's daily operations.

Distributed ClickHouse Security

For clustered deployments, secure inter-node communication:

# values.yaml for distributed ClickHouse
clickhouse:
  layout:
    shardsCount: 2
    replicasCount: 2
  zookeeper:
    replicaCount: 3
schemaMigrator:
  enableReplication: true
  • Enable TLS between ClickHouse nodes (<interserver_http_host> with HTTPS).
  • Secure ZooKeeper connections with TLS and digest authentication.
  • Restrict inter-node traffic to private network only.

SSO Integration

Supported SSO Methods

SigNoz supports three SSO protocols, available in both Cloud and self-hosted Enterprise:

Method Protocol IdP Examples
SAML 2.0 SAML Okta, Azure AD, OneLogin, Keycloak, AWS SSO
OIDC OpenID Connect Okta, Azure AD, Auth0, Keycloak
Google Workspace OAuth2 Google Workspace

SAML Configuration

SAML is configured per email domain. When a user from a registered domain logs in, SigNoz delegates authentication to the configured IdP.

Configuration fields: - Domain: Email domain to associate with the IdP (for example, example.com). - SAML ACS URL / IDP URL: The assertion consumer service URL from the IdP. - SAML X.509 Certificate: Public certificate for signature verification. - SAML Entity ID: Unique identifier for the SigNoz service provider. - Skip AuthN Requests Signed: Whether to skip signing authn requests.

Domain: example.com
SAML ACS URL/SAML IDP URL: https://idp.YOUR_DOMAIN/saml/sso
SAML X.509 Certificate: <certificate-data>
SAML Entity ID: https://signoz.YOUR_DOMAIN
Skip AuthN Requests Signed: True

SSO Features

  • Just-in-Time provisioning: Users are automatically created on first SSO login.
  • Attribute mapping: IdP claims mapped to SigNoz user fields (name, email).
  • Role mapping: IdP group memberships or attributes automatically assigned to SigNoz roles.
  • Enforce SSO: Require all users from a domain to authenticate via SSO (disables password login).

API Authentication

Service Accounts

Service accounts enable automated workloads to interact with the SigNoz API:

GET /api/v1/service_accounts/me
SIGNOZ-API-KEY: <your-service-account-key>

Service accounts support: - Role assignment: Viewer, Editor, Admin roles control API access scope. - Multiple keys: Each service account can have multiple API keys. - Key rotation: Keys can be rotated without deleting the service account.

Terraform Provider

The SigNoz Terraform provider uses API keys for authentication:

provider "signoz" {
  endpoint     = "https://signoz.YOUR_DOMAIN"
  access_token = var.signoz_api_key
}

Best practice: store the access token in environment variables or a secrets manager rather than in plaintext:

export SIGNOZ_ACCESS_TOKEN="your-api-key"
export SIGNOZ_ENDPOINT="https://signoz.YOUR_DOMAIN"

Data Retention Policies

ClickHouse TTL

SigNoz manages data retention through ClickHouse table TTL. The Query Service configures TTL during schema migration:

  • Traces: Default retention configurable via SigNoz settings (typically 7-30 days).
  • Logs: Separate TTL per log pipeline.
  • Metrics: Tiered retention (raw data shorter, aggregated data longer).

Retention is enforced by ClickHouse's background TTL merge process. No manual data deletion is required.

Storage Encryption

ClickHouse supports encryption at rest for data files:

# ClickHouse server config
storage_configuration:
  disks:
    encrypted:
      type: encrypted
      disk: default
      key: "encryption-key-hex"
  policies:
    encrypted_policy:
      volumes:
        main:
          disk: encrypted

Alternatively, use filesystem-level encryption (LUKS) on the underlying EBS volumes.

Network Security

Component Default Port Purpose Recommended Exposure
Otel Collector 4317 (gRPC), 4318 (HTTP) OTLP ingestion Behind load balancer
Query Service 8080 API server Behind reverse proxy with TLS
Frontend 3301 Web UI Via Query Service proxy
ClickHouse 9000 (TCP), 8123 (HTTP) Data store Internal only

Hardening Checklist

Area Recommendation
Ingestion keys Unique key per collector. Rotate on compromise
ClickHouse user Dedicated user with minimum database permissions
ClickHouse TLS Enable native TLS for inter-node and client connections
ClickHouse network Restrict to internal VPC only
SSO Enforce SSO for all organizational email domains
API keys Store in environment variables or Vault. Never store them in code
Retention Set appropriate TTLs per signal type
Encryption at rest Use ClickHouse encrypted disks or LUKS on EBS
TLS termination Deploy reverse proxy (Nginx/Caddy) for HTTPS
Schema migrations Use an elevated user for migrations. Use a restricted user for runtime

Sources