# niklasfrick/spark-dashboard architecture

> Architecture diagram of the GitHub repository niklasfrick/spark-dashboard, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-13). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/niklasfrick/spark-dashboard
- Repository: https://github.com/niklasfrick/spark-dashboard

## Overview

#### Purpose and Entry Points
Spark Dashboard is a Linux/NVIDIA monitoring service for host hardware and vLLM inference engines. The Rust binary is the production entry point; it serves the embedded React dashboard, REST configuration API, and WebSockets. Key paths: `src/main.rs`, `src/server.rs`, `src/cli/service.rs`.

#### Backend Runtime and Orchestration
`main` parses CLI/environment configuration, initializes shared state, and starts independent Tokio collector tasks plus Axum. Collectors publish snapshots through a bounded broadcast channel so slow/disconnected browser clients do not control collection. Key paths: `src/main.rs`, `src/metrics/mod.rs`, `src/engines/mod.rs`.

#### Host Metrics Collection
The hardware collector polls at a configurable interval (default 1 second), assembling CPU, memory, disk, network, and multi-GPU snapshots. GPU collection relies on NVIDIA/NVML; CPU/system counters use Linux-facing sources such as sysinfo/procfs. It also supports GPU simulation for development and unified-memory detection. Key paths: `src/metrics/gpu.rs`, `src/metrics/cpu.rs`, `src/metrics/memory.rs`.

#### Engine Discovery and vLLM Monitoring
Engine collection is separate from hardware collection. It discovers vLLM processes and, when Docker socket access exists, vLLM containers; explicit engine URLs can override discovery. The vLLM adapter polls Prometheus-format metrics and tracks engine lifecycle/state, model metadata, latency, throughput, requests, and cache metrics. Key paths: `src/engines/detector.rs`, `src/engines/vllm.rs`, `src/engines/prometheus.rs`.

#### Delivery, API, and Persistence Boundaries
Axum exposes `/ws` for metric streams and `/api/dashboard` for a shared dashboard document. The backend treats configuration as opaque, size-limited bytes; `config_store` handles atomic persistence and read-only-state behavior. Optional `/ws/logs` uses Docker APIs to fan out logs only for tracked container engines. Production static assets are embedded; unmatched API routes remain API 404s rather than falling through to the SPA. Key paths: `src/server.rs`, `src/ws.rs`, `src/config_store.rs`.

#### React Dashboard Data Flow
The Vite/React client opens the WebSocket, reconnects on failure, batches received snapshots, and retains rolling history in circular buffers. `Dashboard` renders host metrics, multi-engine aggregate/per-engine tabs, charts, gauges, controls, and optional logs. Dashboard layout/configuration is loaded and saved through the REST API, with schema/migration/preset logic entirely client-side. Key paths: `frontend/src/main.tsx`, `frontend/src/hooks/useMetrics.ts`, `frontend/src/components/views/Dashboard.tsx`.

#### Deployment and External Dependencies
Production supports a systemd-managed host binary and a GPU-enabled Docker image. The systemd service provisions a restricted service user and persistent state directory; Docker requires NVIDIA Container Toolkit and optionally mounts `/var/run/docker.sock` for container discovery/logs. External integrations are NVIDIA drivers/NVML, Docker Engine API via Bollard, vLLM HTTP/Prometheus endpoints, and optional authenticated engine APIs. Key paths: `deploy/host/systemd/spark-dashboard.service`, `deploy/docker/Dockerfile`, `deploy/docker/docker-compose.yml`.

