<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Temir Kussainov</title>
    <description>The latest articles on DEV Community by Temir Kussainov (@protemir).</description>
    <link>https://dev.to/protemir</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4143530%2F43211e42-6857-44c4-9482-cc9ffaa1a556.JPG</url>
      <title>DEV Community: Temir Kussainov</title>
      <link>https://dev.to/protemir</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/protemir"/>
    <language>en</language>
    <item>
      <title>Why ClickHouse® fills the disk in self-hosted Langfuse and SigNoz, and how to fix it</title>
      <dc:creator>Temir Kussainov</dc:creator>
      <pubDate>Sat, 26 Sep 2026 04:40:18 +0000</pubDate>
      <link>https://dev.to/protemir/why-clickhouser-fills-the-disk-in-self-hosted-langfuse-and-signoz-and-how-to-fix-it-3l4c</link>
      <guid>https://dev.to/protemir/why-clickhouser-fills-the-disk-in-self-hosted-langfuse-and-signoz-and-how-to-fix-it-3l4c</guid>
      <description>&lt;p&gt;&lt;em&gt;Also in &lt;a href="https://diskvet.dev/es/guide/" rel="noopener noreferrer"&gt;Español&lt;/a&gt; · &lt;a href="https://diskvet.dev/pt/guide/" rel="noopener noreferrer"&gt;Português&lt;/a&gt; · &lt;a href="https://diskvet.dev/ru/guide/" rel="noopener noreferrer"&gt;Русский&lt;/a&gt; · &lt;a href="https://diskvet.dev/ja/guide/" rel="noopener noreferrer"&gt;日本語&lt;/a&gt; · &lt;a href="https://diskvet.dev/ko/guide/" rel="noopener noreferrer"&gt;한국어&lt;/a&gt; · &lt;a href="https://diskvet.dev/zh/guide/" rel="noopener noreferrer"&gt;中文&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Your Langfuse or SigNoz server is running out of disk, but your traces are small. In most public reports the space goes to ClickHouse® itself: to its own log tables, such as &lt;code&gt;system.trace_log&lt;/code&gt; and &lt;code&gt;system.text_log&lt;/code&gt;, which have no size limit by default. ClickStack has the same problem.&lt;/p&gt;

&lt;p&gt;This guide shows how to confirm it with one read-only query, free the space now, and stop it from coming back without hitting the known traps. You don't need any extra tools.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Tested on stock &lt;code&gt;clickhouse/clickhouse-server&lt;/code&gt; images 24.8, 25.12 and 26.9 (the SigNoz commands on 25.5 and 25.12), with the ClickHouse service and config taken from Langfuse's and SigNoz's compose files.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check.&lt;/strong&gt; Run one read-only query on &lt;code&gt;system.parts&lt;/code&gt;. If &lt;code&gt;system.*_log&lt;/code&gt; tables are bigger than your data, ClickHouse's own logs are the problem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free space now.&lt;/strong&gt; &lt;code&gt;TRUNCATE&lt;/code&gt; the big logs. For a table over 50 GB, add &lt;code&gt;SETTINGS max_table_size_to_drop = 0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stop it coming back.&lt;/strong&gt; Add a &lt;code&gt;config.d&lt;/code&gt; file with a TTL for each log (for &lt;code&gt;opentelemetry_span_log&lt;/code&gt; the TTL goes inside &lt;code&gt;&amp;lt;engine&amp;gt;&lt;/code&gt;), then restart ClickHouse.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clean up.&lt;/strong&gt; Drop the &lt;code&gt;*_log_0&lt;/code&gt;, &lt;code&gt;*_log_1&lt;/code&gt; copies that the restart leaves behind.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Still full?&lt;/strong&gt; Check Docker's container logs, deleted rows and stuck parts. On Langfuse, update Langfuse before you move ClickHouse to 26.8+.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. What is using the disk? Check ClickHouse disk usage by table
&lt;/h2&gt;

&lt;p&gt;Save this query as &lt;code&gt;size.sql&lt;/code&gt;. It lists the biggest tables by size on disk:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;database&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;formatReadableSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes_on_disk&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="k"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;database&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes_on_disk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Langfuse (docker compose).&lt;/strong&gt; Run this in the folder with Langfuse's &lt;code&gt;docker-compose.yml&lt;/code&gt;. Its compose file already sets &lt;code&gt;CLICKHOUSE_USER&lt;/code&gt; and &lt;code&gt;CLICKHOUSE_PASSWORD&lt;/code&gt; inside the container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-T&lt;/span&gt; clickhouse sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'clickhouse-client --user "$CLICKHOUSE_USER" --password "$CLICKHOUSE_PASSWORD" --readonly=1 --format PrettyCompact'&lt;/span&gt; &amp;lt; size.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SigNoz (docker compose).&lt;/strong&gt; The container is usually called &lt;code&gt;signoz-clickhouse&lt;/code&gt; (check with &lt;code&gt;docker ps&lt;/code&gt;). SigNoz's &lt;code&gt;users.xml&lt;/code&gt; leaves the &lt;code&gt;default&lt;/code&gt; user without a password:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; signoz-clickhouse clickhouse-client &lt;span class="nt"&gt;--readonly&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nt"&gt;--format&lt;/span&gt; PrettyCompact &amp;lt; size.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;--readonly=1&lt;/code&gt; makes the session read-only: ClickHouse refuses any change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to read it.&lt;/strong&gt; Compare the &lt;code&gt;system&lt;/code&gt; rows with your own data (&lt;code&gt;default&lt;/code&gt; for Langfuse, &lt;code&gt;signoz_*&lt;/code&gt; for SigNoz). If &lt;code&gt;system.trace_log&lt;/code&gt; or &lt;code&gt;system.text_log&lt;/code&gt; is at the top, go on to section 2.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. How do I free the disk space right now?
&lt;/h2&gt;

