Maple Local · free · works offline

The local observability stack, in one command.

Point any OpenTelemetry exporter at localhost and see traces, logs, metrics, errors, sessions, and a service map while you build. One process instead of a compose file. No containers, no account, no cloud — and nothing to sign up for, ever.

brew install Makisuo/tap/maple
~/your-app local
maple start
🍁 maple · local mode
● listening on http://127.0.0.1:4318
OTLP/HTTP POST /v1/{traces,logs,metrics}
query POST /local/query
dashboard https://local.maple.dev
data ~/.maple/data
pid 48213 · stop with `maple stop`

1 process1 port0 containers0 accounts

Replace the compose file

One process instead of five containers

The usual local setup is a collector, one backend per signal, and a dashboard on top: five containers, five config files, and three different UIs. Maple Local is one process that does all of it, started with one command, on one port.

The usual stack docker-compose.yml
Maple Local one process
Receive
otel-collector :4317 :4318 collector.yaml
Traces
jaeger :16686 own UI
Metrics
prometheus :9090 scrape config, own UI
Logs
loki :3100 loki.yaml
Dashboards
grafana :3000 datasources, provisioning, own UI
maple start :4318, one UI, no config file

Every row on the left, plus errors, sessions, and a service map, from a single process.

5 containers 5 config files 3 UIs
1 process 1 port 1 UI

Light describes the running footprint: one process, one port, nothing to orchestrate before your app starts. The download itself is not small; the embedded database engine is a few hundred megabytes on disk.

Standalone by design

No account. No cloud. Nothing leaves your machine.