Main entry points: [`src/main.rs`](https://github.com/niklasfrick/spark-dashboard/blob/main/src/main.rs) (Rust entry point), [`src/metrics/mod.rs`](https://github.com/niklasfrick/spark-dashboard/blob/main/src/metrics/mod.rs) (Hardware collector), [`src/engines/mod.rs`](https://github.com/niklasfrick/spark-dashboard/blob/main/src/engines/mod.rs) (Engine collector), [`src/server.rs`](https://github.com/niklasfrick/spark-dashboard/blob/main/src/server.rs) (Axum server)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_backend["Rust backend"]
  node_rust_entry["Rust entry point<br/>binary<br/>[main.rs]"]
  node_service_cli["Service CLI<br/>service management<br/>[service.rs]"]
  node_server["Axum server<br/>HTTP/WebSocket server<br/>[server.rs]"]
  node_snapshot_bus["Snapshot broadcast<br/>bounded channel<br/>[mod.rs]"]
  node_hardware_collector["Hardware collector<br/>Tokio collector<br/>[mod.rs]"]
  node_gpu_metrics["GPU metrics<br/>NVML collector<br/>[gpu.rs]"]
  node_host_metrics["CPU and memory metrics<br/>Linux collector<br/>[cpu.rs]"]
  node_memory_metrics["Memory metrics<br/>Linux collector<br/>[memory.rs]"]
  node_engine_collector["Engine collector<br/>Tokio collector<br/>[mod.rs]"]
  node_engine_detector["vLLM discovery<br/>process/container discovery<br/>[detector.rs]"]
  node_vllm_adapter["vLLM adapter<br/>engine monitor<br/>[vllm.rs]"]
  node_prometheus_polling["Prometheus polling<br/>metrics parser<br/>[prometheus.rs]"]
  node_config_store[("Dashboard config store<br/>atomic persistence<br/>[config_store.rs]")]
  node_websocket_stream["Metrics WebSocket<br/>/ws endpoint<br/>[ws.rs]"]
end

subgraph group_frontend["React dashboard"]
  node_react_entry["React client<br/>Vite entry point<br/>[main.tsx]"]
  node_metrics_hook["Metrics data hook<br/>WebSocket client<br/>[useMetrics.ts]"]
  node_dashboard["Dashboard UI<br/>React view<br/>[Dashboard.tsx]"]
end

subgraph group_deployment["Deployment"]
  node_systemd_service["Systemd host service<br/>host deployment"]
  node_docker_image["GPU Docker deployment<br/>container deployment"]
  node_docker_compose["Docker Compose<br/>container configuration<br/>[docker-compose.yml]"]
end

node_nvml{{"NVIDIA drivers / NVML<br/>external integration"}}
node_docker_api{{"Docker Engine API<br/>external integration"}}
node_vllm_endpoints{{"vLLM endpoints<br/>external integration"}}

node_service_cli -->|"manages"| node_rust_entry
node_rust_entry -->|"starts"| node_hardware_collector
node_rust_entry -->|"starts"| node_engine_collector
node_rust_entry -->|"starts"| node_server
node_hardware_collector -->|"collects"| node_gpu_metrics
node_hardware_collector -->|"collects"| node_host_metrics
node_host_metrics -->|"includes"| node_memory_metrics
node_gpu_metrics -->|"uses"| node_nvml
node_hardware_collector -->|"publishes snapshots"| node_snapshot_bus
node_engine_collector -->|"discovers"| node_engine_detector
node_engine_detector -.->|"inspects containers"| node_docker_api
node_engine_collector -->|"monitors engines"| node_vllm_adapter
node_vllm_adapter -->|"uses"| node_prometheus_polling
node_prometheus_polling -->|"polls"| node_vllm_endpoints
node_engine_collector -->|"publishes snapshots"| node_snapshot_bus
node_server -->|"exposes /ws"| node_websocket_stream
node_snapshot_bus -->|"streams snapshots"| node_websocket_stream
node_server -->|"serves /api/dashboard"| node_config_store
node_react_entry -->|"initializes"| node_metrics_hook
node_metrics_hook -->|"connects /ws"| node_websocket_stream
node_metrics_hook -->|"supplies history"| node_dashboard
node_dashboard -->|"loads and saves config"| node_server
node_systemd_service -->|"runs"| node_rust_entry
node_docker_image -->|"packages"| node_rust_entry
node_docker_compose -->|"deploys"| node_docker_image
node_docker_image -.->|"optional socket mount"| node_docker_api

click node_rust_entry "https://github.com/niklasfrick/spark-dashboard/blob/main/src/main.rs"
click node_service_cli "https://github.com/niklasfrick/spark-dashboard/blob/main/src/cli/service.rs"
click node_server "https://github.com/niklasfrick/spark-dashboard/blob/main/src/server.rs"
click node_snapshot_bus "https://github.com/niklasfrick/spark-dashboard/blob/main/src/metrics/mod.rs"
click node_hardware_collector "https://github.com/niklasfrick/spark-dashboard/blob/main/src/metrics/mod.rs"
click node_gpu_metrics "https://github.com/niklasfrick/spark-dashboard/blob/main/src/metrics/gpu.rs"
click node_host_metrics "https://github.com/niklasfrick/spark-dashboard/blob/main/src/metrics/cpu.rs"
click node_memory_metrics "https://github.com/niklasfrick/spark-dashboard/blob/main/src/metrics/memory.rs"
click node_engine_collector "https://github.com/niklasfrick/spark-dashboard/blob/main/src/engines/mod.rs"
click node_engine_detector "https://github.com/niklasfrick/spark-dashboard/blob/main/src/engines/detector.rs"
click node_vllm_adapter "https://github.com/niklasfrick/spark-dashboard/blob/main/src/engines/vllm.rs"
click node_prometheus_polling "https://github.com/niklasfrick/spark-dashboard/blob/main/src/engines/prometheus.rs"
click node_config_store "https://github.com/niklasfrick/spark-dashboard/blob/main/src/config_store.rs"
click node_websocket_stream "https://github.com/niklasfrick/spark-dashboard/blob/main/src/ws.rs"
click node_react_entry "https://github.com/niklasfrick/spark-dashboard/blob/main/frontend/src/main.tsx"
click node_metrics_hook "https://github.com/niklasfrick/spark-dashboard/blob/main/frontend/src/hooks/useMetrics.ts"
click node_dashboard "https://github.com/niklasfrick/spark-dashboard/blob/main/frontend/src/components/views/Dashboard.tsx"
click node_systemd_service "https://github.com/niklasfrick/spark-dashboard/blob/main/deploy/host/systemd/spark-dashboard.service"
click node_docker_image "https://github.com/niklasfrick/spark-dashboard/blob/main/deploy/docker/Dockerfile"
click node_docker_compose "https://github.com/niklasfrick/spark-dashboard/blob/main/deploy/docker/docker-compose.yml"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_rust_entry,node_service_cli,node_server,node_snapshot_bus,node_hardware_collector,node_gpu_metrics,node_host_metrics,node_memory_metrics,node_engine_collector,node_engine_detector,node_vllm_adapter,node_prometheus_polling,node_config_store,node_websocket_stream toneBlue
class node_react_entry,node_metrics_hook,node_dashboard toneAmber
class node_systemd_service,node_docker_image,node_docker_compose toneMint
class node_nvml,node_docker_api,node_vllm_endpoints toneNeutral
```

## Components

### Rust backend

- [Rust entry point](https://github.com/niklasfrick/spark-dashboard/blob/main/src/main.rs): binary · Parses configuration and starts collectors and Axum. · `src/main.rs`
- [Service CLI](https://github.com/niklasfrick/spark-dashboard/blob/main/src/cli/service.rs): service management · `src/cli/service.rs`
- [Axum server](https://github.com/niklasfrick/spark-dashboard/blob/main/src/server.rs): HTTP/WebSocket server · Serves APIs, WebSockets, and embedded assets. · `src/server.rs`
- [Snapshot broadcast](https://github.com/niklasfrick/spark-dashboard/blob/main/src/metrics/mod.rs): bounded channel · Decouples collectors from browser clients. · `src/metrics/mod.rs`
- [Hardware collector](https://github.com/niklasfrick/spark-dashboard/blob/main/src/metrics/mod.rs): Tokio collector · Produces periodic host and GPU snapshots. · `src/metrics/mod.rs`
- [GPU metrics](https://github.com/niklasfrick/spark-dashboard/blob/main/src/metrics/gpu.rs): NVML collector · Collects multi-GPU data, simulation, and unified-memory status. · `src/metrics/gpu.rs`
- [CPU and memory metrics](https://github.com/niklasfrick/spark-dashboard/blob/main/src/metrics/cpu.rs): Linux collector · Reads CPU, memory, disk, and network counters. · `src/metrics/cpu.rs`
- [Memory metrics](https://github.com/niklasfrick/spark-dashboard/blob/main/src/metrics/memory.rs): Linux collector · `src/metrics/memory.rs`
- [Engine collector](https://github.com/niklasfrick/spark-dashboard/blob/main/src/engines/mod.rs): Tokio collector · Discovers and monitors inference engines independently of host metrics. · `src/engines/mod.rs`
- [vLLM discovery](https://github.com/niklasfrick/spark-dashboard/blob/main/src/engines/detector.rs): process/container discovery · Finds processes and Docker containers; explicit URLs override discovery. · `src/engines/detector.rs`
- [vLLM adapter](https://github.com/niklasfrick/spark-dashboard/blob/main/src/engines/vllm.rs): engine monitor · Tracks lifecycle, model, latency, throughput, requests, and cache data. · `src/engines/vllm.rs`
- [Prometheus polling](https://github.com/niklasfrick/spark-dashboard/blob/main/src/engines/prometheus.rs): metrics parser · `src/engines/prometheus.rs`
- [Dashboard config store](https://github.com/niklasfrick/spark-dashboard/blob/main/src/config_store.rs): atomic persistence · Stores opaque size-limited bytes and handles read-only state. · `src/config_store.rs`
- [Metrics WebSocket](https://github.com/niklasfrick/spark-dashboard/blob/main/src/ws.rs): /ws endpoint · `src/ws.rs`

### React dashboard

- [React client](https://github.com/niklasfrick/spark-dashboard/blob/main/frontend/src/main.tsx): Vite entry point · `frontend/src/main.tsx`
- [Metrics data hook](https://github.com/niklasfrick/spark-dashboard/blob/main/frontend/src/hooks/useMetrics.ts): WebSocket client · Reconnects, batches snapshots, and maintains rolling circular history. · `frontend/src/hooks/useMetrics.ts`
- [Dashboard UI](https://github.com/niklasfrick/spark-dashboard/blob/main/frontend/src/components/views/Dashboard.tsx): React view · Renders host and engine views, charts, controls, and optional logs. · `frontend/src/components/views/Dashboard.tsx`

### Deployment

- [Systemd host service](https://github.com/niklasfrick/spark-dashboard/blob/main/deploy/host/systemd/spark-dashboard.service): host deployment · Runs a restricted service user with persistent state. · `deploy/host/systemd/spark-dashboard.service`
- [GPU Docker deployment](https://github.com/niklasfrick/spark-dashboard/blob/main/deploy/docker/Dockerfile): container deployment · Uses NVIDIA runtime and can mount the Docker socket. · `deploy/docker/Dockerfile`
- [Docker Compose](https://github.com/niklasfrick/spark-dashboard/blob/main/deploy/docker/docker-compose.yml): container configuration · `deploy/docker/docker-compose.yml`

### Other components

- **NVIDIA drivers / NVML**: external integration
- **Docker Engine API**: external integration · Supports container discovery and tracked-engine logs.
- **vLLM endpoints**: external integration · HTTP and Prometheus endpoints may require authentication.

## Connections

- Service CLI → Rust entry point: manages
- Rust entry point → Hardware collector: starts
- Rust entry point → Engine collector: starts
- Rust entry point → Axum server: starts
- Hardware collector → GPU metrics: collects
- Hardware collector → CPU and memory metrics: collects
- CPU and memory metrics → Memory metrics: includes
- GPU metrics → NVIDIA drivers / NVML: uses
- Hardware collector → Snapshot broadcast: publishes snapshots
- Engine collector → vLLM discovery: discovers
- vLLM discovery → Docker Engine API: inspects containers
- Engine collector → vLLM adapter: monitors engines
- vLLM adapter → Prometheus polling: uses
- Prometheus polling → vLLM endpoints: polls
- Engine collector → Snapshot broadcast: publishes snapshots
- Axum server → Metrics WebSocket: exposes /ws
- Snapshot broadcast → Metrics WebSocket: streams snapshots
- Axum server → Dashboard config store: serves /api/dashboard
- React client → Metrics data hook: initializes
- Metrics data hook → Metrics WebSocket: connects /ws
- Metrics data hook → Dashboard UI: supplies history
- Dashboard UI → Axum server: loads and saves config
- Systemd host service → Rust entry point: runs
- GPU Docker deployment → Rust entry point: packages
- Docker Compose → GPU Docker deployment: deploys
- GPU Docker deployment → Docker Engine API: optional socket mount
