Skip to main content
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
This page shows representative examples. 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.
The script installs ~/.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

Each named server has its own data in .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:
The file is overlaid on the built-in defaults, so it only needs the settings you change. The selection is not remembered: a later start without --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 as 18-alpine; new instances default to 18.
An instance is identified by its name and major version. Resuming a stopped instance reuses its original port, user, password and database, so creation flags have no effect on a resume. A random password is generated unless you pass one. .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).
Every command except 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

This opens your browser for the OAuth device flow. Tokens are saved globally to ~/.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:
Login verifies the key and prints the identity it belongs to. A key the API rejects is not saved, and the command exits 4. If the API is unreachable, the key is saved with a warning. For CI and other automation, inject the key through your secret manager instead of saving it:
For development, the CLI also reads these variables from a .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:
  1. --api-key and --api-secret flags
  2. .clickhouse/credentials.json
  3. Exported environment variables
  4. Variables from .env in the current directory
  5. Global OAuth tokens
Pass --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:
Most resource commands take a positional ID or an exact --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 poll get until a resource reaches the state you need.

Services

Save the initial password shown at creation; it is returned only once. Creation returns before provisioning finishes, so repeat 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:
Memory per replica is a multiple of 4 GB, at most 120 GB on unpaid and 356 GB on paid services, with up to 50 replicas. Organization and warehouse limits can lower these. Horizontal autoscaling needs its organization feature. 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_admin roles if needed. Existing roles, origins and other key bindings are kept, and no new key is created. When the CLI changes the endpoint, it prints Binding the authenticated API key to the Query API endpoint for service '<name>'... to stderr. Pass --no-auto-enable to fail instead.
A per-service key saved by an earlier CLI version still takes precedence for that service. If the API rejects it, 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.
AWS sizes include 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:
Replicate Postgres with CDC. TLS is verified by default; for a Managed Postgres source, export its CA and pass it:
--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:
BigQuery pipes run a snapshot by default. For CDC, pass --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:
CDC pipes must be 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.
Every ClickStack update replaces the complete resource. Save the current state with 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:
To run each step yourself, use 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:
Omitting --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

Restoring always creates a new service. 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:
When the CLI detects a coding agent (such as Claude Code, Cursor, Codex, Gemini CLI, Goose or Devin, or any tool that sets 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:
Branch on 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:
Skills install into the current project by default, or into your home directory with --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

The CLI also checks for updates in the background, at most once every 24 hours, and prints a notice when a newer version is available.

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
Argument values, SQL, credentials, resource identifiers, arguments after -- and error messages are never recorded. There is no installation or device ID. To opt out:
Set CHCTL_TELEMETRY_DEBUG=1 to print the payload to stderr without sending anything. See telemetry details.