Jupiter Metis Binary: self-host the Solana liquidity router
How to run jup-ag/metis-binary: Binary Key (10k staked JUP), Yellowstone gRPC, quote/swap/swap-instructions APIs, Docker/Fly, and how Metis differs from Jupiter Swap API V2 meta-aggregator.
devrels.xyz/a/259short linkJupiter Metis Binary: self-host the Solana liquidity router. Source and releases: github.com/jup-ag/metis-binary; product/docs: metis.builders.
What Metis is
Metis is Jupiter’s onchain multi-hop, multi-split routing engine — the pathfinder that walks Solana DEX liquidity (Raydium, Orca, Meteora, Pump, Phoenix, Sanctum, and dozens more). Marketing on metis.builders frames it as the Solana liquidity engine with 60+ venues; treat volume stats as product claims, not your SLA.
In the hosted Jupiter Swap API V2, Metis is one routing engine among several:
| Path | Endpoints | Engines | You get |
|---|---|---|---|
| Meta-Aggregator | /swap/v2/order + /execute | Metis, JupiterZ, Dflow, OKX | Assembled tx; managed landing; platform fees |
| Router (hosted) | /swap/v2/build (+ optional submit) | Metis only | Raw instructions; full tx control / CPI |
| Self-hosted binary | Your :8080 quote / swap / swap-instructions | Metis only | Same class of control as Router, on your metal — Binary Key gated |
Use the meta-aggregator when you want best price and least ops. Use metis-binary when latency, data residency, custom fee accounts, instruction composability, or independence from Jupiter’s public API rate limits matter enough to run the router yourself.
Repository
jup-ag/metis-binary is intentionally thin: Dockerfile (debian trixie-slim, amd64), release zips of metis-binary-x86_64-unknown-linux-gnu, and a Fly.io example. The algorithm and API surface are documented on metis.builders — not reimplemented in the public tree. Latest tags at research time were in the v7.x line (e.g. v7.1.0). Always pin a release tag in production.
# From upstream Dockerfile — linux/amd64 binary zip
FROM --platform=linux/amd64 debian:trixie-slim
WORKDIR /app
# unzip metis-binary-x86_64-unknown-linux-gnu.zip → ./metis-binary
ENV RUST_LOG=info
CMD ["/app/metis-binary"]Access: Binary Key
Self-host is not anonymous. Docs: Binary Key.
- Request via portal.metis.builders.
- Prove control of a wallet with at least 10,000 JUP staked at vote.jup.ag — one escrow, do not split stake across multiple escrows for the check.
- Receive Binary Key by email; one key → one binary instance.
Never put the key in client code or git. Pass as BINARY_KEY / --binary-key. Docs state no Jupiter-side rate limit on the self-hosted surface (your RPC and hardware become the limit). Penalties and binary errors have dedicated pages if the key or process misbehaves — read those before paging on-call.
Run shape
Hard requirements: BINARY_KEY + RPC_URL. Recommended: Yellowstone gRPC so account state stays hot without thrashing HTTP RPC.
RUST_LOG=info ./metis-binary \
--binary-key "$BINARY_KEY" \
--rpc-url "$RPC_URL" \
--yellowstone-grpc-endpoint "$YELLOWSTONE_GRPC_ENDPOINT" \
--yellowstone-grpc-x-token "$YELLOWSTONE_GRPC_X_TOKEN"
# Defaults once healthy:
# API 127.0.0.1:8080
# metrics 127.0.0.1:9100 → /metrics /health /ready| Var / flag | Role |
|---|---|
BINARY_KEY | Auth — required |
RPC_URL | Account sync + swap metadata — required |
YELLOWSTONE_GRPC_* | gRPC stream; poll mode if unset (higher RPC load) |
API_ENDPOINT | Default 127.0.0.1:8080 |
METRICS_ENDPOINT | Default 127.0.0.1:9100 |
DEX_PROGRAM_IDS / EXCLUDE_DEX_PROGRAM_IDS | Whitelist / blacklist AMM programs |
FILTER_MARKETS_WITH_MINTS | Only markets touching listed mints |
MARKET_MODE=file + MARKET_CACHE | Load markets from local JSON cache |
DISABLE_SWAP_CACHE_LOADING | Quote-only style deploys (skip some swap caches) |
SNAPSHOT_POLL_INTERVAL_MS | Freshness vs RPC cost tradeoff |
Full tables (Yellowstone transport knobs, diagnostic toggles) live under Self host. Config via env, CLI flags (1:1 with env), or --env-file.
HTTP API (self-hosted)
Documented reference routes:
| Method | Path | Use |
|---|---|---|
| GET | /quote | Route quote — inputMint, outputMint, amount (raw units) |
| POST | /swap | Build swap transaction from a quote |
| POST | /swap-instructions | Raw instructions for CPI / custom tx assembly |
| GET | /program-id-to-label | Label map for DEX program IDs |
Quote guides cover platformFeeBps + feeAccount, onlyDirectRoutes (often worse price — use sparingly), and maxAccounts (recommend starting near 64; too low drops account-heavy AMMs like some DLMM paths). Simple vs shared-accounts routing instructions matter when markets lack ALTs — see the requote-with-lower-max-accounts guide before shipping a tight CU/account budget.
# Example shape — pin host/port to your API_ENDPOINT
curl -sG "http://127.0.0.1:8080/quote" \
--data-urlencode "inputMint=So11111111111111111111111111111111111111112" \
--data-urlencode "outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" \
--data-urlencode "amount=100000000"Deploy notes
- Docker: upstream image path expects the linux gnu zip; platform linux/amd64.
- Fly.io:
examples/fly.io—fly launch/fly deploy; README suggests performance-class sizing (e.g. performance-8x) for serious load — validate against your QPS and gRPC. - Observability: scrape
/metrics; gate traffic on/readynot just process up. - Send path: binary builds quotes/txs; landing is still your RPC, bundle stack, or Jupiter submit infrastructure — self-host does not mean free inclusion.
Chooser
| Need | Prefer |
|---|---|
| Best price, least ops, gasless helpers | Swap V2 Meta-Agg /order + /execute |
| Metis instructions without running a box | Hosted /build |
| Colocated routing, custom market filters, private RPC | metis-binary |
| RFQ / JupiterZ competition | Meta-Agg only (not in self-hosted Metis) |
| No 10k JUP stake / no Binary Key | Hosted APIs + API key from developers.jup.ag |
People and links
| Surface | URL |
|---|---|
| GitHub | jup-ag/metis-binary |
| Product | metis.builders |
| Binary Key + portal | docs/binary-key · portal.metis.builders |
| Self-host guide | docs/self-host |
| Jupiter Swap V2 | dev.jup.ag/docs/swap |
| Org | jup-ag |
| X | @JupiterExchange |
Resources
Keep reading
Same-chain stays Jupiter-class. Cross-ecosystem needs routers/solvers + messaging + honest status. Pyth prices the edge cases; Wormhole moves messages/assets.
Not every “swap API” is the same product. Here is what each aggregator layer actually gives your app — routing engines, landing, fees, AI tooling, and when to call whom.
Intent model on NEAR, 1click.chaindefuser.com tokens/quote/status, JWT fees, Solana assetIds, vs routers like LI.FI.
Get new articles in your inbox
Technical deep-dives on Solana tooling, infrastructure, and ecosystem. No noise.
