Uptrace

Unified open-source APM that collects OpenTelemetry traces, metrics, and logs into a single self-hosted platform backed by ClickHouse.

4.2Kstars
210forks
GNU AGPLv3
Go

Uptrace is an open-source Application Performance Monitoring (APM) platform that solves the fragmentation problem in modern observability by unifying distributed traces, metrics, and logs into a single self-hosted interface. Built on OpenTelemetry for vendor-neutral data collection and ClickHouse for high-throughput time-series storage, it enables teams to monitor and troubleshoot distributed systems at a fraction of the cost of commercial alternatives.

The platform ships with purpose-built query languages for both spans (UQL — Uptrace Query Language) and metrics (MQL — Metrics Query Language), giving engineers precise control over how telemetry data is sliced, aggregated, and visualized. Uptrace can process more than 10,000 spans per second on a single core, and its schema design compresses a 1KB span to roughly 40 bytes on disk — making it viable for teams with high-volume telemetry and limited infrastructure budgets.

Uptrace accepts data from OpenTelemetry Collector, Prometheus scrape endpoints, Vector log pipelines, FluentBit, and AWS CloudWatch, covering the full observability stack. Pre-built dashboards are generated automatically as soon as metrics start flowing, and Grafana can be configured to use Uptrace as a Tempo- or Prometheus-compatible data source for teams with existing visualization tooling.

Deployment is straightforward via Docker Compose or Kubernetes, with ClickHouse and PostgreSQL as the only required external dependencies. User management, SSO via OpenID Connect, and project isolation are configured through a single YAML file, keeping operational overhead low for self-hosted installations.

What You Get

  • Unified traces, metrics, and logs UI - Single interface to ingest, query, and correlate all three telemetry signals without switching between tools or accounts.
  • UQL — Uptrace Query Language for spans - SQL-like syntax to aggregate, filter, and group spans by any attribute, enabling complex latency distributions and error-rate breakdowns.
  • MQL — Metrics query language - PromQL-compatible expression engine for time-series metrics, allowing familiar Prometheus-style queries against OpenTelemetry metric data.
  • 50+ auto-generated dashboards - Pre-built dashboards created automatically once instrumented services send data, covering common runtimes, databases, and infrastructure.
  • Multi-channel alerting on any signal - Define alert rules on span error rates, metric thresholds, or log patterns, with notifications via Email, Slack, Webhook, and AlertManager.
  • ClickHouse-backed aggressive compression - Schema design compresses 1KB spans to ~40 bytes, enabling storage of billions of spans on commodity hardware.
  • Grafana and Prometheus compatibility - Configure Grafana to query Uptrace as a Tempo datasource for traces and a Prometheus datasource for metrics, integrating with existing dashboards.
  • Span and log correlation via context propagation - Logs are automatically linked to their parent traces using OpenTelemetry trace context, making it trivial to jump from a log line to the full trace.
  • SSO via OpenID Connect - Built-in authentication integrations for Keycloak, Google Cloud Identity, and Cloudflare Access for team-wide access control.
  • Service dependency graph and annotations - Visualize inter-service call relationships and annotate charts with deployment events to correlate releases with performance changes.

Common Use Cases

  • Debugging slow API requests in microservices - A backend engineer traces a 3-second API call across eight services, using span attributes and UQL to isolate the specific downstream database call causing the slowdown.
  • Replacing Datadog on a cost-constrained team - A startup migrates from Datadog to self-hosted Uptrace, retaining full trace and metric visibility while eliminating per-seat and per-host licensing fees.
  • Monitoring Kubernetes workloads at scale - A platform team deploys Uptrace alongside OpenTelemetry Collector to ingest telemetry from hundreds of pods, using auto-generated dashboards to track resource usage and latency SLOs.
  • Correlating error spikes with deployments - A DevOps team uses chart annotations to mark deployment times and immediately sees a spike in 5xx error rates on the span error dashboard, enabling rapid rollback decisions.
  • Ingesting Prometheus metrics without infrastructure changes - A team already running Prometheus scrape jobs points Uptrace’s Prometheus ingest endpoint at their exporters, gaining long-term storage and cross-signal correlation without changing their instrumentation.
  • Incident triage for on-call engineers - An on-call engineer receives a Slack alert from Uptrace, clicks through to the correlated trace, and jumps directly to the error log within the same UI to identify a null pointer exception in minutes.

Under The Hood

