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 file) and get back query_id, exec_time_ms, columns, and rows as JSON. Set session variables, toggle the query cache, or enable profiling inline.Fragment → Pipeline → Operator with all counters) with --full,--raw,audit_log,--detail mode that breaks down per-partition stats, per-tablet rows/size, and the backend mapping (find skew fast).auth status probes the connection and reports the Doris version, backends, and workload groups.--format.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 --version
On 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 tests
Put 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>.
auth — manage connectionsdoriscli 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.
sql — execute queriesdoriscli 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" }] }
profile — analyze query profilesdoriscli 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]
tablet — bucket / tablet distributiondoriscli tablet db.orders # overview doriscli tablet db.orders --detail # per-partition + per-tablet + backends doriscli tablet db.orders --detail --partition p20240101
use — switch the default environmentdoriscli 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 (written 0600).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"
| jq and scripts just work).--format json|table|csv.doriscli --env prod sql "SHOW BACKENDS" --format table doriscli --env prod sql "SELECT * FROM db.t" | jq '.rows[] | .id'