Skip to content

Architecture

Deployment Modes

All LGTM backends (Mimir, Loki, Tempo) share the same deployment mode philosophy: a single binary with a -target flag that selects which component to run. This gives three deployment tiers:

Mode Description Use Case Ops Complexity
Monolithic All components in one process Dev, testing, PoC, small prod Low
Simple Scalable (SSD) Read/Write/Backend targets as separate services Mid-sized production Medium
Microservices Each component as independent pod Large-scale, hyperscale production High

Monolithic Mode

flowchart LR
    App["Applications"] --> Alloy["Alloy"]
    Alloy --> M["Mimir<br/>(all-in-one)"]
    Alloy --> L["Loki<br/>(all-in-one)"]
    Alloy --> T["Tempo<br/>(all-in-one)"]
    M --> S3["Object Storage"]
    L --> S3
    T --> S3
    G["Grafana"] -.-> M
    G -.-> L
    G -.-> T

    style M fill:#7b42bc,color:#fff
    style L fill:#2a7de1,color:#fff
    style T fill:#e65100,color:#fff
    style G fill:#ff6600,color:#fff

Simple Scalable Deployment

flowchart TB
    subgraph MimirSSD["Mimir (Simple Scalable)"]
        MW["Write Path<br/>(distributor + ingester)"]
        MR["Read Path<br/>(query-frontend + querier)"]
        MB["Backend<br/>(compactor + store-gateway)"]
    end

    subgraph LokiSSD["Loki (Simple Scalable)"]
        LW["Write Path<br/>(distributor + ingester)"]
        LR["Read Path<br/>(query-frontend + querier)"]
        LB["Backend<br/>(compactor + index-gateway)"]
    end

    subgraph TempoSSD["Tempo (Simple Scalable)"]
        TW["Write Path<br/>(distributor + ingester)"]
        TR["Read Path<br/>(query-frontend + querier)"]
        TB2["Backend<br/>(compactor)"]
    end

    S3["Object Storage"]
    MW --> S3
    LW --> S3
    TW --> S3
    MR --> S3
    LR --> S3
    TR --> S3

    style MimirSSD fill:#7b42bc,color:#fff
    style LokiSSD fill:#2a7de1,color:#fff
    style TempoSSD fill:#e65100,color:#fff

Microservices Mode (Production)

flowchart TB
    subgraph MimirMS["Mimir Microservices"]
        MD["Distributor"]
        MI["Ingester ×3"]
        MQF["Query Frontend"]
        MQ["Querier ×2"]
        MSG["Store-Gateway ×2"]
        MC["Compactor"]
    end

    subgraph LokiMS["Loki Microservices"]
        LD["Distributor"]
        LI["Ingester ×3"]
        LQF["Query Frontend"]
        LQ["Querier ×2"]
        LIG["Index Gateway"]
        LC["Compactor"]
    end

    subgraph TempoMS["Tempo Microservices"]
        TD["Distributor"]
        TI["Ingester ×3"]
        TQF["Query Frontend"]
        TQ["Querier ×2"]
        TMG["Metrics Generator"]
        TC["Compactor"]
    end

    S3["Object Storage<br/>(3 separate buckets)"]

    MI --> S3
    MSG --> S3
    MC --> S3
    LI --> S3
    LIG --> S3
    LC --> S3
    TI --> S3
    TC --> S3
    TMG -->|"remote_write"| MD

    style MimirMS fill:#7b42bc,color:#fff
    style LokiMS fill:#2a7de1,color:#fff
    style TempoMS fill:#e65100,color:#fff
    style S3 fill:#0d1117,color:#fff

Full Production Topology