Architecture Uptrace employs a modular monolith structured around Uber’s fx dependency injection framework, which wires all subsystems declaratively at startup through provider and consumer contracts. The ingestion pipeline follows a clear stratification: OTLP, Prometheus, Vector, and CloudWatch data enters through gRPC and HTTP handlers, flows through a shared generic BaseConsumer type parameterized over index and data record pairs, and is batch-inserted into ClickHouse with configurable worker pool sizes and buffer depths. Span, log, event, and metric pipelines share this base consumer abstraction but diverge in transformation logic, achieving strong separation of concerns without code duplication. PostgreSQL holds relational metadata — projects, dashboards, users, and alert definitions — while ClickHouse handles all time-series queries. The Vue 3 frontend is fully decoupled from the backend, communicating solely via REST and gRPC APIs. Configuration is centralized in a well-structured YAML file managed by the bunconf package, supporting environment variable substitution for secrets and cluster-aware ClickHouse shard configuration.

Tech Stack The backend is written in Go 1.24 using Uber’s fx for dependency injection and bunrouter for HTTP routing alongside native gRPC handlers. ClickHouse serves as the primary time-series store with ZSTD compression and support for clustered and distributed deployments with configurable shards and replicas. PostgreSQL stores relational metadata and is accessed via the bun ORM with full migration support. The queue system uses a custom taskq library backed by PostgreSQL’s pgq or Redis. The frontend is Vue 3 with Vuetify components built using Vite and TypeScript. Both the UQL and MQL query languages are implemented with hand-written lexers, parsers, and AST evaluators in Go, generating optimized ClickHouse SQL. The project self-instruments with the uptrace-go SDK, sending its own telemetry to the running instance.

Code Quality Test coverage is sparse and focused on utility-level functions — a single tracing test validates string formatting, and queue integration tests cover background workers, but the core ingestion and query pipelines lack automated tests. The shared BaseConsumer generic type demonstrates mature use of Go type parameters, and structured logging via otelzap is used consistently throughout the backend. Error handling follows basic fmt.Errorf wrapping rather than structured error types, and no linter configuration file is present in the repository root. CI via GitHub Actions is referenced in the README and runs build-and-test workflows on each push. The codebase is well-organized by domain package but would benefit from broader test coverage given its role as an observability foundation.

What Makes It Unique Uptrace’s most distinctive technical contribution is its pair of purpose-built query languages — UQL for trace aggregation and MQL for metric time-series — with hand-rolled lexers, parsers, and AST evaluators that generate ClickHouse SQL directly. This avoids dependency on third-party query engines while achieving tight integration between the query layer and the storage schema. The generic BaseConsumer[IT, DT] pattern in Go shares batching, buffering, and worker pool logic across spans, logs, and events with full type safety, avoiding the code duplication typical of multi-signal APM platforms. The aggressive compression — 1KB spans stored as roughly 40 bytes — results from deliberate schema choices including bfloat16 representation for metric values in ClickHouse. The project also self-instruments with OpenTelemetry, using Uptrace to monitor itself, which functions as both a demonstration and a continuous integration test of the platform’s reliability.

Self-Hosting

Uptrace is released under the GNU Affero General Public License version 3 (AGPL-3.0). This is a strong copyleft license that permits commercial use and modification, but any modified version you deploy over a network must make its source code available to users under the same AGPL terms. For most self-hosters running Uptrace as an internal observability tool — where external users are not accessing the modified service — the AGPL imposes no practical obligation. However, companies building a product or SaaS on top of a modified Uptrace and exposing it to customers would need to release their modifications. There is no commercial licensing exception or enterprise-tier source-available variant in the repository; the AGPL applies uniformly.

Running Uptrace yourself requires managing three persistent services: ClickHouse (time-series storage), PostgreSQL (metadata and alerts), and the Uptrace binary itself. Docker Compose configuration is provided for getting started, and Kubernetes deployment is supported, but production setups require capacity planning for ClickHouse — particularly for high-cardinality attribute storage and retention policies. The team is responsible for ClickHouse schema migrations, PostgreSQL backups, and binary upgrades when new versions ship. The system exposes health checks and self-observability via OpenTelemetry, which helps with operational monitoring, but there is no built-in high-availability clustering for the Uptrace process itself — redundancy must be arranged at the infrastructure level.

Uptrace offers a hosted cloud version at uptrace.dev that eliminates all infrastructure management: ClickHouse, PostgreSQL, upgrades, backups, and scaling are handled by the Uptrace team. The cloud tier adds managed SLAs, support channels, and a playground environment accessible without any login. Self-hosters give up these guarantees and support access, and must handle data retention and storage cost management independently. For teams with strict data residency requirements or cost sensitivity at high data volumes, self-hosting remains attractive; for smaller teams prioritizing operational simplicity, the managed offering removes substantial overhead.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack

No spam. Unsubscribe anytime.

Join 750+ subscribers
No spam. Unsubscribe anytime.

Search