clickhousectl (alias chctl) is the official CLI for ClickHouse, from local development to ClickHouse Cloud. It works for people at a terminal, for scripts, and for coding agents.
With clickhousectl you can:
- Install and switch local ClickHouse versions, run isolated local servers, and execute SQL
- Run Docker-backed Postgres locally
- Create, configure, scale, back up and query ClickHouse Cloud services
- Create, monitor, configure and restore ClickHouse Managed Postgres services
- Create and operate ClickPipes from object storage, Kafka, Kinesis, Pub/Sub, Postgres, MySQL, MongoDB and BigQuery
- Manage sources, dashboards, alerts, webhooks, saved searches and roles on a Managed ClickStack service
- Develop executable UDFs locally and deploy them to ClickHouse Cloud
- Manage organization members, invitations, API keys and roles
- Install the official ClickHouse agent skills into coding agents
clickhousectl <command> --help is the authoritative reference for every command and flag. Most commands’ help ends with a CONTEXT FOR AGENTS block; for Cloud commands it also lists the API-key permissions they need. For task walkthroughs, follow the guide links in each section. For a Cloud-focused overview, see ClickHouse CLI.
Installation
clickhousectl runs on macOS and Linux, on ARM64 and x86_64.
~/.local/bin/clickhousectl and creates the chctl alias. Make sure ~/.local/bin is on your PATH.
You can also install it with a package manager:
Only the install script and npm create the
chctl alias. To update an existing install, run clickhousectl update (see Self-update).
Requirements
- Docker, for local Postgres only
- For Cloud commands, a ClickHouse Cloud account. Read commands work with browser OAuth (
cloud auth login). Creating or changing resources needs an API key. See Authentication.
Local
Local commands work in the current directory. Each project keeps its server data in.clickhouse/, while ClickHouse binaries are shared globally in ~/.clickhouse/. The CLI does not search parent directories, so run local commands from your project root. See the local development guide for the full workflow.
Install and select versions
local use installs the version if needed, sets it as the default for future server starts, and symlinks it to ~/.local/bin/clickhouse, so clickhouse client and clickhouse local are on your PATH. Pass --no-global to skip the symlink. If a regular file already exists at that path, it is left alone.
local remove refuses the default version or one used by a running server in any project. --force stops those servers and removes the version, clearing the default and the symlink.
Initialize a project
init is optional. It creates a git-ignored .clickhouse/ directory for runtime data, plus SQL scaffolds you can commit: clickhouse/ (tables/, materialized_views/, queries/, seed/, udfs/) and postgres/ (tables/, views/, functions/, queries/, seed/). Re-running it only creates what is missing.
Run local servers
.clickhouse/servers/<name>/data/, and stopping a server keeps it for the next start. Without a name, the first server is default; if default is already running, a new name is generated. Default ports are HTTP 8123 and TCP 9000, with free ports assigned when those are taken.
--version chooses a version for that start without changing the default. A bare start with no version and no default installs latest without making it the default; run local use latest first to make it the default.
Run SQL with the local client
local client connects to a named server with the same ClickHouse binary that runs it (default name: default). Arguments after -- go to clickhouse client unchanged. Output and exit status come from clickhouse client, even in JSON mode, so set the SQL output format yourself when scripting.
Custom server configuration
Put a partial XML or YAML config in~/.clickhouse/configs/ and select it by name when starting a server:
--config removes the overlay. Managed data paths and ports always win over config values.
Write connection details to a dotenv file
dotenv reads the running server’s actual ports and writes CLICKHOUSE_HOST, CLICKHOUSE_PORT and CLICKHOUSE_HTTP_PORT, plus the user, password and database when you pass them. Other lines in an existing file are kept. Load the file with your application’s dotenv loader; never eval the printed preview.
Local Postgres
Local Postgres runs in Docker, so Docker must be running. Postgres 17 and 18 are supported, including image tags such as18-alpine; new instances default to 18.
.env.local contains the password, so keep it out of version control.
Local UDFs
local udf deploys executable UDFs from clickhouse/udfs/<name>/ to a local server. cloud udf uploads the same directory to Cloud (see UDFs in Cloud).
init takes --server <name> (default default). deploy validates udf.json the same way Cloud does. On a running server, it reloads functions and confirms the function loaded. The native runtime deploys locally only on Linux amd64 or arm64 hosts. See the user-defined functions guide.
Authentication
Cloud commands use one of two credential types:
If you don’t have a ClickHouse Cloud account yet,
clickhousectl cloud auth signup opens the sign-up page in your browser.
OAuth login
~/.clickhouse/tokens.json and refreshed automatically.
OAuth is read-only. To create or change resources, log in with an API key.
API key
Create an API key with the roles your commands need, then save it. The interactive prompt keeps the secret out of your shell history:.env file in the current directory. Keep .env out of version control.
Check and clear credentials
whoami works with either credential type and exits 4 if the credentials are rejected. status can exit 0 even when no credentials work, so use whoami to test access. Logout does not unset environment variables or edit .env.
Credential precedence
The first available source wins:--api-keyand--api-secretflags.clickhouse/credentials.json- Exported environment variables
- Variables from
.envin the current directory - Global OAuth tokens
--debug to any cloud command to print the selected credential source and API URL to stderr:
Select an organization
Organization-scoped commands pick the organization automatically only when your credentials reach exactly one. Otherwise pass--org-id, or --org-name with the exact name:
--name. See authentication and access for permissions, restricted keys and logout cleanup.
Cloud
Cloud commands call the ClickHouse Cloud API. Create and update requests return once the API accepts them, so pollget until a resource reaches the state you need.
Services
get until the state is running. Omitting --ip-allow allows all IPs (0.0.0.0/0). Entries accept IP_OR_CIDR=DESCRIPTION. Restore a backup into a new service with --backup-id, or place a service in BYOC infrastructure with --byoc-id.
Update, scale and configure a service:
update changes only the flags you pass.
Other service command groups are settings (list, get, schema, set, unset), scaling-schedule, upgrade-window, replica-aware-routing (Beta), snapshot (Beta), private-endpoint, backup-config and prometheus. See create and operate a Cloud service.
Query API
cloud service query runs one SQL statement over HTTP, with no local clickhouse binary and no service password:
- OAuth runs the query as your identity, with read-only SQL access. Nothing is bound to the service.
- API key: on the first call, clickhousectl adds your API key to the service’s Query API endpoint, creating the endpoint with
sql_console_adminroles if needed. Existing roles, origins and other key bindings are kept, and no new key is created. When the CLI changes the endpoint, it printsBinding the authenticated API key to the Query API endpoint for service '<name>'...to stderr. Pass--no-auto-enableto fail instead.
cloud service repair-query-key <service-id> deliberately replaces it.
The Query API accepts one statement per request. It can time out after about 30 seconds while the SQL keeps running, so check the result before retrying a write. Use clickhouse client for multi-statement scripts, bulk loads and long queries. The service IP allowlist restricts direct connections, not the proxied Query API route. Querying an idle service wakes it; a stopped service must be started with cloud service start.
Manage the service’s Query API endpoint, named SQL endpoints and saved queries:
query-endpoint create replaces the roles for every key bound to the endpoint. See SQL and Query API behavior.
Managed Postgres
cloud postgres manages ClickHouse Managed Postgres. These commands are Beta, and GCP is in private preview.
m6gd.large, c6gd.xlarge and r6gd.xlarge. On GCP, pass --provider gcp with a GCP region and a size such as c4-standard-lssd-4.
Save the password and connection string from create. Later get responses never return credentials, and reset-password is the only way to get new ones. Connect with psql using sslmode=verify-full and the CA file.
Omitting access flags on create allows all IPv4 and IPv6 addresses on Postgres (5432) and PgBouncer (6432). Pass one --ip-allow IP_OR_CIDR:PORTS[=DESCRIPTION] per rule, or --block-public-access for no rules. Once you pass a rule, only the listed rules apply.
Monitor and recover:
cloud postgres query accepts only OAuth, so it fails while a higher-priority API key source is active. metrics, slow-queries and prometheus cover monitoring. restore copies the source’s current IPv4 access rules onto the restored service unless you pass --ip-allow or --block-public-access. Restores and replicas return without a password. promote and switchover return once accepted; after a promote, poll postgres get --json until the replica reports isPrimary: true. See the Managed Postgres guide.
ClickPipes
cloud clickpipe ingests data from object storage, Kafka, Kinesis, Pub/Sub, Postgres, MySQL, MongoDB and BigQuery. Creation and schema discovery need an API key and a running destination service. Each source has its own clickpipe create <source> subcommand; run it with --help for its flags.
Load files from S3 with an IAM role. Discover the schema first, then choose the columns:
--table-mapping creates ReplacingMergeTree tables, so read current state with FINAL WHERE _peerdb_is_deleted = 0. A Kafka pipe follows the same pattern: run clickpipe schema-discover kafka with the same source flags, then pass the columns:
--replication-mode cdc, a --replication-method, and a per-table watermark column or events function in --table-mapping-json; schedule syncs with --sync-cron or --sync-interval-seconds. Operate existing pipes:
Paused before update: stop the pipe, poll get until it is Paused, then update it. The service can resume the pipe as part of the update, so run start only if get still shows Paused. --start-paused is available for object storage, Kafka, Kinesis and Pub/Sub. Other command groups are cdc-scaling, context get (GCP workload-identity readiness and principal) and reverse-private-endpoint. See the ClickPipes guide and the ClickPipe configuration reference.
ClickStack
cloud clickstack manages sources, dashboards, alerts, webhooks, saved searches and roles on an existing Managed ClickStack service. Resources are JSON files (--file, or - for stdin). Reads support OAuth; writes need an API key.
get --json and send the full definition, not only the changed fields. See the ClickStack guide.
UDFs in Cloud
cloud udf manages organization-scoped executable UDFs, their versions and their service attachments. deploy uploads the directory you tested with local udf, waits for the build, attaches that version and waits until it is deployed:
udf create, udf version create, udf attach (with --wake for an idle service), udf detach and udf delete. These return once accepted; poll udf get and udf attachment get. Reads support OAuth; writes need an API key. See the user-defined functions guide.
Organizations and access
cloud org subcommands take --org-id, never a positional ID. org usage covers at most 31 days. org also has quota, balance, notification-types, role (custom organization roles) and byoc (BYOC infrastructure). Notifications are Beta.
Manage members, invitations and API keys:
--ip-allow on key create denies all network access, unlike service creation. The secret is shown only once. key list returns one page unless you pass --all. On key update, omitted flags keep their settings, while --clear-expiry, --clear-roles and --clear-ip-allow remove them.
Backups
cloud backup bucket (get, create, update, delete) configures a bring-your-own backup bucket from a provider-specific JSON file. See the backup section of the Cloud service guide.
JSON output
Commands that return structured data accept--json, including local, Cloud, skills, update and telemetry commands:
AI_AGENT), it selects JSON automatically. SQL and native clients keep their own formats: cloud service query returns JSONEachRow in JSON mode, and local client output is always native. Scripts that parse query output should pass --format explicitly.
In JSON mode, runtime errors go to stderr as an object with a stable code and a message:
error.code, not on the message. Usage errors stay as text, with exit code 2. See automation and output contracts for output shapes and error codes.
Exit codes
local client, local postgres client and other native-client handoffs pass the client’s own exit status through.
Agent skills
Install the official ClickHouse agent skills into your coding agents:--global. The shared .agents/skills/ directory is always included. Without a terminal, you must pass --agent, --all or --detected-only. Run clickhousectl skills --help for the supported agent names.
Self-update
Telemetry
clickhousectl collects anonymous usage data to guide development. The first run shows a notice and sends nothing; collection starts on a following run unless you disable it.
Each event contains:
- The command path and the names of explicitly passed flags and arguments, never their values
- The outcome and exit code
- For a mistyped command, the command or flag name the CLI suggested, never what you typed
- For runtime failures, bounded categories: failure stage and kind, an allowlisted HTTP status, and retry, provisioning-state and duration categories
- The CLI version, OS and architecture, whether it runs in CI, and the detected coding agent
-- and error messages are never recorded. There is no installation or device ID.
To opt out:
CHCTL_TELEMETRY_DEBUG=1 to print the payload to stderr without sending anything. See telemetry details.