Skip to content
Maple Docs
Open app

Maple Local

Run the whole of Maple as one binary on your machine: OTLP ingest, an embedded ClickHouse, a query API, the dashboard and a CLI. No account, no containers, nothing to deploy.

Maple Local is the full product running on your machine, free, for local development. Point any OpenTelemetry exporter at localhost, open the dashboard, and explore traces, logs, metrics, errors and a service map. It is not a client for the hosted service and needs no account. Your telemetry is stored and queried on your machine. The CLI does make a few network calls of its own by default, listed in What connects to the internet.

Two commands get you running:

brew install Makisuo/tap/maple
maple start

What you get

SurfaceWhat it is
OTLP/HTTP ingestPOST /v1/{traces,logs,metrics} on port 4318, protobuf or JSON, gzip optional. Any OTel SDK works unchanged.
DashboardThe same Maple UI, either auto-updating from local.maple.dev or bundled in the binary for offline use.
CLImaple services, maple traces, maple errors and the other query commands in the CLI reference, printing JSON you can pipe into jq or an agent.
Raw SQLmaple query "<sql>" against the embedded store when the typed commands don’t cover it.

Data lives in ~/.maple/data and survives restarts. See Your data for retention and restore points.

1. Install

Both methods install the same two-file bundle, maple and libchdb, on macOS and Linux, and verify its checksum.

Homebrew

brew install Makisuo/tap/maple

Upgrade with brew upgrade maple and remove it with brew uninstall maple.

Install script

curl -fsSL https://maple.dev/cli/install | sh

The script detects your OS and architecture, downloads the matching bundle from the latest GitHub release, installs it into ~/.maple/bin, clears the macOS Gatekeeper quarantine, and links maple onto your PATH. Read scripts/install.sh before piping it to a shell. Upgrade in place with maple update. To remove it:

curl -fsSL https://maple.dev/cli/uninstall | sh

Uninstalling keeps ~/.maple/data. If you later move to Homebrew, delete the old maple symlink on your PATH so your shell finds Homebrew’s binary.

To install by hand, download a release bundle from GitHub Releases and keep maple and libchdb in the same directory.

2. Start the server

maple start            # ingest, store and query API on :4318
maple start --offline  # also serve the dashboard from the binary
maple start -d         # run detached; stop with `maple stop`

maple start is the one long-lived process. It owns the embedded database and hosts ingest, the query API and, with --offline, the dashboard, all on a single port bound to loopback. The startup banner prints the addresses and a link to open. A detached server writes its output to ~/.maple/maple.log.

The flags you are likely to touch:

FlagDefaultUse it when
--port <int>4318Something else already listens on 4318
--data-dir <path>~/.maple/dataYou want a second, separate store
--offlineoffYou have no internet, or want the UI same-origin
--background, -doffYou want it out of the way; maple stop ends it
--resetoffA new binary refuses an old store; wipes live data, keeps checkpoints

Everything else, including bind and advertise hosts, checkpoint cadence and recovery policy, is in the CLI reference.

3. Send telemetry

Point your app at the server. No auth header is needed locally, and most exporters default to protobuf, so this is usually all it takes:

export OTEL_EXPORTER_OTLP_ENDPOINT="http://127.0.0.1:4318"
export OTEL_SERVICE_NAME="my-service"

Your exporter posts to /v1/traces, /v1/logs and /v1/metrics. The server writes each batch to the embedded ClickHouse store in ~/.maple/data, and the dashboard and the CLI read it back through POST /local/query.

For custom spans, log correlation and framework auto-instrumentation, follow the guide for your language in Instrument your application. Anything you can send to hosted Maple flows into the local server unchanged.

4. Open the dashboard

The banner links to the dashboard. There are two ways to serve it:

Default, from local.maple.devOffline
Where the UI comes fromHosted, always the latest buildBundled inside the binary
Talks to your data overLoopback, from a public originSame origin
Needs internetYes, to load the pageNo
Browser promptChrome asks once to “access devices on your local network”None

Both read the same local store. Start with --offline when you are on a plane, behind a strict proxy, or would rather not see the prompt.

Reaching it from another machine

Bind to all interfaces with two secrets: an ingest key for OTLP and an access token for the dashboard and queries.

export MAPLE_LOCAL_INGEST_KEY="$(openssl rand -hex 32)"
export MAPLE_LOCAL_ACCESS_TOKEN="$(openssl rand -hex 32)"
maple start --host 0.0.0.0 --offline
  • Exporters send the ingest key as Authorization: Bearer <key>, e.g. OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer%20<key>". It can write telemetry, never read it.
  • The dashboard asks for the access token once and keeps you signed in for 30 days. Scripts send it as Authorization: Bearer <token>; maple CLI commands send it when MAPLE_LOCAL_ACCESS_TOKEN is set.