&lt;p&gt;Open a client with write access:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Langfuse&lt;/span&gt;
docker compose &lt;span class="nb"&gt;exec &lt;/span&gt;clickhouse sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'clickhouse-client --user "$CLICKHOUSE_USER" --password "$CLICKHOUSE_PASSWORD"'&lt;/span&gt;
&lt;span class="c"&gt;# SigNoz&lt;/span&gt;
docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; signoz-clickhouse clickhouse-client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Empty the big logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;TRUNCATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="k"&gt;system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trace_log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;TRUNCATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="k"&gt;system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text_log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;TRUNCATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="k"&gt;system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metric_log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;TRUNCATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="k"&gt;system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query_log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This deletes only ClickHouse's own diagnostics, not your traces, and needs no restart.&lt;/p&gt;

&lt;p&gt;Langfuse reads &lt;code&gt;system.query_log&lt;/code&gt; to follow some of its own queries (&lt;a href="https://github.com/langfuse/langfuse/issues/13123" rel="noopener noreferrer"&gt;#13123&lt;/a&gt;). So empty it, but don't switch it off.&lt;/p&gt;

&lt;h3&gt;
  
  
  TRUNCATE fails with Code 359? Tables over 50 GB
&lt;/h3&gt;

&lt;p&gt;ClickHouse won't drop or truncate a table bigger than &lt;code&gt;max_table_size_to_drop&lt;/code&gt; (default 50,000,000,000 bytes, about 46.6 GiB). The limit applies to &lt;code&gt;TRUNCATE&lt;/code&gt; too, and a bigger table fails with &lt;code&gt;Code: 359 ... (TABLE_SIZE_EXCEEDS_MAX_DROP_SIZE_LIMIT)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Big logs do hit it: the &lt;code&gt;text_log&lt;/code&gt; in &lt;a href="https://github.com/orgs/langfuse/discussions/15024" rel="noopener noreferrer"&gt;Langfuse discussion #15024&lt;/a&gt; was 59.20 GiB. There are two ways around it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option A.&lt;/strong&gt; Lift the limit for one statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- ClickHouse 23.12+: lift the limit for this one statement&lt;/span&gt;
&lt;span class="k"&gt;TRUNCATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="k"&gt;system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text_log&lt;/span&gt; &lt;span class="n"&gt;SETTINGS&lt;/span&gt; &lt;span class="n"&gt;max_table_size_to_drop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Option B.&lt;/strong&gt; Create the one-time flag file, then run the plain &lt;code&gt;TRUNCATE&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose &lt;span class="nb"&gt;exec &lt;/span&gt;clickhouse sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'touch /var/lib/clickhouse/flags/force_drop_table &amp;amp;&amp;amp; chmod 666 /var/lib/clickhouse/flags/force_drop_table'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(SigNoz: &lt;code&gt;docker exec signoz-clickhouse sh -c '...'&lt;/code&gt; with the same command.) ClickHouse deletes the flag after the first &lt;code&gt;DROP&lt;/code&gt; or &lt;code&gt;TRUNCATE&lt;/code&gt; that needs it, so create it again before the next big table.&lt;/p&gt;

&lt;p&gt;The space is back now, but the logs start growing again right away. Section 4 stops that. Section 3 explains why it happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Why are trace_log and text_log so big?
&lt;/h2&gt;

&lt;p&gt;ClickHouse writes its own diagnostics into tables in the &lt;code&gt;system&lt;/code&gt; database: &lt;code&gt;query_log&lt;/code&gt;, &lt;code&gt;trace_log&lt;/code&gt;, &lt;code&gt;text_log&lt;/code&gt;, &lt;code&gt;metric_log&lt;/code&gt; and more. The &lt;a href="https://clickhouse.com/docs/reference/system-tables/overview" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; says it plainly: "By default, table growth is unlimited."&lt;/p&gt;

&lt;p&gt;Recent &lt;a href="https://github.com/ClickHouse/ClickHouse/blob/master/programs/server/config.xml" rel="noopener noreferrer"&gt;default configs&lt;/a&gt; set a TTL only for a few small logs (since 25.9, &lt;code&gt;processors_profile_log&lt;/code&gt; keeps 30 days), not for the big ones. Two defaults make the big ones grow fast:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the query profiler is on and writes stack samples of running queries into &lt;code&gt;trace_log&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;text_log&lt;/code&gt; stores the server log at &lt;code&gt;trace&lt;/code&gt; level.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Public examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Langfuse &lt;a href="https://github.com/langfuse/langfuse/issues/13123" rel="noopener noreferrer"&gt;#13123&lt;/a&gt;:&lt;/strong&gt; &lt;code&gt;system.trace_log&lt;/code&gt; was 66.86 GiB, while the Langfuse tables listed there (&lt;code&gt;traces&lt;/code&gt;, &lt;code&gt;observations&lt;/code&gt;, &lt;code&gt;scores&lt;/code&gt;) took about 51 MiB together. The maintainers decided not to override ClickHouse's defaults and added a &lt;a href="https://langfuse.com/faq/all/reduce-clickhouse-disk-size" rel="noopener noreferrer"&gt;FAQ page&lt;/a&gt; instead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SigNoz &lt;a href="https://github.com/SigNoz/signoz/issues/12050" rel="noopener noreferrer"&gt;#12050&lt;/a&gt;:&lt;/strong&gt; more than 80 GB of system logs (including a &lt;code&gt;trace_log_0&lt;/code&gt; copy) next to less than 500 MB of telemetry. Truncating the &lt;code&gt;system.*&lt;/code&gt; tables freed about 80 GB. SigNoz's new Foundry installer sets TTLs; older docker compose installs don't have them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ClickStack Helm chart &lt;a href="https://github.com/ClickHouse/ClickStack-helm-charts/pull/275" rel="noopener noreferrer"&gt;PR #275&lt;/a&gt;:&lt;/strong&gt; a 10 Gi volume hit 100% after 10 days, with 5.2 GB of trace-level server logs and a 3.7 GB &lt;code&gt;system.text_log&lt;/code&gt; against ~70 MB of telemetry. The PR, merged in September 2026, adds a 7-day TTL.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. How do I set a TTL on ClickHouse system logs?
&lt;/h2&gt;

&lt;p&gt;A TTL makes ClickHouse delete old log rows by itself. Set it &lt;strong&gt;after&lt;/strong&gt; the &lt;code&gt;TRUNCATE&lt;/code&gt; from section 2, because of how ClickHouse applies it.&lt;/p&gt;

&lt;p&gt;When you add a TTL and restart, ClickHouse doesn't shrink the old table. It renames it to &lt;code&gt;trace_log_0&lt;/code&gt; with all its rows and creates a new one with the TTL. If you truncated first, these copies are tiny, and step 4 drops them.&lt;/p&gt;

&lt;p&gt;Run the SQL below in the same write-access client as in section 2.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: which logs have no TTL?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;formatReadableSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total_bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="k"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;engine_full&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'TTL [^S]*'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;ttl&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tables&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;database&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'system'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt; &lt;span class="k"&gt;LIKE&lt;/span&gt; &lt;span class="s1"&gt;'%MergeTree'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'_log(_[0-9]+)?$'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;total_bytes&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An empty &lt;code&gt;ttl&lt;/code&gt; means the log is kept forever. Names like &lt;code&gt;trace_log_0&lt;/code&gt; are old copies; step 4 removes them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: add a TTL file in config.d
&lt;/h3&gt;

&lt;p&gt;Save this as &lt;code&gt;clickhouse-ttl.xml&lt;/code&gt; next to &lt;code&gt;docker-compose.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;clickhouse&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Keep 7 days of ClickHouse's own logs. List only logs your server has. --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;query_log&amp;gt;&amp;lt;ttl&amp;gt;&lt;/span&gt;event_date + INTERVAL 7 DAY DELETE&lt;span class="nt"&gt;&amp;lt;/ttl&amp;gt;&amp;lt;/query_log&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;trace_log&amp;gt;&amp;lt;ttl&amp;gt;&lt;/span&gt;event_date + INTERVAL 7 DAY DELETE&lt;span class="nt"&gt;&amp;lt;/ttl&amp;gt;&amp;lt;/trace_log&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;text_log&amp;gt;&amp;lt;ttl&amp;gt;&lt;/span&gt;event_date + INTERVAL 7 DAY DELETE&lt;span class="nt"&gt;&amp;lt;/ttl&amp;gt;&amp;lt;/text_log&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;metric_log&amp;gt;&amp;lt;ttl&amp;gt;&lt;/span&gt;event_date + INTERVAL 7 DAY DELETE&lt;span class="nt"&gt;&amp;lt;/ttl&amp;gt;&amp;lt;/metric_log&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;asynchronous_metric_log&amp;gt;&amp;lt;ttl&amp;gt;&lt;/span&gt;event_date + INTERVAL 7 DAY DELETE&lt;span class="nt"&gt;&amp;lt;/ttl&amp;gt;&amp;lt;/asynchronous_metric_log&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;part_log&amp;gt;&amp;lt;ttl&amp;gt;&lt;/span&gt;event_date + INTERVAL 7 DAY DELETE&lt;span class="nt"&gt;&amp;lt;/ttl&amp;gt;&amp;lt;/part_log&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- The stock config defines this log with &amp;lt;engine&amp;gt;, so a separate &amp;lt;ttl&amp;gt;
         stops the server from starting (ClickHouse#88366). TTL goes inside. --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;opentelemetry_span_log&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;engine&amp;gt;&lt;/span&gt;ENGINE = MergeTree PARTITION BY toYYYYMM(finish_date) ORDER BY (finish_date, finish_time_us) TTL finish_date + INTERVAL 7 DAY DELETE&lt;span class="nt"&gt;&amp;lt;/engine&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/opentelemetry_span_log&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/clickhouse&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mount it into the &lt;code&gt;clickhouse&lt;/code&gt; service (keep your existing volume lines):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;clickhouse&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./clickhouse-ttl.xml:/etc/clickhouse-server/config.d/clickhouse-ttl.xml:ro&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three traps in this step:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;opentelemetry_span_log&lt;/code&gt; takes its TTL inside &lt;code&gt;&amp;lt;engine&amp;gt;&lt;/code&gt;.&lt;/strong&gt; The stock config defines this log with &lt;code&gt;&amp;lt;engine&amp;gt;&lt;/code&gt;, and per the &lt;a href="https://clickhouse.com/docs/reference/system-tables/overview" rel="noopener noreferrer"&gt;docs&lt;/a&gt; that conflicts with &lt;code&gt;&amp;lt;ttl&amp;gt;&lt;/code&gt;. The server then exits with &lt;code&gt;If 'engine' is specified for system table, TTL parameters should be specified directly inside 'engine'&lt;/code&gt; (&lt;a href="https://github.com/ClickHouse/ClickHouse/issues/88366" rel="noopener noreferrer"&gt;ClickHouse #88366&lt;/a&gt;). Copy &lt;code&gt;PARTITION BY&lt;/code&gt; and &lt;code&gt;ORDER BY&lt;/code&gt; from &lt;code&gt;SELECT engine_full FROM system.tables WHERE database = 'system' AND name = 'opentelemetry_span_log'&lt;/code&gt; (SigNoz's config also sorts by &lt;code&gt;trace_id&lt;/code&gt;). Or switch the log off with &lt;code&gt;&amp;lt;opentelemetry_span_log remove="1"/&amp;gt;&lt;/code&gt; (Langfuse's &lt;a href="https://langfuse.com/self-hosting/configuration/scaling" rel="noopener noreferrer"&gt;scaling docs&lt;/a&gt;). &lt;code&gt;remove&lt;/code&gt; doesn't delete the existing table, so drop it yourself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;List only the logs your server has.&lt;/strong&gt; A section in the config is what turns a log on (the stock &lt;code&gt;config.xml&lt;/code&gt; disables &lt;code&gt;session_log&lt;/code&gt; by commenting it out). SigNoz's own &lt;a href="https://github.com/SigNoz/signoz/blob/v0.129.0/deploy/common/clickhouse/config.xml" rel="noopener noreferrer"&gt;&lt;code&gt;config.xml&lt;/code&gt;&lt;/a&gt; doesn't enable &lt;code&gt;text_log&lt;/code&gt;, so delete that line there. Also add &lt;code&gt;processors_profile_log&lt;/code&gt;, which has no TTL in that file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Profile settings go into users.d, not config.d.&lt;/strong&gt; If you also turn off the query profiler (&lt;code&gt;query_profiler_real_time_period_ns&lt;/code&gt; and &lt;code&gt;query_profiler_cpu_time_period_ns&lt;/code&gt; = 0, as in Langfuse's scaling docs), put that &lt;code&gt;&amp;lt;profiles&amp;gt;&lt;/code&gt; block into &lt;code&gt;users.d/&lt;/code&gt;. In &lt;code&gt;config.d/&lt;/code&gt; it is silently ignored (&lt;a href="https://github.com/triggerdotdev/trigger.dev/issues/4343" rel="noopener noreferrer"&gt;trigger.dev #4343&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: restart ClickHouse
&lt;/h3&gt;

&lt;p&gt;The TTL from &lt;code&gt;config.d&lt;/code&gt; takes effect only when the server restarts (&lt;a href="https://kb.altinity.com/altinity-kb-setup-and-maintenance/altinity-kb-system-tables-eat-my-disk/" rel="noopener noreferrer"&gt;Altinity KB&lt;/a&gt;). A config reload is not enough. With compose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt; clickhouse     &lt;span class="c"&gt;# recreates the container with the new mount&lt;/span&gt;
docker compose ps clickhouse
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If ClickHouse keeps restarting, the reason is in its error log inside the container. &lt;code&gt;docker compose logs&lt;/code&gt; may not show it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;docker compose ps &lt;span class="nt"&gt;-aq&lt;/span&gt; clickhouse&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;:/var/log/clickhouse-server/clickhouse-server.err.log &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 20 clickhouse-server.err.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: drop the old trace_log_0 copies
&lt;/h3&gt;

&lt;p&gt;After the restart, every changed log has a copy like &lt;code&gt;trace_log_0&lt;/code&gt; (then &lt;code&gt;_1&lt;/code&gt;, &lt;code&gt;_2&lt;/code&gt; after later changes). The copy keeps all the old rows and has no TTL (ClickStack PR #275 upgrade note, &lt;a href="https://github.com/getsentry/snuba/issues/7311" rel="noopener noreferrer"&gt;Sentry snuba #7311&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;This query writes the &lt;code&gt;DROP&lt;/code&gt; statements for you. Read them, then paste them into the client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="s1"&gt;'DROP TABLE system.'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s1"&gt;' SETTINGS max_table_size_to_drop = 0;'&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tables&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;database&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'system'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'_log_[0-9]+$'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ClickHouse no longer writes to these tables. &lt;code&gt;DROP&lt;/code&gt; can't be undone.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: check the result
&lt;/h3&gt;

&lt;p&gt;Run the step 1 query again. Every big log should show a TTL, and no &lt;code&gt;_N&lt;/code&gt; names should be left.&lt;/p&gt;

&lt;p&gt;ClickHouse removes expired rows during merges, by default at most every 4 hours (&lt;a href="https://clickhouse.com/docs/reference/settings/merge-tree-settings/merge-with#merge_with_ttl_timeout" rel="noopener noreferrer"&gt;&lt;code&gt;merge_with_ttl_timeout&lt;/code&gt;&lt;/a&gt;), so the size shrinks over the next hours.&lt;/p&gt;

&lt;p&gt;A script can do the checking for you: &lt;a href="https://github.com/Protemir/diskvet" rel="noopener noreferrer"&gt;diskvet&lt;/a&gt; (my project) runs the step 1 check read-only and prints the &lt;code&gt;TRUNCATE&lt;/code&gt; commands, the TTL file and the &lt;code&gt;DROP&lt;/code&gt; list for your tables, with the flag for tables over the drop limit (see section 7).&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Disk still full? Where else the space goes
&lt;/h2&gt;

&lt;p&gt;Compare &lt;code&gt;df -h&lt;/code&gt; with the total size of all parts (&lt;code&gt;SELECT formatReadableSize(sum(bytes_on_disk)) FROM system.parts&lt;/code&gt;). If the disk holds much more than that, the space is outside ClickHouse's tables.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are Docker container logs filling the disk?
&lt;/h3&gt;

&lt;p&gt;Docker's default &lt;code&gt;json-file&lt;/code&gt; log driver has no size limit (&lt;code&gt;max-size&lt;/code&gt; defaults to &lt;code&gt;-1&lt;/code&gt;, see the &lt;a href="https://docs.docker.com/engine/logging/drivers/json-file/" rel="noopener noreferrer"&gt;Docker docs&lt;/a&gt;). In &lt;a href="https://github.com/langfuse/langfuse/issues/16339" rel="noopener noreferrer"&gt;Langfuse #16339&lt;/a&gt; the ClickHouse container's log reached 89.1 GiB and filled a 244 GiB root disk.&lt;/p&gt;

&lt;p&gt;Find the biggest ones:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'du -h /var/lib/docker/containers/*/*-json.log | sort -h | tail -5'&lt;/span&gt;
docker ps &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;--no-trunc&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt; &lt;span class="s1"&gt;'{{.ID}} {{.Names}}'&lt;/span&gt;   &lt;span class="c"&gt;# the folder name is the container ID&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To fix it, add a &lt;code&gt;logging:&lt;/code&gt; block to every service in &lt;code&gt;docker-compose.yml&lt;/code&gt;. In #16339 the Langfuse maintainers recommended doing it for all containers, not only ClickHouse. SigNoz's &lt;a href="https://github.com/SigNoz/signoz/blob/v0.129.0/deploy/docker/docker-compose.yaml" rel="noopener noreferrer"&gt;compose file&lt;/a&gt; already sets &lt;code&gt;50m&lt;/code&gt; × 3.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="na"&gt;logging&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;json-file&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;max-size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;50m"&lt;/span&gt;
        &lt;span class="na"&gt;max-file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run &lt;code&gt;docker compose up -d --force-recreate&lt;/code&gt;: log options apply only to newly created containers. Recreating also removes the old log file; in #16339 that freed 81 GiB.&lt;/p&gt;

&lt;p&gt;Two notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If your Docker daemon uses another logging driver, set retention there instead, because &lt;code&gt;driver: json-file&lt;/code&gt; overrides it.&lt;/li&gt;
&lt;li&gt;Langfuse's README (&lt;a href="https://github.com/langfuse/langfuse/pull/16363" rel="noopener noreferrer"&gt;PR #16363&lt;/a&gt;) describes the daemon-wide way: set &lt;code&gt;max-size&lt;/code&gt; and &lt;code&gt;max-file&lt;/code&gt; as daemon defaults, then restart Docker and recreate the containers. It also advises against truncating or rotating these files with external tools.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Are ClickHouse's own log files big?
&lt;/h3&gt;

&lt;p&gt;ClickHouse also writes plain log files to &lt;code&gt;/var/log/clickhouse-server&lt;/code&gt; (a volume in Langfuse's compose). By default they are at &lt;code&gt;trace&lt;/code&gt; level, rotated at 1000M, with up to 10 old files kept (&lt;a href="https://clickhouse.com/docs/reference/settings/server-settings/settings/other#logger" rel="noopener noreferrer"&gt;&lt;code&gt;logger&lt;/code&gt; docs&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;ClickStack PR #275 uses the values below. Save them as another &lt;code&gt;config.d&lt;/code&gt; file, mount it like the TTL file and restart ClickHouse (section 4, step 3):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;clickhouse&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;logger&amp;gt;&amp;lt;level&amp;gt;&lt;/span&gt;information&lt;span class="nt"&gt;&amp;lt;/level&amp;gt;&amp;lt;size&amp;gt;&lt;/span&gt;100M&lt;span class="nt"&gt;&amp;lt;/size&amp;gt;&amp;lt;count&amp;gt;&lt;/span&gt;10&lt;span class="nt"&gt;&amp;lt;/count&amp;gt;&amp;lt;/logger&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/clickhouse&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why do deleted rows still take space?
&lt;/h3&gt;

&lt;p&gt;Langfuse's data retention removes old rows with a &lt;a href="https://clickhouse.com/docs/reference/statements/delete" rel="noopener noreferrer"&gt;lightweight &lt;code&gt;DELETE&lt;/code&gt;&lt;/a&gt;. ClickHouse only marks such rows; the space comes back when the part is merged.&lt;/p&gt;

&lt;p&gt;Background merges skip parts over &lt;a href="https://clickhouse.com/docs/reference/settings/merge-tree-settings/max-bytes#max_bytes_to_merge_at_max_space_in_pool" rel="noopener noreferrer"&gt;&lt;code&gt;max_bytes_to_merge_at_max_space_in_pool&lt;/code&gt;&lt;/a&gt; (150 GiB), and old monthly partitions are rarely merged. In &lt;a href="https://github.com/orgs/langfuse/discussions/13969" rel="noopener noreferrer"&gt;Langfuse discussion #13969&lt;/a&gt; a May partition of ~802 GiB was ~85% deleted rows.&lt;/p&gt;

&lt;p&gt;Find the partitions with deleted rows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;database&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;partition_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;formatReadableSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes_on_disk&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;size&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;has_lightweight_delete&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;database&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;partition_id&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes_on_disk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then apply the delete mask, one partition at a time (&lt;a href="https://clickhouse.com/docs/reference/statements/alter/apply-deleted-mask" rel="noopener noreferrer"&gt;APPLY DELETED MASK&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;observations&lt;/span&gt; &lt;span class="n"&gt;APPLY&lt;/span&gt; &lt;span class="n"&gt;DELETED&lt;/span&gt; &lt;span class="n"&gt;MASK&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="k"&gt;PARTITION&lt;/span&gt; &lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="s1"&gt;'202605'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Careful:&lt;/strong&gt; this is a heavyweight mutation. It rewrites the affected parts, so it needs free space for the new copies and loads the disk. Run it off-peak and watch it with &lt;code&gt;SELECT * FROM system.mutations WHERE NOT is_done&lt;/code&gt;. In #13969 it freed ~360 GiB per replica in ~17 minutes.&lt;/p&gt;

&lt;p&gt;Since v3.179.0 the Langfuse worker can do this on a schedule: &lt;code&gt;LANGFUSE_CLICKHOUSE_DELETED_MASK_CLEANER_ENABLED=true&lt;/code&gt; (off by default; see &lt;code&gt;.env.prod.example&lt;/code&gt;, &lt;a href="https://github.com/langfuse/langfuse/pull/14035" rel="noopener noreferrer"&gt;PR #14035&lt;/a&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Are old parts stuck on disk? (inactive and detached parts)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;database&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;formatReadableSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes_on_disk&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="k"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;remove_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;oldest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;refcount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;max_refcount&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;database&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes_on_disk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inactive parts are left over from merges. ClickHouse deletes them after &lt;a href="https://clickhouse.com/docs/reference/settings/merge-tree-settings/other#old_parts_lifetime" rel="noopener noreferrer"&gt;&lt;code&gt;old_parts_lifetime&lt;/code&gt;&lt;/a&gt; (480 s), once no query uses them (&lt;code&gt;refcount&lt;/code&gt; = 1).&lt;/p&gt;

&lt;p&gt;If they pile up (112.55 GiB of them in Langfuse discussion #15024) and &lt;code&gt;oldest&lt;/code&gt; is hours ago, look for long queries in &lt;code&gt;system.processes&lt;/code&gt; and stop them with &lt;code&gt;KILL QUERY WHERE query_id = '...'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Detached parts stay on disk until you remove them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;database&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;formatReadableSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes_on_disk&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;size&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;detached_parts&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;database&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check &lt;code&gt;reason&lt;/code&gt; first. Remove a part with &lt;code&gt;ALTER TABLE &amp;lt;db&amp;gt;.&amp;lt;table&amp;gt; DROP DETACHED PART '&amp;lt;name&amp;gt;' SETTINGS allow_drop_detached = 1&lt;/code&gt;, not by deleting folders.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Upgrading ClickHouse? Check this first
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Langfuse + ClickHouse 26.8 or newer: update Langfuse first.&lt;/strong&gt; ClickHouse 26.8 changed the default of &lt;code&gt;input_format_read_datetime_number_as_raw_value&lt;/code&gt; from 1 to 0. Older Langfuse sends &lt;code&gt;DateTime64&lt;/code&gt; values as millisecond numbers, and on 26.8+ they end up stored as &lt;code&gt;9999-12-31 23:59:59&lt;/code&gt; (&lt;a href="https://github.com/langfuse/langfuse/issues/16858" rel="noopener noreferrer"&gt;Langfuse #16858&lt;/a&gt;: 0.59% to 21.43% of writes per project). The fix is &lt;a href="https://github.com/langfuse/langfuse/pull/16892" rel="noopener noreferrer"&gt;PR #16892&lt;/a&gt; (backported to v3 in &lt;a href="https://github.com/langfuse/langfuse/pull/16957" rel="noopener noreferrer"&gt;PR #16957&lt;/a&gt;), released in Langfuse v4.28.0 and v3.225.7. Langfuse partitions by month, so such rows land in partition &lt;code&gt;999912&lt;/code&gt;. Check your version and look for them:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;version&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;database&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;partition_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt;
  &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;
  &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;partition_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'9999'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;database&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;partition_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;After any upgrade, run the step 1 query from section 4 again.&lt;/strong&gt; When a release changes a log's schema, ClickHouse renames the current table and creates a new one, so new &lt;code&gt;_N&lt;/code&gt; copies appear. Drop them as in step 4.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. Check everything at once
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Protemir/diskvet" rel="noopener noreferrer"&gt;diskvet&lt;/a&gt; (my project) is an open-source (Apache-2.0) read-only script that runs most of the checks above and prints a report with the fix commands. It can't see Docker's log files, but it shows how much of the disk is outside ClickHouse's parts.&lt;/p&gt;

&lt;p&gt;On the machine with Langfuse's &lt;code&gt;docker-compose.yml&lt;/code&gt; (read &lt;code&gt;checks.sql&lt;/code&gt; before you run it):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSLO&lt;/span&gt; https://github.com/Protemir/diskvet/releases/latest/download/diskvet.sh
curl &lt;span class="nt"&gt;-fsSLO&lt;/span&gt; https://github.com/Protemir/diskvet/releases/latest/download/checks.sql
sh diskvet.sh report &lt;span class="nt"&gt;--docker&lt;/span&gt; auto &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; report.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For SigNoz, use &lt;code&gt;--docker signoz-clickhouse&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It reads only metadata from &lt;code&gt;system.*&lt;/code&gt; tables (&lt;code&gt;system.tables&lt;/code&gt;, &lt;code&gt;system.parts&lt;/code&gt;, &lt;code&gt;system.disks&lt;/code&gt;, &lt;code&gt;system.detached_parts&lt;/code&gt;, &lt;code&gt;system.mutations&lt;/code&gt;, &lt;code&gt;system.part_log&lt;/code&gt; and a few more), with &lt;code&gt;readonly=2&lt;/code&gt; and resource limits. It never reads rows of your tables, &lt;code&gt;system.query_log&lt;/code&gt; or query texts, and sends nothing anywhere. Nothing runs by itself: you read each fix and run it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;ClickHouse documentation and source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;System tables overview (unlimited growth, &lt;code&gt;&amp;lt;engine&amp;gt;&lt;/code&gt; vs &lt;code&gt;&amp;lt;ttl&amp;gt;&lt;/code&gt;, renaming on schema change): &lt;a href="https://clickhouse.com/docs/reference/system-tables/overview" rel="noopener noreferrer"&gt;https://clickhouse.com/docs/reference/system-tables/overview&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Default &lt;code&gt;config.xml&lt;/code&gt; (logs without TTL, &lt;code&gt;opentelemetry_span_log&lt;/code&gt; engine, &lt;code&gt;text_log&lt;/code&gt; and logger at &lt;code&gt;trace&lt;/code&gt;, &lt;code&gt;session_log&lt;/code&gt; commented out): &lt;a href="https://github.com/ClickHouse/ClickHouse/blob/master/programs/server/config.xml" rel="noopener noreferrer"&gt;https://github.com/ClickHouse/ClickHouse/blob/master/programs/server/config.xml&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;max_table_size_to_drop&lt;/code&gt;, server setting and &lt;code&gt;force_drop_table&lt;/code&gt;: &lt;a href="https://clickhouse.com/docs/reference/settings/server-settings/settings/max-table#max_table_size_to_drop" rel="noopener noreferrer"&gt;https://clickhouse.com/docs/reference/settings/server-settings/settings/max-table#max_table_size_to_drop&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;max_table_size_to_drop&lt;/code&gt;, query setting: &lt;a href="https://clickhouse.com/docs/reference/settings/session-settings/max#max_table_size_to_drop" rel="noopener noreferrer"&gt;https://clickhouse.com/docs/reference/settings/session-settings/max#max_table_size_to_drop&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Query-level override since 23.12: &lt;a href="https://github.com/ClickHouse/ClickHouse/pull/57452" rel="noopener noreferrer"&gt;https://github.com/ClickHouse/ClickHouse/pull/57452&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The flag is removed after use (&lt;code&gt;checkCanBeDropped&lt;/code&gt;): &lt;a href="https://github.com/ClickHouse/ClickHouse/blob/master/src/Interpreters/Context.cpp" rel="noopener noreferrer"&gt;https://github.com/ClickHouse/ClickHouse/blob/master/src/Interpreters/Context.cpp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;TRUNCATE: &lt;a href="https://clickhouse.com/docs/reference/statements/truncate" rel="noopener noreferrer"&gt;https://clickhouse.com/docs/reference/statements/truncate&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;opentelemetry_span_log&lt;/code&gt; TTL error: &lt;a href="https://github.com/ClickHouse/ClickHouse/issues/88366" rel="noopener noreferrer"&gt;https://github.com/ClickHouse/ClickHouse/issues/88366&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MergeTree settings: &lt;code&gt;merge_with_ttl_timeout&lt;/code&gt; (14400 s) &lt;a href="https://clickhouse.com/docs/reference/settings/merge-tree-settings/merge-with#merge_with_ttl_timeout" rel="noopener noreferrer"&gt;https://clickhouse.com/docs/reference/settings/merge-tree-settings/merge-with#merge_with_ttl_timeout&lt;/a&gt;, &lt;code&gt;old_parts_lifetime&lt;/code&gt; (480 s) &lt;a href="https://clickhouse.com/docs/reference/settings/merge-tree-settings/other#old_parts_lifetime" rel="noopener noreferrer"&gt;https://clickhouse.com/docs/reference/settings/merge-tree-settings/other#old_parts_lifetime&lt;/a&gt;, &lt;code&gt;max_bytes_to_merge_at_max_space_in_pool&lt;/code&gt; (150 GiB) &lt;a href="https://clickhouse.com/docs/reference/settings/merge-tree-settings/max-bytes#max_bytes_to_merge_at_max_space_in_pool" rel="noopener noreferrer"&gt;https://clickhouse.com/docs/reference/settings/merge-tree-settings/max-bytes#max_bytes_to_merge_at_max_space_in_pool&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Server log rotation (&lt;code&gt;logger&lt;/code&gt;: &lt;code&gt;level&lt;/code&gt;, &lt;code&gt;size&lt;/code&gt;, &lt;code&gt;count&lt;/code&gt;): &lt;a href="https://clickhouse.com/docs/reference/settings/server-settings/settings/other#logger" rel="noopener noreferrer"&gt;https://clickhouse.com/docs/reference/settings/server-settings/settings/other#logger&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Lightweight DELETE: &lt;a href="https://clickhouse.com/docs/reference/statements/delete" rel="noopener noreferrer"&gt;https://clickhouse.com/docs/reference/statements/delete&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;APPLY DELETED MASK: &lt;a href="https://clickhouse.com/docs/reference/statements/alter/apply-deleted-mask" rel="noopener noreferrer"&gt;https://clickhouse.com/docs/reference/statements/alter/apply-deleted-mask&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;system.parts: &lt;a href="https://clickhouse.com/docs/reference/system-tables/parts" rel="noopener noreferrer"&gt;https://clickhouse.com/docs/reference/system-tables/parts&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;system.detached_parts: &lt;a href="https://clickhouse.com/docs/reference/system-tables/detached_parts" rel="noopener noreferrer"&gt;https://clickhouse.com/docs/reference/system-tables/detached_parts&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;DROP DETACHED PART: &lt;a href="https://clickhouse.com/docs/reference/statements/alter/partition" rel="noopener noreferrer"&gt;https://clickhouse.com/docs/reference/statements/alter/partition&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;allow_drop_detached&lt;/code&gt;: &lt;a href="https://clickhouse.com/docs/reference/settings/session-settings/allow#allow_drop_detached" rel="noopener noreferrer"&gt;https://clickhouse.com/docs/reference/settings/session-settings/allow#allow_drop_detached&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;system.mutations: &lt;a href="https://clickhouse.com/docs/reference/system-tables/mutations" rel="noopener noreferrer"&gt;https://clickhouse.com/docs/reference/system-tables/mutations&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;KILL QUERY: &lt;a href="https://clickhouse.com/docs/reference/statements/kill" rel="noopener noreferrer"&gt;https://clickhouse.com/docs/reference/statements/kill&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Altinity KB, "System tables ate my disk" (restart needed): &lt;a href="https://kb.altinity.com/altinity-kb-setup-and-maintenance/altinity-kb-system-tables-eat-my-disk/" rel="noopener noreferrer"&gt;https://kb.altinity.com/altinity-kb-setup-and-maintenance/altinity-kb-system-tables-eat-my-disk/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;json-file logging driver (&lt;code&gt;max-size&lt;/code&gt; defaults to -1; existing containers keep old settings): &lt;a href="https://docs.docker.com/engine/logging/drivers/json-file/" rel="noopener noreferrer"&gt;https://docs.docker.com/engine/logging/drivers/json-file/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Langfuse:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;FAQ, reduce ClickHouse disk size: &lt;a href="https://langfuse.com/faq/all/reduce-clickhouse-disk-size" rel="noopener noreferrer"&gt;https://langfuse.com/faq/all/reduce-clickhouse-disk-size&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Scaling docs, ClickHouse system log tables: &lt;a href="https://langfuse.com/self-hosting/configuration/scaling" rel="noopener noreferrer"&gt;https://langfuse.com/self-hosting/configuration/scaling&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;#13123, system tables grow unbounded: &lt;a href="https://github.com/langfuse/langfuse/issues/13123" rel="noopener noreferrer"&gt;https://github.com/langfuse/langfuse/issues/13123&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;#16339, unbounded Docker log: &lt;a href="https://github.com/langfuse/langfuse/issues/16339" rel="noopener noreferrer"&gt;https://github.com/langfuse/langfuse/issues/16339&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #16363, Docker log rotation in the README (daemon defaults, no external truncation): &lt;a href="https://github.com/langfuse/langfuse/pull/16363" rel="noopener noreferrer"&gt;https://github.com/langfuse/langfuse/pull/16363&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Discussion #13969, lightweight-deleted rows: &lt;a href="https://github.com/orgs/langfuse/discussions/13969" rel="noopener noreferrer"&gt;https://github.com/orgs/langfuse/discussions/13969&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Discussion #15024, inactive parts and 59 GiB text_log: &lt;a href="https://github.com/orgs/langfuse/discussions/15024" rel="noopener noreferrer"&gt;https://github.com/orgs/langfuse/discussions/15024&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #14035, deleted-mask cleaner (released in v3.179.0): &lt;a href="https://github.com/langfuse/langfuse/pull/14035" rel="noopener noreferrer"&gt;https://github.com/langfuse/langfuse/pull/14035&lt;/a&gt;, &lt;a href="https://github.com/langfuse/langfuse/releases/tag/v3.179.0" rel="noopener noreferrer"&gt;https://github.com/langfuse/langfuse/releases/tag/v3.179.0&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;#16858, DateTime64 on ClickHouse 26.8+: &lt;a href="https://github.com/langfuse/langfuse/issues/16858" rel="noopener noreferrer"&gt;https://github.com/langfuse/langfuse/issues/16858&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #16892 and v3 backport PR #16957: &lt;a href="https://github.com/langfuse/langfuse/pull/16892" rel="noopener noreferrer"&gt;https://github.com/langfuse/langfuse/pull/16892&lt;/a&gt;, &lt;a href="https://github.com/langfuse/langfuse/pull/16957" rel="noopener noreferrer"&gt;https://github.com/langfuse/langfuse/pull/16957&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Releases with the fix: &lt;a href="https://github.com/langfuse/langfuse/releases/tag/v4.28.0" rel="noopener noreferrer"&gt;https://github.com/langfuse/langfuse/releases/tag/v4.28.0&lt;/a&gt;, &lt;a href="https://github.com/langfuse/langfuse/releases/tag/v3.225.7" rel="noopener noreferrer"&gt;https://github.com/langfuse/langfuse/releases/tag/v3.225.7&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SigNoz, ClickStack and others:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SigNoz #12050, 80+ GB of system logs: &lt;a href="https://github.com/SigNoz/signoz/issues/12050" rel="noopener noreferrer"&gt;https://github.com/SigNoz/signoz/issues/12050&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;SigNoz v0.129.0 ClickHouse &lt;code&gt;config.xml&lt;/code&gt; and &lt;code&gt;users.xml&lt;/code&gt;: &lt;a href="https://github.com/SigNoz/signoz/blob/v0.129.0/deploy/common/clickhouse/config.xml" rel="noopener noreferrer"&gt;https://github.com/SigNoz/signoz/blob/v0.129.0/deploy/common/clickhouse/config.xml&lt;/a&gt;, &lt;a href="https://github.com/SigNoz/signoz/blob/v0.129.0/deploy/common/clickhouse/users.xml" rel="noopener noreferrer"&gt;https://github.com/SigNoz/signoz/blob/v0.129.0/deploy/common/clickhouse/users.xml&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;SigNoz v0.129.0 &lt;code&gt;docker-compose.yaml&lt;/code&gt; (container &lt;code&gt;signoz-clickhouse&lt;/code&gt;, &lt;code&gt;max-size: 50m&lt;/code&gt;, &lt;code&gt;max-file: "3"&lt;/code&gt;): &lt;a href="https://github.com/SigNoz/signoz/blob/v0.129.0/deploy/docker/docker-compose.yaml" rel="noopener noreferrer"&gt;https://github.com/SigNoz/signoz/blob/v0.129.0/deploy/docker/docker-compose.yaml&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ClickStack Helm chart PR #275: &lt;a href="https://github.com/ClickHouse/ClickStack-helm-charts/pull/275" rel="noopener noreferrer"&gt;https://github.com/ClickHouse/ClickStack-helm-charts/pull/275&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Sentry snuba #7311, &lt;code&gt;*_log_N&lt;/code&gt; copies without TTL: &lt;a href="https://github.com/getsentry/snuba/issues/7311" rel="noopener noreferrer"&gt;https://github.com/getsentry/snuba/issues/7311&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;trigger.dev #4343, profile settings in config.d ignored: &lt;a href="https://github.com/triggerdotdev/trigger.dev/issues/4343" rel="noopener noreferrer"&gt;https://github.com/triggerdotdev/trigger.dev/issues/4343&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Written and tested by an AI agent: every command was run on the ClickHouse versions listed at the top. Also on &lt;a href="https://diskvet.dev/guide/" rel="noopener noreferrer"&gt;diskvet.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;ClickHouse is a registered trademark of ClickHouse, Inc. diskvet is not affiliated with ClickHouse, Inc. Langfuse, SigNoz and ClickStack are trademarks of their respective owners.&lt;/p&gt;

</description>
      <category>clickhouse</category>
      <category>devops</category>
      <category>selfhosted</category>
      <category>observability</category>
    </item>
  </channel>
</rss>
