Databases 16 min read

How to Implement Multi‑Tenant Resource Isolation in ClickHouse Using Quotas and Profiles

This article demonstrates how to achieve multi‑tenant resource isolation in ClickHouse by configuring XML files, leveraging Quotas and Settings Profiles, and transitioning to SQL‑driven access control with roles, illustrating practical steps, code snippets, and best practices for secure user management.

GrowingIO Tech Team
GrowingIO Tech Team
GrowingIO Tech Team
How to Implement Multi‑Tenant Resource Isolation in ClickHouse Using Quotas and Profiles

Introduction

Providing multi‑tenant isolation in ClickHouse is essential to prevent a single user from exhausting database resources and affecting others. Beyond hardware isolation, a cost‑effective method uses ClickHouse's built‑in resource‑limiting mechanisms.

Resource‑Limiting Mechanisms

ClickHouse offers two primary ways to control user resources:

Quotas : limit usage over a time interval (e.g., number of queries per 10 seconds).

Settings Profiles : a collection of settings applied per query, independent of time.

Both can be defined in XML configuration files or managed via SQL.

XML Configuration Example

<code>&lt;?xml version="1.0"?&gt;
&lt;yandex&gt;
  &lt;logger&gt;
    &lt;level&gt;trace&lt;/level&gt;
    &lt;log&gt;/tmp/log/clickhouse-server.log&lt;/log&gt;
    &lt;errorlog&gt;/tmp/log/clickhouse-server.err.log&lt;/errorlog&gt;
    &lt;size&gt;1000M&lt;/size&gt;
    &lt;count&gt;10&lt;/count&gt;
  &lt;/logger&gt;
  &lt;query_log&gt;
    &lt;database&gt;system&lt;/database&gt;
    &lt;table&gt;query_log&lt;/table&gt;
    &lt;partition_by&gt;toYYYYMM(event_date)&lt;/partition_by&gt;
    &lt;flush_interval_milliseconds&gt;1000&lt;/flush_interval_milliseconds&gt;
  &lt;/query_log&gt;
  &lt;tcp_port&gt;9000&lt;/tcp_port&gt;
  &lt;listen_host&gt;127.0.0.1&lt;/listen_host&gt;
  &lt;max_concurrent_queries&gt;500&lt;/max_concurrent_queries&gt;
  &lt;mark_cache_size&gt;5368709120&lt;/mark_cache_size&gt;
  &lt;path&gt;./clickhouse/&lt;/path&gt;
  &lt;users_config&gt;users.xml&lt;/users_config&gt;
&lt;/yandex&gt;</code>

The corresponding

users.xml

defines profiles, quotas, and users:

<code>&lt;?xml version="1.0"?&gt;
&lt;yandex&gt;
  &lt;profiles&gt;
    &lt;default&gt;
      &lt;readonly&gt;1&lt;/readonly&gt;
    &lt;/default&gt;
    &lt;pA&gt;
      &lt;max_memory_usage&gt;10G&lt;/max_memory_usage&gt;
      &lt;max_memory_usage_for_user&gt;10G&lt;/max_memory_usage_for_user&gt;
      &lt;max_memory_usage_for_all_queries&gt;10G&lt;/max_memory_usage_for_all_queries&gt;
      &lt;max_query_size&gt;1073741824&lt;/max_query_size&gt;
      &lt;readonly&gt;1&lt;/readonly&gt;
    &lt;/pA&gt;
  &lt;/profiles&gt;
  &lt;users&gt;
    &lt;zeppelin&gt;
      &lt;password&gt;password&lt;/password&gt;
      &lt;networks&gt;
        &lt;ip&gt;::/0&lt;/ip&gt;
      &lt;/networks&gt;
      &lt;profile&gt;pA&lt;/profile&gt;
      &lt;quota&gt;qA&lt;/quota&gt;
    &lt;/zeppelin&gt;
  &lt;/users&gt;
  &lt;quotas&gt;
    &lt;qA&gt;
      &lt;interval&gt;
        &lt;duration&gt;10&lt;/duration&gt; <!-- 10 seconds -->
        &lt;queries&gt;2&lt;/queries&gt;
      &lt;/interval&gt;
    &lt;/qA&gt;
  &lt;/quotas&gt;
&lt;/yandex&gt;</code>

These files bind the user

zeppelin

to profile

pA

and quota

qA

, limiting the user to two queries every ten seconds.

Profile vs. Quota

Profiles apply settings per query (e.g.,

readonly

), while quotas are time‑based counters. A profile’s

max_rows_to_read

limits rows read in a single query, not over the user’s lifetime.

Quotas allow you to limit resource usage over a period of time or track the use of resources. A settings profile is a collection of settings grouped under the same name.

Quotas behave similarly to a token‑bucket algorithm: tokens are generated each interval; once exhausted, further queries are rejected until the next interval replenishes the bucket.

SQL‑Driven Access Control

ClickHouse recommends using SQL‑driven workflows for managing users, roles, profiles, and quotas. This approach avoids the rigidity of static XML files and enables dynamic, programmatic changes.

Both of the configuration methods work simultaneously, so if you use the server configuration files for managing accounts and access rights, you can smoothly switch to SQL‑driven workflow.

Step‑by‑Step Solution

Create a super‑admin user

ledzeppelin

and a regular user

zeppelin

using SQL.

Revoke all privileges from the default user and make it read‑only via a profile.

Create a settings profile, a quota, and a role, then bind them together.

Grant the role to

zeppelin

, effectively applying the profile and quota.

<code>CREATE USER ledzeppelin;</code>
<code>GRANT ALL ON *.* TO ledzeppelin WITH GRANT OPTION;</code>
<code>CREATE USER zeppelin;</code>
<code>CREATE SETTINGS PROFILE IF NOT EXISTS z_profile SETTINGS readonly = 2;</code>
<code>CREATE QUOTA IF NOT EXISTS z_quota FOR INTERVAL 10 second MAX queries 1;</code>
<code>CREATE ROLE IF NOT EXISTS z_role;</code>
<code>GRANT SELECT ON db.* TO z_role;</code>
<code>ALTER SETTINGS PROFILE z_profile TO z_role;</code>
<code>ALTER QUOTA z_quota TO z_role;</code>
<code>GRANT z_role TO zeppelin;</code>

If a role needs to be changed, revoke it from the user, modify the profile or quota, then grant the role again.

<code>REVOKE z_role FROM zeppelin;
-- modify profile/quota
GRANT z_role TO zeppelin;</code>

Persistence of SQL‑Created Entities

SQL‑driven access entities are stored under the directory defined by

access_control_path

(default

/var/lib/clickhouse/access/

). After a server restart, ClickHouse reloads these files, preserving the configurations.

<code>&lt;yandex&gt;
  ...
  &lt;access_control_path&gt;/var/lib/clickhouse/access/ledzeppelin/&lt;/access_control_path&gt;
  ...
&lt;/yandex&gt;</code>

Conclusion

The article shows how to start from ClickHouse user resource isolation, use Quotas and Settings Profiles for enforcement, and extend to full user management with roles. Both XML configuration and SQL‑driven methods are viable, with the latter being the recommended, flexible approach for modern deployments.

ClickHouseResource IsolationRolesQuotasSettings ProfilesSQL Access Control
GrowingIO Tech Team
Written by

GrowingIO Tech Team

The official technical account of GrowingIO, showcasing our tech innovations, experience summaries, and cutting‑edge black‑tech.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.