Maple Local is not a trial, a free tier, or a client for a hosted service. It is the complete product running on 127.0.0.1, and it stays complete whether or not you ever touch anything else Maple makes.

  1. OTLP exporter your app or SDK
  2. Ingest POST /v1/* on :4318
  3. Embedded store ~/.maple/data
  4. Query API same port
  5. Dashboard and CLI read it back
127.0.0.1 One process receives your telemetry, stores it, and answers every query from the dashboard and the CLI. Nothing in this loop leaves your machine.
  • No account, ever

    There is no sign-up, login, or license key. maple start is the whole onboarding, and nothing in the binary asks you to create anything.

  • Your telemetry stays on loopback

    Ingest, storage, and every query run on 127.0.0.1. The dashboard page loads from local.maple.dev by default so UI fixes ship without a new binary — your data never goes there. Pass --offline and the UI is served from the binary too.

  • Works with no internet

    With --offline everything, including the UI, comes out of the binary. The only other network call is a once-a-day check for a newer release — skipped for Homebrew installs, off with MAPLE_NO_UPDATE_CHECK=1.

  • You own the files

    Everything lives under ~/.maple. Seal a day into Parquet with maple archive and query it with DuckDB; uninstalling removes the binary and leaves your data directory alone.

  • The full product, not a viewer

    The same engine and views that run the hosted service: traces with correlated logs, log patterns, metrics, errors grouped by fingerprint, browser sessions, and a service map.

  • Source-available

    The whole platform is on GitHub under the Functional Source License, converting to Apache 2.0. Read the ingest path, the schema, and the installer before you trust them.

The dashboard

The full product, not a trace viewer

Six views, one dashboard, all reading your local store. The same screens you'd want in production, with your development traffic in them.

Traces

Full span trees with correlated logs

Search spans by service, duration, or error, then drill into any trace for its complete waterfall and the log lines emitted alongside it.

trace 9f3c · order fetch LIVE
edge GET /api/orders/8421 412ms
orders-api load_order 366ms
auth verify_jwt 38ms
orders-api fetch_line_items 184ms
postgres SELECT * FROM line_items 158ms
shipping rate_quote 96ms
fedex-api POST /rates 72ms
redis SET order:8421:rate 14ms
8 spans · 412ms wall queried 12.8B rows in 198ms
logs · volume · last 5hLIVE
14.0K logsin selected range
4 severities · 60 buckets · 5m eachwarn cluster 11:10–11:40 · error blip 11:50
logs · stream LIVE
12:04:18 INFO edge GET /api/orders/8421 200 412ms
12:04:18 INFO orders-api load_order order_id=8421 366ms
12:04:18 DEBUG auth verify_jwt iss=auth.maple.dev 38ms
12:04:18 INFO postgres SELECT line_items rows=12 158ms
12:04:18 INFO shipping rate_quote carrier=ups 96ms
12:04:18 WARN fedex-api POST /rates retried (1/3) 72ms
12:04:18 INFO redis SET order:8421:rate ttl=3600 14ms
12:04:19 INFO edge GET /api/cart 200 94ms
12:04:19 INFO cart-svc load_cart user=u_4109 58ms
12:04:19 DEBUG feature-flag evaluate fast_checkout=false
12:04:19 ERROR payments stripe.charge declined card=v•••4242 204ms
12:04:19 WARN payments fallback to authorize_only flow
12:04:19 INFO kafka produce orders.canceled offset=98041
12:04:20 INFO edge POST /webhooks/stripe 200 26ms
12:04:20 INFO events dispatch payment.failed → ops
12:04:20 DEBUG scheduler reschedule retry_at=12:04:25
12:04:20 INFO edge GET /api/inventory 200 41ms
12:04:20 INFO inventory lookup sku=SKU-9081 region=iad 23ms
12:04:20 WARN inventory stock low sku=SKU-9081 qty=3
12:04:21 INFO search query "red shoes" hits=412 82ms
12:04:21 INFO edge GET /api/recos 200 67ms
12:04:21 DEBUG recos model=v3.2 cohort=A2
12:04:21 INFO edge POST /api/feedback 201 18ms
12:04:21 INFO analytics track event=checkout_started
12:04:18 INFO edge GET /api/orders/8421 200 412ms
12:04:18 INFO orders-api load_order order_id=8421 366ms
12:04:18 DEBUG auth verify_jwt iss=auth.maple.dev 38ms
12:04:18 INFO postgres SELECT line_items rows=12 158ms
12:04:18 INFO shipping rate_quote carrier=ups 96ms
12:04:18 WARN fedex-api POST /rates retried (1/3) 72ms
12:04:18 INFO redis SET order:8421:rate ttl=3600 14ms
12:04:19 INFO edge GET /api/cart 200 94ms
12:04:19 INFO cart-svc load_cart user=u_4109 58ms
12:04:19 DEBUG feature-flag evaluate fast_checkout=false
12:04:19 ERROR payments stripe.charge declined card=v•••4242 204ms
12:04:19 WARN payments fallback to authorize_only flow
12:04:19 INFO kafka produce orders.canceled offset=98041
12:04:20 INFO edge POST /webhooks/stripe 200 26ms
12:04:20 INFO events dispatch payment.failed → ops
12:04:20 DEBUG scheduler reschedule retry_at=12:04:25
12:04:20 INFO edge GET /api/inventory 200 41ms
12:04:20 INFO inventory lookup sku=SKU-9081 region=iad 23ms
12:04:20 WARN inventory stock low sku=SKU-9081 qty=3
12:04:21 INFO search query "red shoes" hits=412 82ms
12:04:21 INFO edge GET /api/recos 200 67ms
12:04:21 DEBUG recos model=v3.2 cohort=A2
12:04:21 INFO edge POST /api/feedback 201 18ms
12:04:21 INFO analytics track event=checkout_started
14.2k events / minute retention 30d · structured
Logs

Search the stream, cluster the noise

Filter by service, severity, text, or trace ID — or run log-patterns to cluster lines into templates and surface the noisiest sources at a glance.

service map · last 60s LIVE
2.8k req/s edge req/s 12.4k err% 0.1% avg 8ms checkout-api req/s 4.2k err% 0.3% avg 24ms cart-svc req/s 8.1k err% 0.1% avg 18ms auth-svc req/s 4.2k err% 0.0% avg 6ms pricing req/s 2.8k err% 2.4% avg 142ms payments req/s 1.1k err% 0.5% avg 38ms redis DB calls/s 18.2k avg 2ms postgres DB calls/s 6.4k avg 14ms
8 services · 8 edges · 60s window pricing-svc · p99 +18% vs 1h ago
Service map

See how your services call each other

Dependency edges with call counts, error rates, and latency — reconstructed from the spans you've sent, entirely on your machine.

Built for the dev loop

Answers in the terminal you're already in

The same binary is a query CLI. Every command runs against the local server and prints JSON by default — add --format table for an aligned table, or --debug to see the query it ran.

  1. A test just failed maple traces --service api --errors --since 5m Pull the failing request's trace instead of adding console.logs.
  2. You changed a hot path maple compare --around "2026-09-06 14:00:00" Latency, error rate, and throughput before and after, side by side.
  3. Your agent is debugging maple diagnose api --since 15m Health, top errors, and recent traces as JSON a coding agent can read.
Install

One command in, one command out

Homebrew downloads the bundle for your platform from the latest GitHub release, verifies its checksum, and links the binary onto your PATH. Upgrades and removal are the Homebrew commands you already know, and uninstalling leaves your data directory in place. Prefer a script? The curl installer does the same thing into ~/.maple/bin.

Platforms
macOS (Apple Silicon and Intel), Linux (x86_64 and arm64)
Install
brew install Makisuo/tap/maple
Start
maple start
Upgrade
brew upgrade maple
Data
~/.maple/data
Uninstall
brew uninstall maple

Start on localhost. Stay there as long as you like.

One install, one command, and your next request shows up as a trace. No trial clock, no account, nothing to cancel later.

brew install Makisuo/tap/maple

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

Shipping to production later? The same CLI and the same endpoint swap work against Maple Cloud. maple auth login switches a command over and --local switches it back. Entirely optional.

FAQ

Common questions

Do I need a Maple account to use Maple Local?
No. There is no sign-up, login, license key, or trial. Install the binary, run `maple start`, point your OpenTelemetry exporter at localhost:4318, and open the dashboard. Nothing in the local product asks you to create an account, now or later.
Does any of my telemetry leave my machine?
No. Ingest, storage, and every query run on 127.0.0.1. By default the dashboard page is loaded from local.maple.dev so UI fixes ship without a new binary, but it only ever talks back to your local server; your data is never sent there. Run `maple start --offline` to serve the UI from the binary as well.
Does it work without an internet connection?
Yes. With `--offline` the binary serves everything, including the dashboard. The only other network call is a once-per-day check for a newer release, which Homebrew installs skip and which `MAPLE_NO_UPDATE_CHECK=1` disables.
What does it replace?
The docker compose stack most repos keep for local telemetry: an OpenTelemetry Collector, a trace backend such as Jaeger, Prometheus for metrics, Loki for logs, and Grafana on top. Maple Local is one process on one port with one UI that covers traces, logs, metrics, errors, sessions, and a service map.
How is it different from the hosted Maple service?
Same engine, same views, no account and no cloud. The hosted service adds what a team needs in production: multi-user access, alerting, retention at scale, and an MCP server for agents. Maple Local is complete on its own; the same CLI can talk to a hosted workspace if you ever want it to, but nothing requires it.
Is it open source, and what does it cost?
It is free and source-available. The whole platform is on GitHub under the Functional Source License, which converts to Apache 2.0. There is no paid tier of Maple Local and no usage limit.