CockroachDB Cloud Community
Status: tested against
querycopHEAD on 2026-05-20. Endpoint conventions cited as of 2026-05.
CockroachDB Cloud is the managed service for CockroachDB, a distributed SQL database that speaks the PostgreSQL wire protocol over a non-standard port (26257). Cluster tiers, as of 2026-05:
- Basic — entry-level multi-tenant tier (the cluster formerly known as Serverless / free).
- Standard — paid multi-tenant tier with predictable performance (the cluster formerly billed as Serverless usage- based).
- Advanced — single-tenant cluster (formerly Dedicated).
All three tiers speak the same PostgreSQL wire protocol on port
26257 and are reached over a per-cluster FQDN. The cookbook recipe
below is the same for all three tiers — tenant routing for the
multi-tenant Basic / Standard tiers is now encoded in the
hostname, so no --cluster=<routing-id> in the client’s options
string is required (see Gotchas
for the historical note and what to do if you have an old
connection string still using --cluster=...).
CockroachDB Cloud does not currently expose an IAM / OAuth equivalent at the SQL wire layer — auth is SQL-user password (the control-plane has its own IAM for the dashboard / API, which is unrelated to data-plane auth). The IAM auth section is intentionally omitted from this page.
For any CockroachDB Cloud cluster (Basic / Standard / Advanced) with SQL-user-password auth, the production-ready config is:
| Env var | Value |
|---|---|
GATEKEEPER_BACKEND_HOST | my-cluster-abcd-1234.aws-us-east-1.cockroachlabs.cloud (the FQDN from the dashboard — for Basic / Standard the tenant routing is baked in here) |
GATEKEEPER_BACKEND_PORT | 26257 |
GATEKEEPER_BACKEND_TLS_MODE | verify-full |
GATEKEEPER_BACKEND_TLS_CA_FILE | /etc/ssl/certs/cockroach-cluster-ca.crt (downloaded per-cluster from the dashboard) |
GATEKEEPER_BACKEND_TLS_SERVER_NAME | (unset — derived from BACKEND_HOST, which matches the cert SAN) |
The cookbook treats the dashboard-displayed connection string as
the source of truth — paste the hostname into BACKEND_HOST and
do not add options=--cluster=... either client-side or in
Querycop’s env. The old --cluster=<routing-id> token is
deprecated; recent CockroachDB Cloud clusters reject it or
ignore it.
Prerequisites
Section titled “Prerequisites”-
A running cluster in CockroachDB Cloud — any tier (Basic / Standard / Advanced). The cluster name, region, FQDN, and connection-string template are visible in the dashboard under Clusters → <your cluster> → Connect.
-
The cluster’s CA cert, downloadable from the same dashboard panel (Connect → Download CA Cert). CockroachDB Cloud uses a per-cluster CA, not a publicly-trusted root.
Terminal window # After the dashboard download lands the file (typical local path# convention from Cockroach Labs is ~/.postgresql/root.crt):mv ~/.postgresql/root.crt /etc/ssl/certs/cockroach-cluster-ca.crtgrep -c BEGIN /etc/ssl/certs/cockroach-cluster-ca.crt # ≥ 1 -
A SQL user created in the cluster, with a password set. Create via the dashboard’s Users section, or via SQL once you have a privileged session:
CREATE USER appuser WITH PASSWORD '<strong-password>';GRANT SELECT, INSERT, UPDATE, DELETEON DATABASE appdb TO appuser; -
Network reachability from the Querycop host to port 26257 on the cluster endpoint (note: not 5432 — Cockroach uses its own port across both tiers).
-
Querycop with backend TLS support (
GATEKEEPER_BACKEND_TLS_*).
Password auth
Section titled “Password auth”CockroachDB Cloud’s data-plane auth is SQL-user password. Querycop forwards the password unchanged.
Step 1: Save the per-cluster CA
Section titled “Step 1: Save the per-cluster CA”The CA cert is per-cluster — it is NOT the same across tiers or regions. Save it to a path Querycop can read:
# Place the dashboard-downloaded CA cert at a stable pathcp ~/Downloads/cc-ca.crt /etc/ssl/certs/cockroach-cluster-ca.crt
# Sanity check it parsedgrep -c BEGIN /etc/ssl/certs/cockroach-cluster-ca.crt # should be ≥ 1Cockroach Labs rotates the per-cluster CA on a published schedule;
the dashboard prompts ahead of rotation. When that happens,
re-download and restart Querycop (no in-process hot reload of
BACKEND_TLS_CA_FILE).
Step 2: Configure Querycop
Section titled “Step 2: Configure Querycop”# Required: the cluster endpointexport GATEKEEPER_BACKEND_HOST=my-cluster-abcd.aws-us-east-1.cockroachlabs.cloudexport GATEKEEPER_BACKEND_PORT=26257
# Required: full TLS verification against the per-cluster CA.export GATEKEEPER_BACKEND_TLS_MODE=verify-fullexport GATEKEEPER_BACKEND_TLS_CA_FILE=/etc/ssl/certs/cockroach-cluster-ca.crt# SERVER_NAME not set — Querycop derives it from BACKEND_HOST,# which matches the SAN on the per-cluster cert.
# Standard Querycop runtime — note the LISTEN_PORT is whatever your# clients should dial; the backend port is fixed at 26257.export GATEKEEPER_LISTEN_PORT=15432export GATEKEEPER_API_PORT=8080export ADMIN_API_KEY=$(openssl rand -hex 16)
querycopStep 3: Connect the client
Section titled “Step 3: Connect the client”The connection looks like an ordinary PostgreSQL client connection
for every tier (Basic / Standard / Advanced) — Querycop translates
the listen port, and the tenant routing for multi-tenant tiers is
already baked into BACKEND_HOST from Step 2:
psql -h 127.0.0.1 -p 15432 -U appuser -d appdb# Password prompt → enter the password set on the Cockroach userNo options=--cluster=... token is required. If your dashboard
or an older runbook still shows a connection string containing
options=--cluster=..., drop that token — it is deprecated and
the FQDN you pasted into BACKEND_HOST already encodes the same
routing.
verify-full is the right default. require (no certificate
verification) is evaluation-only. disable is not an
appropriate choice — CockroachDB Cloud refuses anything weaker than
TLS server-side anyway, so the handshake fails immediately.
Smoke test
Section titled “Smoke test”# Terminal 1: bring up Querycop with the env above.docker compose up -d # or `querycop` directly
# Terminal 2: same shape for every tier (Basic / Standard / Advanced).PGPASSWORD='<password>' psql \ -h 127.0.0.1 -p 15432 -U appuser -d appdb \ -c 'select 1'# ?column?# ----------# 1# (1 row)A green select 1 means proxy-side handshake, backend TLS, and
password auth all worked. If you see something else:
backend TLS negotiation failed: x509: certificate signed by unknown authority→ the per-cluster CA file is missing, stale, or wasn’t picked up. Re-download from the dashboard and updateBACKEND_TLS_CA_FILE.cluster "..." not foundor similar tenant-routing error → the FQDN inBACKEND_HOSTdoesn’t match an active cluster. Re-paste from the dashboard’s Connect panel. If the connection string the dashboard emits is in the old form withoptions=--cluster=..., drop that token and rely on the FQDN alone.password authentication failed for user "appuser"→ wrong password or user doesn’t exist. Check via the dashboard’s Users section.
Gotchas
Section titled “Gotchas”Tenant routing is now encoded in the hostname — no --cluster= options needed
Section titled “Tenant routing is now encoded in the hostname — no --cluster= options needed”For the multi-tenant Basic / Standard tiers, the cluster’s front-door router dispatches to the right tenant by reading the hostname the client connected to. Every cluster gets its own FQDN that includes the cluster-routing identity, and the dashboard emits that hostname directly in its connection-string panel. The recipe is:
- Paste the dashboard hostname into
GATEKEEPER_BACKEND_HOST(Step 2 above). - Have the client connect to Querycop’s listen address. Querycop
dials the backend FQDN. With
GATEKEEPER_BACKEND_TLS_SERVER_NAMEunset, Querycop derives the TLS SNI fromBACKEND_HOST, so CockroachDB Cloud’s edge sees the dashboard-provided hostname it expects and routes accordingly. - Do not add
options=--cluster=...anywhere — client-side connection string OR Querycop env. The token is deprecated and the FQDN is the source of truth.
If you have an older connection string still using
options=--cluster=... — from a legacy dashboard view, a
pre-cutover runbook, or copy-pasted from an old StackOverflow
answer — recent CockroachDB Cloud clusters either ignore the
token or reject it outright. Drop the token; the FQDN already
carries the routing.
For the single-tenant Advanced tier, there’s no routing question at all: the FQDN points at one physical cluster, and the client connects normally. Querycop’s recipe is identical to the multi-tenant case (this is why the cookbook now has a single unified Step 3 instead of a Basic-vs-Advanced split).
If you’re running Querycop in front of a cluster where you genuinely need to inject a startup parameter the client can’t be configured with — Querycop deliberately doesn’t mutate the StartupMessage, so the right pattern is a per-client ConfigMap / env-driven connection-string template in front, not proxy-side rewriting.
Port 26257, not 5432
Section titled “Port 26257, not 5432”This is the most common smoke-test misfire on a first deployment.
CockroachDB Cloud’s backend listens on port 26257 across every
tier (Basic / Standard / Advanced). If you set BACKEND_PORT=5432
by muscle memory, the dial fails immediately with connection refused.
The listen port on Querycop’s client-side (GATEKEEPER_LISTEN_PORT)
can be whatever you like — 15432 is fine, your apps don’t care
that the upstream is on 26257.
Per-cluster CA rotation
Section titled “Per-cluster CA rotation”Cockroach Labs rotates the per-cluster CA on a published schedule; the dashboard prompts ahead of the rotation. The operator pattern:
- When prompted, download the new CA from the dashboard.
- Replace
/etc/ssl/certs/cockroach-cluster-ca.crtwith the new PEM. - Restart Querycop (no in-process hot reload of
BACKEND_TLS_CA_FILE).
The dashboard exposes both the outgoing and incoming CA during the transition window, so re-downloading well in advance avoids the cliff edge.
Client→proxy TLS vs proxy→CockroachDB TLS are SEPARATE legs
Section titled “Client→proxy TLS vs proxy→CockroachDB TLS are SEPARATE legs”| Leg | Configured by | Default |
|---|---|---|
| Client → Querycop | GATEKEEPER_PROXY_TLS_CERT / _KEY | OFF — plaintext unless you put TLS material in front |
| Querycop → CockroachDB | GATEKEEPER_BACKEND_TLS_* (this page) | prefer (default) — upgrade to verify-full per recipe |
In this cookbook the proxy→DB leg is verify-full. The
client→proxy leg is your call — psql over plaintext to a
localhost proxy is fine for development; for production put a TLS
cert on Querycop (GATEKEEPER_PROXY_TLS_CERT / _KEY).
Because CockroachDB Cloud auth is SQL-user password, that password traverses the client→proxy leg unchanged (Querycop forwards it). Don’t run app→Querycop in plaintext over a non-loopback network unless the network itself is trusted.
CockroachDB serial / unique behavior differs from stock PostgreSQL
Section titled “CockroachDB serial / unique behavior differs from stock PostgreSQL”Not a Querycop concern, but worth knowing during onboarding: CockroachDB Cloud is wire-compatible with PostgreSQL but the underlying engine has its own semantics around:
SERIALcolumns: CockroachDB usesunique_rowid()by default (random-looking int64) rather than a per-table sequence.RETURNINGclauses,ON CONFLICT, transaction retries: largely compatible but with retry-loop expectations in apps; see CockroachDB Transactions.pg_catalogquery shape: similar but not identical; ORM reflection can hit edge cases.
These are wire-protocol-compatible from Querycop’s perspective — the proxy doesn’t care about the result-shape differences. But if an app behaves oddly on Cockroach Cloud and you’re tempted to blame Querycop, the engine semantics are the more likely cause.
Org-level IAM is for the dashboard, NOT the SQL wire
Section titled “Org-level IAM is for the dashboard, NOT the SQL wire”CockroachDB Cloud has its own RBAC system at the organization /
project / cluster level, accessible via the dashboard and the
CockroachDB Cloud API. Those identities authenticate humans /
service accounts against the control plane (creating clusters,
managing users, downloading CA certs, rotating credentials). They
are NOT a substitute for SQL-user passwords on the data plane —
the MySQL-style cockroach sql CLI and any PG-wire client must
still authenticate with the SQL-user password the dashboard
generated.
If you’re automating SQL-user creation from CI, you’d use a
CockroachDB Cloud API token to call the users REST endpoint and
then take the returned password into your secrets store —
Querycop only ever sees the SQL-user password the client
subsequently presents.
Cross-links
Section titled “Cross-links”docs/configuration.md§1.5 — backend TLS reference- CockroachDB docs: Connect to a Basic cluster
- CockroachDB docs: Connect to a Standard / Advanced cluster
- CockroachDB docs: Connection parameters
- CockroachDB docs: Transactions (engine semantics)