TECHNICAL REFERENCE
Full technical breakdown of the observability pipeline. Component inventory, data flow, deployment topology, security posture, and schema reference.
End-to-end telemetry pipeline from browser instrumentation to queryable storage. All arrows represent real, production data paths.
flowchart LR
subgraph Client["Client (Browser)"]
SDK["HyperDX Browser SDK\n@hyperdx/browser"]
end
subgraph Tunnel["Cloudflare"]
CF["Cloudflared Tunnel\n(ingress)"]
end
subgraph SelfHost["Self-hosted VM (Cloudflare-tunneled)"]
Collector["OTEL Collector\n:4318 OTLP/HTTP"]
HDX["HyperDX App\n:8080"]
GF["Grafana\n:3000"]
end
subgraph Storage["ClickHouse Cloud (GCP us-central1, managed)"]
CH[("otel_traces\notel_logs\notel_metrics")]
end
subgraph Consumers["Query Interfaces"]
Vercel["Vercel Portal + API\n(serverless functions)"]
SQL["SQL Console\n(ad-hoc)"]
end
SDK -->|"OTLP/HTTP\ntraces, logs, RUM"| CF
CF -->|"tunnel"| Collector
Collector -->|"INSERT (batch)"| CH
HDX -->|"SELECT"| CH
GF -->|"SELECT"| CH
Vercel -->|"SELECT :8443"| CH
SQL -->|"SELECT"| CH
style SDK fill:#3b82f6,color:#fff,stroke:#60a5fa
style CF fill:#f97316,color:#fff,stroke:#fb923c
style Collector fill:#06b6d4,color:#fff,stroke:#22d3ee
style HDX fill:#7c3aed,color:#fff,stroke:#a78bfa
style GF fill:#ea580c,color:#fff,stroke:#f97316
style CH fill:#ca8a04,color:#fff,stroke:#facc15
style Vercel fill:#0ea5e9,color:#fff,stroke:#38bdf8
style SQL fill:#64748b,color:#fff,stroke:#94a3b8
Capture
Browser SDK auto-instruments clicks, navigation, network requests, console output, and DOM snapshots. Emits standard OTLP over HTTP.
Ingest
OTEL Collector receives, batches, and inserts telemetry into ClickHouse. No intermediate queue or broker required.
Query
Three independent consumers read from the same tables. No data duplication, no sync lag. One source of truth.
EXOS Analytics captures OTEL traces from server-side APIs, not just browser events. Every EXOS API call is already instrumented with OpenTelemetry. EXOS Analytics turns that existing telemetry into product insight — no new client-side instrumentation required.
Server-side event tracking is easier to maintain, more reliable, and captures what matters most: the actual business logic executing behind the UI. Browser events show what users clicked. Server traces show what actually happened.
Every component in the stack, its role, and its licensing. No proprietary lock-in on the data path.
| Component | Role | License | Deployment |
|---|---|---|---|
| HyperDX Browser SDK | Client-side auto-instrumentation. Captures clicks, navigation, network, console, and DOM for session replay. Emits OTLP. | MIT | NPM / CDN script tag |
| OpenTelemetry Collector | Receives OTLP/HTTP on :4318. Batches and exports to ClickHouse via the clickhouseexporter. |
Apache 2.0 | Docker container |
| ClickHouse Cloud | Columnar OLAP database. Stores all traces, logs, and metrics. Handles both INSERT (write) and SELECT (query) workloads. | Apache 2.0 (core) | Managed service (GCP, us-central1) |
| HyperDX App | Session replay UI, trace viewer, log explorer. Reads from ClickHouse via SQL. | Apache 2.0 | Docker container |
| Grafana | Dashboard and alerting platform. Connects to ClickHouse as a data source for operational dashboards. | AGPLv3 | Docker container |
| Cloudflared | Ingress tunnel. Routes external HTTPS traffic to internal Docker services without exposing ports. | Proprietary | Docker container |
| Vercel | Serves the static portal (vanilla HTML) and the serverless API functions under /api/*, which query ClickHouse over HTTPS. |
Proprietary | Vercel serverless |
Current production deployment. The portal and API run on Vercel; telemetry is stored in a managed ClickHouse Cloud instance on GCP (us-central1); telemetry ingest runs through a Cloudflare-tunneled OTEL collector on a self-hosted VM.
flowchart TB
subgraph Internet
Browser["End User Browser"]
CloudFlare["Cloudflare Edge\n(tunnel ingress)"]
end
subgraph Ingest["OTEL Collector VM (self-hosted)"]
CFD["cloudflared"]
OTEL["otel-collector\n:4318 OTLP/HTTP"]
CFD --> OTEL
end
subgraph Serve["Vercel"]
Portal["Static Portal\n(vanilla HTML)"]
API["Serverless API\napi/[action].js"]
end
subgraph CHCloud["ClickHouse Cloud — GCP us-central1"]
CH[("ClickHouse\nSOC 2 Type II")]
end
Browser -->|HTTPS| CloudFlare
CloudFlare -->|tunnel| CFD
OTEL -->|"INSERT (batch)"| CH
Browser -->|HTTPS| Portal
Portal --> API
API -->|"HTTPS :8443 (TLS)"| CH
style Browser fill:#64748b,color:#fff,stroke:#94a3b8
style CloudFlare fill:#f97316,color:#fff,stroke:#fb923c
style OTEL fill:#06b6d4,color:#fff,stroke:#22d3ee
style CFD fill:#64748b,color:#fff,stroke:#94a3b8
style Portal fill:#0ea5e9,color:#fff,stroke:#38bdf8
style API fill:#0ea5e9,color:#fff,stroke:#38bdf8
style CH fill:#ca8a04,color:#fff,stroke:#facc15
| Platform | Vercel |
| Portal | Static vanilla HTML (no build step) |
| API | Serverless functions via api/[action].js |
| Max duration | 30 s per request |
| Ingest | Cloudflare-tunneled OTEL collector (self-hosted VM) |
| Service | ClickHouse Cloud (managed) |
| Cloud | GCP (us-central1) |
| Connection | HTTPS, port 8443 (TLS) from Vercel functions |
| Compliance | SOC 2 Type II |
| Backup | ClickHouse Cloud automated |
Key security properties of the deployment. No third-party analytics vendors receive user data.
us-central1.
maskAllText and maskAllInputs flags redact sensitive content before it leaves the browser.
8443).
user.email, user.uid).?skipauth=true) bypasses only the front-end sign-in overlay for evaluation and test automation — it grants no additional data privilege.exos_readonly — SELECT on the default + exos databases only, with engine-level readonly=1 blocking remote()/url()/s3() escapes.{ default, exos } and reject cross-database references. Other data on the instance is unreachable from any portal surface.Full detail: Docs → Access & Auth.
Primary table structure in ClickHouse. These tables follow the OpenTelemetry data model and are queryable by all three consumer applications.
Primary event table. One row per span. Powers session replay, trace analysis, and dashboard aggregations.
| Column | Type | Description |
|---|---|---|
Timestamp |
DateTime64(9) | Nanosecond-precision event timestamp |
TraceId |
String | W3C trace context identifier. Links all spans in a distributed trace. |
SpanId |
String | Unique span identifier within the trace |
ParentSpanId |
String | Parent span for causal ordering |
SpanName |
LowCardinality(String) | Operation name (e.g., HTTP GET, click, routeChange) |
ServiceName |
LowCardinality(String) | Logical service identifier (e.g., clickstack-portal) |
SpanAttributes |
Map(String, String) | Span-level key-value metadata. Includes URL, status code, user agent, DOM element selectors. |
ResourceAttributes |
Map(String, String) | Resource-level metadata. Includes SDK version, browser info, OS. |
Duration |
Int64 | Span duration in nanoseconds |
StatusCode |
LowCardinality(String) | OTEL status: Unset, Ok, Error |
Console captures and structured log events. Correlated to traces via TraceId.
Key columns: Timestamp, TraceId, SeverityText, Body, LogAttributes
Web Vitals and custom metrics. LCP, FID, CLS, TTFB captured automatically by the SDK.
Key columns: Timestamp, MetricName, Value, Attributes
SELECT SpanName, count() AS events, avg(Duration)/1e6 AS avg_ms FROM otel_traces WHERE ServiceName = 'clickstack-portal' AND Timestamp > now() - INTERVAL 1 HOUR GROUP BY SpanName ORDER BY events DESC LIMIT 20
ServiceName into distinct products — EXOS Operations (exos-*), the Analytics Portal (clickstack-portal), RadLo (radlo-web), and Docs (beppe-dotfiles-docs). The conceptual data model — the OpenTelemetry trace/span/attribute model, the core default and exos tables, and the property concept — is documented in Docs → Concepts & Data Model.
The portal backend exposes these JSON API endpoints. All endpoints query ClickHouse in real time — no caching layer, no pre-aggregation.
| Endpoint | Description | Parameters |
|---|---|---|
GET /api/stats |
KPI snapshot: session count, event volume, and error rate. | workspace, lob, operator, task, hours |
GET /api/events |
Raw trace/log feed with search and pagination. | table, hours, workspace, search, status, limit, offset, cursor |
GET /api/funnels |
Funnel analysis with windowFunnel(). Returns step-by-step conversion rates for a defined sequence of events. |
steps, hours, workspace, list |
GET /api/retention |
Cohort retention matrix. Groups users by first action date and measures return rates over subsequent periods. | first_action, return_action, granularity, hours, workspace, list |
GET /api/paths |
User journey analysis. Discovers the most common sequences of actions users take through the application. | hours, workspace, depth |
GET /api/errors |
Grouped error analysis. Returns error messages ranked by frequency with affected services and time distribution. | hours, workspace, group |
GET /api/sessions |
Session list; pass id for one enriched session's spans (replay drill-down). |
id, hours, limit, lob, operator, task, span |
GET /api/operators |
Operator leaderboard; pass id for a single-operator profile. |
id, hours, lob, role |
GET /api/ocpm |
Object-centric process mining: interactions, variants, lifecycle, actor-affinity. | hours |
GET /api/insights · /api/patterns |
Narrative process-mining insights and rolling-z-score anomaly detection. | hours, min_hours, threshold |
GET /api/workspaces · /api/lobs · /api/filters |
Discovery: available properties, lines of business, and cascading filter options. | lob, operator |
POST /api/query |
Natural-language → SQL (Claude on Azure), validated and executed read-only. | { question } or { messages[] } |
POST /api/sql |
Execute a raw read-only SELECT/WITH. DDL/DML and cross-database refs rejected. |
{ sql, database? } |
GET /api/schema |
Column catalog for the queryable default + exos tables. |
— |
workspace parameter to scope results to a single property (a ServiceName); omit it to query the default EXOS + Portal scope. All endpoints query ClickHouse in real time and run as the least-privilege exos_readonly user. Full per-endpoint reference: Docs → API & Query Reference.
ClickHouse is a columnar OLAP engine optimized for analytical queries over large datasets. These are documented ClickHouse characteristics, not theoretical claims.
109+
Rows
ClickHouse handles billions of rows per table. Horizontal scaling via ClickHouse Cloud adds shards as volume grows.
<100ms
Query Latency
Columnar storage + vectorized execution. Sub-100ms on typical analytical queries scanning millions of rows.
10-20x
Compression
LZ4 + delta encoding on columnar data. Telemetry data (highly repetitive) compresses exceptionally well.