NEW

Pulse 2025 Product Roundup: From Monitoring to AI-Native Control Plane

ClickHouse http_handlers: Custom HTTP Endpoints Guide

The ClickHouse HTTP interface ships with several built-in endpoints, including /, /ping, /replicas_status, and /play. The <http_handlers> configuration section lets you add custom routes, restrict existing ones, or serve predefined queries through a clean URL. This is the same machinery that powers features such as remote jemalloc pprof endpoints and lightweight REST-style APIs in front of ClickHouse.

Where Handlers Are Defined

HTTP handlers live in the server config, typically under /etc/clickhouse-server/config.d/. Each rule matches an incoming request by URL and method, then dispatches it to a handler. If you define <http_handlers> without <defaults/>, the built-in routes disappear, so almost every real config includes <defaults/> to keep /ping, /replicas_status, and the query interface working.

<?xml version="1.0" ?>
<clickhouse>
    <http_handlers>
        <rule>
            <url>/custom</url>
            <methods>GET,POST</methods>
            <handler>
                <type>predefined_query_handler</type>
                <query>SELECT 1</query>
            </handler>
        </rule>
        <defaults/>
    </http_handlers>
</clickhouse>

Handler Types

Type Purpose
dynamic_query_handler Accepts a query parameter from the URL or body, like the default / endpoint
predefined_query_handler Runs a fixed SQL statement embedded in the config
static Returns a static response with a configured status, content type, and body

The static type is what you use to disable an endpoint by returning 403, redirect traffic, or serve a health page that does not run SQL.

Example: Disable the /play UI

The web SQL console at /play is convenient in development but is often unwanted on production servers facing untrusted networks. A static handler returning 403 shuts it off without disabling the HTTP interface:

<?xml version="1.0" ?>
<clickhouse>
    <http_handlers>
        <rule>
            <url>/play</url>
            <methods>GET</methods>
            <handler>
                <type>static</type>
                <status>403</status>
                <content_type>text/plain; charset=UTF-8</content_type>
                <response_content></response_content>
            </handler>
        </rule>
        <defaults/>
    </http_handlers>
</clickhouse>

The <defaults/> tag preserves /, /ping, and the rest, so the rule only affects /play.

Example: Predefined Query Endpoint

Expose a curated query as a stable URL. Callers do not need to know the schema and cannot inject arbitrary SQL:

<rule>
    <url>/api/active_queries</url>
    <methods>GET</methods>
    <handler>
        <type>predefined_query_handler</type>
        <query>
            SELECT query_id, user, elapsed, read_rows
            FROM system.processes
            FORMAT JSON
        </query>
    </handler>
</rule>

A simple curl http://clickhouse:8123/api/active_queries returns the JSON response.

Key Configuration Elements

  • <url> matches the request path. Regex syntax is allowed when the value starts with regex:.
  • <methods> is a comma-separated list of HTTP verbs.
  • <handler> defines the response. Each type has its own required sub-elements.
  • <headers> (optional) can match specific request headers, useful for routing by Content-Type.
  • <empty_query_string/> enforces that no query is passed alongside a predefined handler.

Common Pitfalls

  • Omitting <defaults/> and accidentally disabling /ping, breaking health checks and load balancer probes.
  • Putting custom rules after <defaults/>. Order matters and the first match wins, so specific rules must come first.
  • Using predefined_query_handler with user-supplied parameters but no param_name validation, which can still allow SQL injection through substitutions.
  • Forgetting that handlers run as the authenticated user. Apply readonly profiles for endpoints exposed externally.

Frequently Asked Questions

Q: Can I serve different ClickHouse queries from the same hostname based on path? A: Yes, that is exactly what http_handlers is for. Define one <rule> per path with a predefined_query_handler.

Q: How do I keep the default endpoints working when I add custom rules? A: Include <defaults/> at the end of the <http_handlers> block. Without it, only your custom rules respond.

Q: Can I require authentication for custom handlers? A: Yes. Handlers reuse the standard HTTP authentication path. Use a dedicated read-only user with a restricted profile.

Q: Does static support files from disk? A: It can return inline content or a file path via <response_content>file://...</response_content>. Keep these files small, since they are served by the ClickHouse process.

Q: What is the difference between dynamic_query_handler and the default /? A: The default / already behaves like a dynamic handler. You only need to define one explicitly when you want to change the parameter name or constrain it to a specific URL.

Subscribe to the Pulse Newsletter

Get early access to new Pulse features, insightful blogs & exclusive events , webinars, and workshops.

We use cookies to provide an optimized user experience and understand our traffic. To learn more, read our use of cookies; otherwise, please choose 'Accept Cookies' to continue using our website.