> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-postgresql-tls-support.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Replica-aware routing

> Route related requests to the same ClickHouse Cloud replica for temporary tables, sessions, and cache reuse

export const PrivatePreviewBadge = () => {
  return <div className="privatePreviewBadge">
            <div className="privatePreviewIcon">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M5.33301 6.66667V4.66667V4.66667C5.33301 3.194 6.52701 2 7.99967 2V2C9.47234 2 10.6663 3.194 10.6663 4.66667V4.66667V6.66667" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path d="M8.00033 9.33337V11.3334" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path fillRule="evenodd" clipRule="evenodd" d="M11.333 14H4.66634C3.92967 14 3.33301 13.4033 3.33301 12.6666V7.99996C3.33301 7.26329 3.92967 6.66663 4.66634 6.66663H11.333C12.0697 6.66663 12.6663 7.26329 12.6663 7.99996V12.6666C12.6663 13.4033 12.0697 14 11.333 14Z" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
        </div>
            {'Private preview in ClickHouse Cloud'}
        </div>;
};

<PrivatePreviewBadge />

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](/sql-reference/statements/create/table#temporary-tables) or [named session state](/interfaces/http#using-clickhouse-sessions-in-the-http-protocol) 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.

<Warning>
  **Requires the HTTP interface**

  Replica-aware routing is applied at the proxy layer over the [HTTP/HTTPS interface](/interfaces/http), using the `session_id` query parameter (see below). It's **not available over the native protocol** (native port, e.g. the [clickhouse-go](/integrations/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](/integrations/language-clients/go/database-sql-api#sessions). The driver sends it as the URL query parameter the proxy hashes on.
</Warning>

<h2 id="prerequisites">
  Prerequisites
</h2>

* 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](/cloud/reference/byoc/overview) isn't supported yet.

<h2 id="configuring-replica-aware-routing">
  Configuring replica-aware routing
</h2>

Open a [support](https://clickhouse.com/support/program) 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.

<h2 id="http-based-routing">
  HTTP-based routing (session\_id)
</h2>

To pin a workload to a replica, set the `session_id` query parameter on the [HTTPS interface](/interfaces/http). 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.

```bash theme={null}
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](/integrations/python), JDBC/ODBC, and others. For `clickhouse-go` (v2), use HTTP mode as noted above.

<h3 id="check-which-replica">
  Check which replica you hit
</h3>

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.

<h2 id="subdomain-based-routing-deprecated">
  Subdomain-based routing (deprecated)
</h2>

<Danger>
  **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](#http-based-routing) instead. If you already use sticky subdomains, contact [support](https://clickhouse.com/support/program) to enable `session_id` routing. This is a breaking change and will require migration.
</Danger>

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.

<h2 id="limitations-of-replica-aware-routing">
  Limitations of replica-aware routing
</h2>

<h3 id="replica-aware-routing-does-not-guarantee-isolation">
  Stickiness can break during service changes
</h3>

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.

<h3 id="not-workload-isolation">
  Replica-aware routing isn't workload isolation
</h3>

Sticky routing only controls *which* replica handles a request. That replica may still serve other traffic. For dedicated compute, use [compute-compute separation](/cloud/reference/warehouses).

<h3 id="replica-aware-routing-does-not-work-out-of-the-box-with-private-link">
  Private Link and the deprecated subdomain method
</h3>

HTTP `session_id` routing works with [private networking](/cloud/security/connectivity/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.

<h3 id="replica-aware-routing-requires-http">
  Replica-aware routing requires the HTTP protocol
</h3>

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.

<h2 id="troubleshooting">
  Troubleshooting
</h2>

**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.