Without the secrets the server still starts and its banner warns you: anyone who can reach the port can use the UI, run raw SQL through /local/query, and send OTLP data. The maintenance routes (checkpoint, scoped delete, day retirement and the local event routes) require a token that maple start writes beside the data directory with mode 0600 (<data-dir>.maintenance-token, and <data-dir>.event-consumer-token for event consumers). They are only as safe as those files. /local/retention/retire deletes a day of live data. The full route list is in the CLI reference.

Put a TLS-terminating proxy in front of anything reachable from the internet; the session cookie is marked Secure when the proxy forwards X-Forwarded-Proto: https. To run it on a server or a container platform, use the image described in Self-hosting.

Query from the terminal

The same binary is the 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
maple traces --service api --since 1h  # recent spans
maple errors --since 24h               # error groups
maple query "SELECT count() FROM traces"
CommandWhat it does
maple services · diagnose <svc> · service-map · top-ops <svc>Service health, dependencies and the hottest operations
maple traces · trace <id> · slow-tracesSearch spans, open one span tree, find the slowest
maple errors · error <hash>Error groups by fingerprint, and one group in detail
maple logs · log-patternsSearch logs, or cluster them into templates
maple timeseries · breakdown · compareBucketed metrics, top-N breakdowns, two windows
maple metrics · attributes keysDiscover metrics and attribute keys
maple query "<sql>"Read-only SQL when the typed commands don’t cover it

Most query commands share the same filters: --since (30m, 1h, 24h, 7d) or absolute --start/--end, --service/-s, --env/-e, and --limit/-n. The CLI reference has every command, argument and flag.

Your data

  • Where it lives. ~/.maple/data, or whatever --data-dir you passed.
  • Retention. Logs and traces are kept for 30 days, metrics for 90. maple start --minimum-raw-telemetry-retention-days <n> raises the floor for raw logs, traces and metrics (90 to 3,650 days). Hosted retention is on Retention.
  • Restore points. The running server takes a checkpoint on a timer, and maple restore rolls the store back to one. Cadence, restore and unclean-shutdown behavior are on Checkpoints and archives.
  • Starting over. maple reset clears live data and keeps checkpoints. maple start --reset does the same in one step after an incompatible upgrade.
  • Keeping history. maple archive exports whole days as Parquet files you can open in DuckDB. See Archives.

What connects to the internet

Your telemetry and query results stay on your machine. These calls go out by default:

CallWhenTurn it off
CLI traces and metricsEvery command, and every request maple start handlesMAPLE_TELEMETRY=off
Release check on GitHubAt most once a day, only in an interactive terminalMAPLE_NO_UPDATE_CHECK=1 (Homebrew installs set it)
Dashboard page from local.maple.devWhen you open the dashboardmaple start --offline

The CLI sends its own telemetry to https://ingest.maple.dev with an ingest key built into the binary. It describes the CLI, not your data: it reports the service name maple-cli, the command, its duration and errors. For each OTLP request maple start handles it records the signal, the body size and the number of items, never the payload. For each /local/query request it records only the timing and whether it succeeded. SQL text, filter values and error messages are never exported, and the CLI’s own logs are not sent at all. MAPLE_INGEST_KEY, MAPLE_ENDPOINT and MAPLE_ENVIRONMENT redirect or relabel this export. With MAPLE_ENDPOINT unset, the CLI uses OTEL_EXPORTER_OTLP_ENDPOINT if it is set, and MAPLE_REGION=eu switches the default to https://ingest.eu.maple.dev. So if you export OTEL_EXPORTER_OTLP_ENDPOINT for your app in the same shell, the CLI’s own telemetry goes there too. See Environment variables.

One CLI, two backends

The same maple also talks to a hosted Maple workspace. Sign in from the terminal and it opens your browser:

maple auth login   # browser sign-in
maple whoami       # the backend a command would use now
maple use local    # pin it; `maple use auto` undoes this

To sign in without a browser, pipe a token into maple auth login --with-token.

For each command, an explicit --local or --remote wins, then the default pinned with maple use, then auto-detect: a set MAPLE_LOCAL_URL means local, otherwise a stored login means remote, otherwise the CLI probes the local server (GET /local/status).

Every query command works against both, maple query included. Against hosted Maple, the SQL must include $__orgFilter and returns at most 100 rows. The macros expand locally too, so one query runs unchanged in both modes. Quote it in single quotes so the shell leaves $__ alone:

maple query 'SELECT count() FROM traces
  WHERE $__orgFilter AND $__timeFilter(Timestamp)' --since 1h

See Using the CLI with hosted Maple.

Under the hood

One compiled binary is both the CLI and the server. It talks to ClickHouse in-process through libchdb, so there is no subprocess and no second runtime to install. Short-lived CLI commands and the dashboard read the store over the same POST /local/query contract. The architecture, the UI origin model and the release bundle are described in the local mode design doc.