A fast, scriptable CLI for the Apache Doris kernel. It connects over the MySQL protocol (+ the FE HTTP API), executes, and returns structured JSON — a "tool, not a brain": all the intelligence lives in the layer above (an agent, a script, your shell). Every command prints machine-readable output and exits; there are no interactive prompts.
The binary is doriscli.
doriscli sql "SELECT VERSION()"
doriscli profile get <query_id>
doriscli tablet db.orders --detail- SQL execution — run a query (or a
.sqlfile) and get backquery_id,exec_time_ms,columns, androwsas JSON. Set session variables, toggle the query cache, or enable profiling inline. - Query profile analysis — fetch and parse Doris query profiles:
- a digest by default (summary + plan + operators + table context),
- the full parsed tree (
Fragment → Pipeline → Operatorwith all counters) with--full, - the raw profile text with
--raw, - diff two runs (slow vs. fast) to find the regression,
- history for a SQL pattern from
audit_log, - list recent or currently-running queries.
- Tablet & bucket analysis — bucket/tablet distribution for a table, with a
--detailmode that breaks down per-partition stats, per-tablet rows/size, and the backend mapping (find skew fast). - Multi-environment auth — save several connections;
auth statusprobes the connection and reports the Doris version, backends, and workload groups. - SOCKS5 tunneling — reach a BYOC / bastioned cluster through a SOCKS5 proxy. Proxy credentials are never written to disk.
- Flexible output — JSON when piped, a pretty table on a TTY, or CSV. Override
with
--format. - Stateless mode — drive it entirely from environment variables (no files touched), which is ideal for bastions, CI, and multi-tenant hosts.
The recommended way to install doris-cli is from npm — it ships prebuilt binaries, so there is no Rust toolchain and no compile step:
npm install -g @apache-doris/doriscli
doriscli --versionOn install, npm pulls only the binary that matches your OS + CPU (via
optionalDependencies + os/cpu constraints). Supported platforms: macOS
(arm64), Linux (x64, arm64). The published package is scoped
(@apache-doris/doriscli), but the installed command is just doriscli.
For any other platform — or to hack on doris-cli itself — build from source below.
Requires a recent stable Rust toolchain (verified on rustc 1.87; the crate uses the MSRV-aware resolver and pins a few dependencies for older toolchains).
cargo build --release # produces target/release/doriscli
cargo run --release -- --version
cargo test # unit testsPut the binary on your PATH:
cp target/release/doriscli /usr/local/bin/# 1. Save a connection ("prod" is just a name you choose)
doriscli auth add prod --host 127.0.0.1 --port 9030 --http-port 8030 \
--user root --password 'secret'
# 2. Verify it (version, backends, workload groups, HTTP health)
doriscli --env prod auth status
# 3. Query
doriscli --env prod sql "SELECT COUNT(*) FROM db.orders"The first environment you add becomes the default, so --env is optional until you
have more than one. Switch the default any time with doriscli use <name>.
doriscli auth add <name> --host <h> --user <u> --password <p> [--port 9030] [--http-port 8030]
doriscli auth add <name> --mysql "mysql://user:pass@host:9030" # URI form
doriscli auth list
doriscli auth status # test connection + cluster info
doriscli auth remove <name>auth add probes the FE HTTP port and, if it doesn't answer, suggests common
alternatives (8080 for cloud FEs, 8030/8040 for self-hosted Apache Doris) so profile
commands work later.
doriscli sql "SELECT * FROM db.t LIMIT 10"
doriscli sql -f migration.sql
doriscli sql "SELECT ..." --profile # SET enable_profile=true first
doriscli sql "SELECT ..." --no-cache # bypass the SQL cache (benchmarking)
doriscli sql "SELECT ..." --set "exec_mem_limit=8g" --set "parallel_pipeline_task_num=8"Output:
{
"query_id": "f1e2...",
"exec_time_ms": 42,
"rows_returned": 10,
"columns": ["id", "name"],
"rows": [{ "id": 1, "name": "a" }]
}doriscli profile list [--limit 20] [--active] # recent, or running queries
doriscli profile get <query_id> # summary + plan + operators
doriscli profile get <query_id> --full # full Fragment→Pipeline→Operator tree
doriscli profile get <query_id> --raw # raw profile text
doriscli profile get <query_id> -f exported.txt # parse a profile saved from the web UI
doriscli profile diff <slow_qid> <fast_qid> # compare two runs
doriscli profile history "<sql substring>" [--days 7] [--limit 50]doriscli tablet db.orders # overview
doriscli tablet db.orders --detail # per-partition + per-tablet + backends
doriscli tablet db.orders --detail --partition p20240101doriscli use # show current + list environments
doriscli use staging # make "staging" the default| Option | Description |
|---|---|
--env <name> |
Which saved environment to use (default: default, or $DORIS_ENV). |
--format <json|table|csv> |
Force the output format. Default: table on a TTY, JSON when piped. |
--socks5 <user:pass@host:port> |
Route the connection through a SOCKS5 proxy (BYOC). |
--init-sql <sql> |
Run a statement right after connecting (e.g. USE @<compute-group>). Overrides $DORIS_INIT_SQL. |
Saved environments live in ~/.doris/:
~/.doris/config.toml— host, ports, user, per-environment.~/.doris/credentials.toml— passwords (written0600).
Every setting can also come from the environment (prefix DORIS_), which takes
precedence over the config files:
| Variable | Meaning | Default |
|---|---|---|
DORIS_HOST |
FE host | — |
DORIS_USER |
MySQL user | — |
DORIS_PASSWORD |
MySQL password | empty |
DORIS_PORT |
MySQL/query port | 9030 |
DORIS_HTTP_PORT |
FE HTTP port | 8030 |
DORIS_ENV |
Which environment to use | default |
DORIS_INIT_SQL |
Statement run after connect | — |
DORIS_SOCKS5_HOST / _PORT / _USER / _PASS |
SOCKS5 proxy (BYOC) | user/pass default to admin |
Stateless mode: when both DORIS_HOST and DORIS_USER are set, doris-cli
connects purely from environment variables and never reads or writes any file —
designed for bastions, CI, and multi-tenant hosts where $HOME may not be writable.
DORIS_HOST=fe.internal DORIS_USER=admin DORIS_PASSWORD=*** \
doriscli sql "SELECT 1"doris-cli talks to any reachable Doris FE — including a cloud cluster — as long as
you give it the resolved host/port. Compute-group routing is handled
by --init-sql (or DORIS_INIT_SQL), which runs USE @<compute-group> right after
connecting:
DORIS_HOST=<resolved-host> DORIS_PORT=<port> DORIS_USER=admin DORIS_PASSWORD=*** \
DORIS_INIT_SQL='USE @my_compute_group' \
doriscli sql "SELECT 1"- TTY → a pretty table.
- Piped / redirected → JSON (so
| jqand scripts just work). - Force either, or CSV, with
--format json|table|csv.
doriscli --env prod sql "SHOW BACKENDS" --format table
doriscli --env prod sql "SELECT * FROM db.t" | jq '.rows[] | .id'