flowchart TB
    subgraph Apps["Applications & Infrastructure"]
        App["Services<br/>(OTel SDK)"]
        K8s["Kubernetes<br/>Nodes"]
    end

    subgraph Collection["Collection Layer"]
        Alloy["Grafana Alloy<br/>(DaemonSet)"]
    end

    subgraph Backends["LGTM Backends (Microservices)"]
        Mimir["Mimir<br/>📊 Metrics"]
        Loki["Loki<br/>📝 Logs"]
        Tempo["Tempo<br/>🔍 Traces"]
        Pyro["Pyroscope<br/>🔥 Profiles"]
    end

    subgraph Storage["Object Storage"]
        B1["mimir-blocks (S3)"]
        B2["loki-chunks (S3)"]
        B3["tempo-traces (S3)"]
        B4["pyroscope-data (S3)"]
    end

    subgraph Grafana["Grafana (HA)"]
        G1["Pod 1"]
        G2["Pod 2"]
        G3["Pod 3"]
    end

    subgraph Support["Supporting Services"]
        PG["PostgreSQL<br/>(Grafana DB)"]
        Redis["Redis<br/>(Sessions)"]
        LB["Ingress / LB"]
        MC["Memcached<br/>(Query Cache)"]
    end

    Apps --> Alloy
    K8s --> Alloy
    Alloy -->|remote_write| Mimir
    Alloy -->|push| Loki
    Alloy -->|OTLP| Tempo
    Alloy -->|push| Pyro

    Mimir --> B1
    Loki --> B2
    Tempo --> B3
    Pyro --> B4

    LB --> G1 & G2 & G3
    G1 --> PG
    G1 --> Redis
    Mimir --> MC
    Loki --> MC

    Grafana -.-> Mimir
    Grafana -.-> Loki
    Grafana -.-> Tempo
    Grafana -.-> Pyro

    style Apps fill:#0d7377,color:#fff
    style Collection fill:#ff6600,color:#fff
    style Backends fill:#2a2d3e,color:#fff
    style Storage fill:#0d1117,color:#fff
    style Grafana fill:#ff6600,color:#fff
    style Support fill:#1a1d2e,color:#fff

Object Storage Layout

Critical rule: Each LGTM component must use separate buckets (or at minimum, separate prefixes within a bucket). Never share the same path.

Component Recommended Bucket Contents
Mimir (blocks) observability-mimir-blocks TSDB blocks (2h intervals)
Mimir (ruler) observability-mimir-ruler Recording and alerting rules
Mimir (alertmanager) observability-mimir-alertmanager Alertmanager state
Loki (chunks + index) observability-loki-chunks Compressed log chunks + TSDB index
Tempo (traces) observability-tempo-traces Parquet trace blocks + bloom filters
Pyroscope (profiles) observability-pyroscope-data Profile blocks

Kubernetes Deployment Matrix

Component Helm Chart Pods (Min HA) Scaling Dimension Key Resource
Grafana grafana/grafana 2–3 HPA (CPU/mem) Memory
Mimir grafana/mimir-distributed 7+ (dist×1, ing×3, q×2, sg×1) Per-component HPA Memory (ingesters), CPU (queriers)
Loki grafana/loki 6+ (dist×1, ing×3, q×2) Per-component HPA Memory (ingesters), CPU (queriers)
Tempo grafana/tempo-distributed 5+ (dist×1, ing×3, q×1) Per-component HPA Memory (ingesters)
Pyroscope grafana/pyroscope 1–3 Replicas Memory
Alloy grafana/alloy 1 per node (DaemonSet) DaemonSet CPU, Memory
PostgreSQL External managed HA pair Managed service Disk IOPS
Redis External managed HA pair Managed service Memory
Memcached bitnami/memcached 2–3 Replicas Memory

Shared Infrastructure Patterns

Hash Rings

Mimir, Loki, and Tempo all use consistent hash rings for sharding data across ingesters. The ring is backed by: - memberlist (default, gossip-based, no external dependency) - Consul or etcd (for environments that already run them)

Caching

Cache Layer Purpose Technology
Query results cache Cache query responses Memcached (recommended) or Redis
Chunks cache Cache data chunks from object storage Memcached
Index cache Cache index lookups Memcached
Metadata cache Cache block metadata Memcached

Memcached is strongly recommended over Redis for cache layers due to lower latency and simpler scaling.