Under the hood

Architecture, no magic.

Four containers, two databases, one license check. That's the whole stack.

What's in the box

Every service mlab IR runs, and what it does. Tap a row to expand.

01 / Service
app

Rust + Actix-web. Serves the UI, exposes the REST API, handles auth and RBAC, talks to both databases. Stateless — restart any time. Healthcheck on /healthz.

02 / Service
executor

Background worker. Runs scheduled jobs: license challenges, observable enrichment, SLA timers, webhook delivery with retries, report generation. Writes analytics to ClickHouse.

03 / Datastore
MySQL 8

Transactional store: alerts, cases, observables, users, attachments metadata, audit log. Migrations auto-run on app boot.

04 / Datastore
ClickHouse

Analytics store: high-volume timeline events, metrics rollups, search indices. Optimised for dashboards and queue filters.

05 / External
License check — mlab.sh

The only outbound call. Once per hour, the executor sends a signed HMAC challenge to mlab.sh/api/v1/ir/license/validate. Result is cached locally with a 48h grace window. No telemetry, no usage analytics, no error reporting to a SaaS.

Request to resolution

  1. Upstream system POSTs to app:/api/v1/alerts.
  2. app validates, normalizes, writes to MySQL, emits a timeline event to ClickHouse.
  3. Analyst loads the queue — app reads MySQL (state) + ClickHouse (filters).
  4. Escalation creates a case, attaches observables, fires webhooks via executor.
  5. On resolution, executor generates the report and stores it on the uploads volume.

Topology

Single host: all four containers via Docker Compose. Suitable up to several hundred analysts.

Scaled out: MySQL and ClickHouse on dedicated hosts; app and executor stay stateless and scale horizontally behind a reverse proxy.

No Kubernetes operator, no Helm chart maintained as a separate product. If you run K8s you convert the compose file — the service contract is plain.