Skip to main content
Skip to main content
Edit this page

Replica-aware routing

Private preview

Replica-aware routing (also known as sticky sessions, sticky routing, or session affinity) routes related requests to the same ClickHouse replica. Use it when you need temporary tables or named session state to stay reachable across queries, or when you want related queries to reuse the same replica's local caches.

It's best-effort and doesn't guarantee isolation. Scaling, upgrades, and restarts can remap which replica a given session_id lands on.

Requires the HTTP interface

Replica-aware routing is applied at the proxy layer over the HTTP/HTTPS interface, using the session_id query parameter (see below). It's not available over the native protocol (native port, e.g. the clickhouse-go driver in its default native mode). Native-protocol clients must switch to HTTP and pass a session_id on each request. For clickhouse-go (v2), set Protocol: clickhouse.HTTP and pass session_id as a setting. The driver sends it as the URL query parameter the proxy hashes on.

Prerequisites

  • Your service needs 2 or more replicas. On a single-replica service, there's nothing to pin to.
  • A running service. Waking an idle service can change which replica a session_id maps to.
  • Available on Enterprise by default when the feature is GA.
  • Supported on standard ClickHouse Cloud services. BYOC isn't supported yet.

Configuring replica-aware routing

Open a support ticket and ask to enable HTTP-based sticky replica routing. Include your service ID and why you need it (temporary tables, session state, or cache reuse). After it's enabled, start sending ?session_id= on HTTPS requests. No restart is required.

HTTP-based routing (session_id)

To pin a workload to a replica, set the session_id query parameter on the HTTPS interface. The proxy uses consistent hashing on that value to select a replica, so all requests sharing the same session_id go to the same server until the cluster topology changes.

You use your existing service hostname. No special sticky hostnames or DNS changes are required.

echo 'SELECT hostName()' | curl \
  -H 'X-ClickHouse-User: default' \
  -H 'X-ClickHouse-Key: <password>' \
  'https://<host>:8443/?session_id=my-workload-1' -d @-

Every request carrying session_id=my-workload-1 lands on the same replica. A different session_id value hashes independently and may land on the same or a different replica. The mapping is consistent, but you don't choose which replica a given value maps to.

session_id is any string you choose (application name, user id, or workload label). Requests without session_id keep normal load balancing.

Any HTTP client that can add a query parameter works, including curl, clickhouse-connect, JDBC/ODBC, and others. For clickhouse-go (v2), use HTTP mode as noted above.

Check which replica you hit

Run the SELECT hostName() example above again with the same session_id. You should get the same hostname. A different session_id may map to a different replica.

Subdomain-based routing (deprecated)

Deprecated

The subdomain-based mechanism is being deprecated and will no longer be enabled on new services. It doesn't scale (each sticky endpoint requires its own TLS certificate). Use the HTTP-based session_id method instead. If you already use sticky subdomains, contact support to enable session_id routing. This is a breaking change and will require migration.

Previously, enabling replica-aware routing allowed a wildcard subdomain on top of the service hostname. For a service with the host name abcxyz123.us-west-2.aws.clickhouse.cloud, any hostname matching *.sticky.abcxyz123.us-west-2.aws.clickhouse.cloud (e.g. aaa.sticky.abcxyz123.us-west-2.aws.clickhouse.cloud) was hashed by Envoy to a consistent replica. The original hostname continued to use LEAST_CONNECTION load balancing, the default routing algorithm.

Limitations of replica-aware routing

Stickiness can break during service changes

Any disruption to the service changes the routing hash ring. That includes server pod restarts (version upgrade, crash, vertical scaling) and scaling out or in. Requests sharing the same session_id may then land on a different server pod. If you rely on temporary tables or session-level settings, be ready to recreate them after a remap.

Replica-aware routing isn't workload isolation

Sticky routing only controls which replica handles a request. That replica may still serve other traffic. For dedicated compute, use compute-compute separation.

HTTP session_id routing works with private networking on your normal service hostname. No extra DNS entries are required.

The deprecated subdomain method doesn't: you must add DNS for the *.sticky.* hostname pattern, and incorrect setup can imbalance load across replicas.

Replica-aware routing requires the HTTP protocol

Sticky routing is keyed on the session_id query parameter, which only exists on the HTTP/HTTPS interface. The native binary protocol carries no such parameter for the proxy to hash on, so replica-aware routing isn't available over the native protocol. Today, native-protocol clients must move the relevant workload to the HTTP interface to use this feature.

Troubleshooting

Queries still land on different replicas with the same session_id

  • Confirm session_id is a URL query parameter (?session_id=...), not an HTTP header.
  • Wait briefly after enablement. It can take under a minute to take effect.
  • Check whether the service recently scaled or restarted; remapping is expected after topology changes. Use SELECT hostName() to discover the new mapping.