Skip to content

Architecture

Component topology, data model, deployment patterns, and technology choices for Monoscope.

Component Topology

flowchart TB
    subgraph Clients["Client Applications"]
        Apps["Your Apps\n(OTel SDKs)"]
        Browser["Browser\n(Session Replay SDK)"]
    end

    subgraph Ingestion["Ingestion Layer"]
        OTel["OTel Collector\n(gRPC :4317)"]
        API["Monoscope API\n(Haskell)"]
        Kafka["Kafka Buffer"]
    end

    subgraph Processing["Processing Layer"]
        Worker["Extraction Worker"]
        Agent["AI Agent\nScheduler"]
        LLM["LLM API"]
    end

    subgraph Storage["Storage Layer"]
        TF["TimeFusion\n(Rust + DataFusion)"]
        PG["PostgreSQL\n+ TimescaleDB (pg18)"]
        S3["S3 Bucket\n(Delta Lake / Parquet)"]
        Cache["Foyer Cache\n(512MB mem + 100GB disk)"]
    end

    subgraph UI["Presentation Layer"]
        Web["Web Dashboard\n(HTMX + Tailwind)"]
        Alerts["Alert Channels\n(Slack, Discord, PagerDuty)"]
    end

    Apps -->|"OTLP/gRPC"| OTel
    Browser -->|"Session events"| API
    OTel -->|"Bearer token"| API
    API --> Kafka --> Worker
    Worker --> TF
    Worker --> PG
    TF --> S3
    TF --> Cache
    Agent -->|"Query"| TF
    Agent --> LLM
    Agent --> Alerts
    Web -->|"SQL via pgwire"| TF
    Web --> PG

    style Storage fill:#2e7d32,color:#fff
    style Ingestion fill:#1565c0,color:#fff
    style Processing fill:#e65100,color:#fff

Technology Breakdown

Component Language Framework/Library Purpose
Monoscope Backend Haskell (80.5%) Hasql, Lucid, HTMX, Eff API, ingestion, processing, web UI
TimeFusion Rust DataFusion, pgwire, Delta Lake, Foyer Time-series query engine with S3 storage
Metadata DB PLpgSQL (2.4%) PostgreSQL + TimescaleDB (pg18) Project config, alerts, user management
Frontend TypeScript (11.7%) HTMX, Tailwind v4, DaisyUI v5, ECharts Server-rendered UI with dynamic updates
SDKs Multi-language OTel SDK wrappers Application instrumentation
Migrations PLpgSQL 87KB of SQL migrations Schema evolution

Haskell Backend Internals

  • hasql-interpolate for type-safe PostgreSQL queries (migrated from postgresql-simple in v0.5.0)
  • Lucid for HTML templating (server-rendered)
  • HTMX for dynamic page updates with morphing
  • Eff effect system for IO abstraction
  • Effectful.Time for time operations
  • Fourmolu for code formatting
  • GHC 9.12 compatible

Data Model

Telemetry Storage (TimeFusion / S3)

erDiagram
    PROJECT ||--o{ OTEL_EVENTS : "contains"
    OTEL_EVENTS {
        uuid id PK
        uuid project_id FK
        timestamptz timestamp
        date date_partition
        text name
        bigint duration_ns
        text kind
        text[] hashes
        text attributes
    }
    TRACE {
        uuid trace_id
        uuid span_id
        uuid parent_span_id
        text service_name
        text operation_name
    }
    LOG_ENTRY {
        uuid id PK
        timestamptz timestamp
        text severity
        text body
        text attributes
    }
    METRIC {
        text metric_name
        text metric_type
        float value
        text labels
    }

Metadata Storage (PostgreSQL + TimescaleDB)

  • Projects — tenant isolation, API keys, retention settings
  • Monitors — alerting rules, health checks, renotify intervals
  • Alerting state — active incidents, notification history
  • Users/Teams — authentication, authorization, audit logs
  • AI Agent configs — schedules, LLM prompts, report recipients

Deployment Topologies

Docker Compose (Development / Small Production)

flowchart LR
    subgraph Host["Docker Host"]
        M["monoscope\n:8080"]
        TF["timefusion\n:5432"]
        PG["postgres+timescaledb\n:5433"]
        K["kafka\n:9092"]
        S3["localstack/minio\nS3-compatible"]
    end

    M --> TF --> S3
    M --> PG
    M --> K

Self-Hosted Production

flowchart TB
    subgraph LB["Load Balancer"]
        Nginx["NGINX\n(TLS Termination)"]
    end

    subgraph K8s["Kubernetes Cluster"]
        subgraph Monoscope["Monoscope Pods"]
            M1["monoscope-api-1"]
            M2["monoscope-api-2"]
        end

        subgraph Workers["Background Workers"]
            W1["extraction-worker"]
            W2["ai-agent-scheduler"]
        end

        OTelCol["OTel Collector"]
    end

    subgraph Data["External Data"]
        S3Prod["AWS S3 / MinIO"]
        PGHA["PostgreSQL HA\n(Patroni / RDS)"]
        TFProd["TimeFusion\n(Deployed separately)"]
        KProd["Kafka Cluster"]
    end

    Nginx --> M1
    Nginx --> M2
    M1 --> S3Prod
    M1 --> PGHA
    M1 --> TFProd
    Workers --> S3Prod
    OTelCol --> M1

    style K8s fill:#1565c0,color:#fff
    style Data fill:#2e7d32,color:#fff

Monoscope Cloud (SaaS)

flowchart LR
    subgraph Cloud["Monoscope Cloud"]
        MC["Managed Monoscope\n+ TimeFusion"]
        MCS3["Monoscope S3"]
    end

    subgraph BYOS["Your S3 Bucket\n(optional)"]
        US3["Your S3\n(unlimited retention)"]
    end

    Apps["Your Apps"] -->|"OTLP"| Cloud
    MC --> MCS3
    MC -->|"BYOS mode"| US3

Sources