Maple Local
Run Maple as a single binary on your machine — OTLP ingest, an embedded ClickHouse, a query API, and the dashboard, with no cloud and no auth.
One Bun-compiled binary — OTLP ingest, an embedded ClickHouse, a query API, and the dashboard — running on 127.0.0.1. No cloud, no Tinybird, no auth.
curl -fsSL https://maple.dev/cli/install | sh maple start 🍁 maple · local mode● listening on http://127.0.0.1:4318OTLP/HTTP POST /v1/{traces,logs,metrics}query POST /local/querydashboard https://local.maple.devdata ~/.maple/datapid 48213 · stop with `maple stop`
- port :4318
- store chDB
- signals traces · logs · metrics
- deps none
Local mode is the fastest way to look at OpenTelemetry data — point any OTLP exporter at localhost, open the dashboard, and explore traces, logs, and metrics with no account and nothing to deploy. It’s the same query engine and UI as hosted Maple, running entirely on your machine. Everything is single-tenant: every row is stored under org_id = "local".
Install
curl -fsSL https://maple.dev/cli/install | sh
The installer detects your OS/arch, downloads the matching bundle from the latest GitHub release, verifies its checksum, installs the two files (maple + libchdb) into ~/.maple/bin, clears the macOS Gatekeeper quarantine, and symlinks maple onto your PATH. macOS (Apple Silicon) and Linux (x86_64 & arm64) are supported.
Prefer not to pipe to a shell? The script is
scripts/install.sh— read it first, or download a release bundle from GitHub Releases by hand. Uninstall withcurl -fsSL https://maple.dev/cli/uninstall | sh(your~/.maple/datais kept).
Start the server
maple start # OTLP ingest + embedded ClickHouse + query API on :4318
maple start --offline # …serve the UI bundled in the binary (no internet, no prompts)
maple start -d # …or detached; logs to ~/.maple/maple.log, stop with `maple stop`
maple start is the long-lived process: it owns the embedded ClickHouse (chDB) connection and hosts OTLP/HTTP ingest, the /local/query API, and (with --offline) the dashboard — all on one loopback port. Data persists in ~/.maple/data between runs.
Common flags: --port (default 4318), --data-dir (default ~/.maple/data), --offline, --background/-d, and --reset to wipe an incompatible store before starting. See the CLI reference for the full list, plus maple stop and maple reset.
Send telemetry
The server speaks OTLP/HTTP on POST /v1/{traces,logs,metrics} (protobuf or JSON, gzip optional) — the same protocol every OpenTelemetry SDK already exports. Point your app at it; no auth header is needed locally:
export OTEL_EXPORTER_OTLP_ENDPOINT="http://127.0.0.1:4318"
export OTEL_SERVICE_NAME="my-service"
That’s it — most exporters default to protobuf and work out of the box. For language-specific setup (custom spans, log correlation, framework auto-instrumentation), follow the instrumentation guides. Any data you can already send to hosted Maple flows into local mode unchanged.
- OTLP exporter your app / SDK
- POST /v1/* ingest · :4318
- chDB store ~/.maple/data
- POST /local/query query API
- dashboard · CLI read your data
/local/query HTTP contract the dashboard uses.
Open the dashboard
By default maple start points you at the auto-updating dashboard hosted at local.maple.dev, which talks back to your binary on loopback (the startup banner prints a link with the bound ?port=). Because that page is a public origin reaching a local server, Chrome may show a one-time “access devices on your local network” prompt.
Pass --offline to serve the dashboard bundled inside the binary from 127.0.0.1 instead: same-origin, no prompt, and it works with no internet. The banner always prints the right URL for the mode you chose.
Query from the terminal
The same binary is also a query CLI. Every command runs against the running server and prints JSON by default (add --format table for an aligned table, or --debug to see the compiled SQL on stderr):
maple services # active services at a glance
maple traces --service api --since 1h # recent spans for one service
maple errors --since 24h # error groups by fingerprint
maple query "SELECT count() FROM traces"
services
04-
maple servicesthroughput, error rate, P95 per service -
maple diagnose <svc>health, top errors, recent traces & logs -
maple service-mapdependency edges with call & error rates -
maple top-ops <svc>operations ranked by a metric
traces
03-
maple tracessearch spans by service, duration, error -
maple trace <id>full span tree + correlated logs -
maple slow-tracesthe slowest traces with duration stats
errors
02-
maple errorserror groups by fingerprint -
maple error <hash>one group: sample traces + timeseries
logs
02-
maple logssearch by service, severity, text, trace -
maple log-patternscluster logs into noisy templates
analytics
03-
maple timeseriestime-bucketed latency, error rate, apdex -
maple breakdowntop-N by service / span / status / method -
maple comparetwo windows side by side (regressions)
metrics & sql
03-
maple metricslist available metrics -
maple attributes keysdiscover attribute keys & values -
maple query "<sql>"raw ClickHouse SQL (local only)
Most query flags are shared: --since (e.g. 30m, 1h, 24h, 7d) or absolute --start/--end, --service/-s, --env/-e, and --limit/-n. The full surface — every command, argument, and flag — lives in the CLI reference.
Local vs. remote
The same CLI talks to either your local server or a hosted Maple workspace. The mode is resolved per command: an explicit --local/--remote flag wins, then a pinned default (maple use local|remote|auto), then auto-detect — a stored token implies remote, otherwise it probes the local server’s /health. Run maple whoami to see what’s resolved. Connect a remote workspace with maple login; details are in the CLI reference.
How it works
One Bun-compiled binary is both the CLI and the server, talking to ClickHouse in-process via bun:ffi → libchdb (no subprocess, no second language). For the architecture, the /local/query contract, the UI-origin model, and the release bundle, see the local-mode design doc.