ClickHouse
This is a deep dive into ClickHouse configuration. Follow one of the deployment guides to get started.
ClickHouse is the main OLAP storage solution within Langfuse for our Trace, Observation, and Score entities. It is optimized for high write throughput and fast analytical queries. This guide covers how to configure ClickHouse within Langfuse and what to keep in mind when (optionally) bringing your own ClickHouse.
Langfuse v3 supports ClickHouse versions >= 24.3. Langfuse v4 requires ClickHouse >= 25.12 (26.4 recommended) for lightweight updates, the JSON type, and full-text search โ see the v3 to v4 upgrade guide.
Official and Community Support
ClickHouse can be consumed as a managed service or self-managed on your own infrastructure. We distinguish between officially supported and community-supported deployment options:
| Option | Support Level |
|---|---|
| ClickHouse Cloud | Official |
| ClickHouse BYOC (Bring Your Own Cloud) | Official |
| ClickHouse Kubernetes Operator | Official |
| Bundled with the Langfuse Helm chart | Community |
| Single-container Docker (development only) | Community |
| Other managed ClickHouse offerings | Community |
- Official: Maintained and tested by the Langfuse team. We prioritize bug reports for these options.
- Community: Expected to work based on community usage. We do not systematically test these options; support is best-effort and fixes often depend on community contributions.
In either case, please report problems via GitHub issues โ pull requests that fix or improve support for community-supported options are highly welcome.
Configuration
Langfuse accepts the following environment variables to fine-tune your ClickHouse usage. They need to be provided for the Langfuse Web and Langfuse Worker containers.
| Variable | Required / Default | Description |
|---|---|---|
CLICKHOUSE_MIGRATION_URL | Required | Migration URL (TCP protocol) for the ClickHouse instance. Pattern: clickhouse://<hostname>:(9000/9440) |
CLICKHOUSE_MIGRATION_SSL | false | Set to true to establish an SSL connection to ClickHouse for the database migration. |
CLICKHOUSE_URL | Required | Hostname of the ClickHouse instance. Pattern: http(s)://<hostname>:(8123/8443) |
CLICKHOUSE_USER | Required | Username of the ClickHouse database. Needs the grants listed under user permissions. |
CLICKHOUSE_PASSWORD | Required | Password of the ClickHouse user. |
CLICKHOUSE_DB | default | Name of the ClickHouse database to use. |
CLICKHOUSE_CLUSTER_ENABLED | true | Whether to run ClickHouse commands ON CLUSTER. Set to false for single-container setups. |
LANGFUSE_AUTO_CLICKHOUSE_MIGRATION_DISABLED | false | Whether to disable automatic ClickHouse migrations. |
CLICKHOUSE_READ_ONLY_URL | Optional read-only endpoint used for public-API reads and selected UI/filter read queries. Falls back to CLICKHOUSE_URL when unset. Reuses CLICKHOUSE_USER, CLICKHOUSE_PASSWORD, and CLICKHOUSE_DB. Only useful on compute-compute separated clusters. See Scaling. |
Langfuse uses default as the cluster name if CLICKHOUSE_CLUSTER_ENABLED is set to true.
You can overwrite this by setting CLICKHOUSE_CLUSTER_NAME to a different value.
In that case, the database migrations will not apply correctly as they cannot run dynamically for different clusters.
You must set LANGFUSE_AUTO_CLICKHOUSE_MIGRATION_DISABLED = true and run ClickHouse migrations manually.
Clone the Langfuse repository, adjust the cluster name in ./packages/shared/clickhouse/migrations/clustered/*.sql and run cd ./packages/shared && sh ./clickhouse/scripts/up.sh
to manually apply the migrations.
Timezones
ClickHouse must run with its timezone set to UTC (the default). Langfuse does not support non-UTC ClickHouse timezones. Running ClickHouse with a different timezone (e.g. via the timezone server setting) will cause queries to return incorrect or empty results.
You can verify your ClickHouse timezone by running:
SELECT timezone()This should return UTC. If it does not, update your ClickHouse server configuration to remove any custom timezone setting and restart the server.
The same requirement applies to Postgres โ all infrastructure components must use UTC. Please vote on this GitHub Discussion if you would like us to consider supporting other timezones.
User Permissions
The ClickHouse user specified in CLICKHOUSE_USER must have the following grants to allow Langfuse to operate correctly.
Replace 'user' with your actual ClickHouse username and adjust the database name if you're using a different database than default.
Langfuse tables
Langfuse applies its ClickHouse schema migrations with the same user that it uses for reads and writes, so the user needs DDL grants in addition to SELECT and INSERT:
-- Read and write tracing data
GRANT SELECT, INSERT ON default.* TO 'user';
-- Update and delete rows: data retention, project and trace deletion, event updates
GRANT ALTER UPDATE, ALTER DELETE ON default.* TO 'user';
-- Apply schema migrations on startup
GRANT CREATE, DROP TABLE, DROP VIEW ON default.* TO 'user';
GRANT ALTER ADD COLUMN, ALTER MODIFY COLUMN, ALTER VIEW MODIFY QUERY ON default.* TO 'user';
GRANT ALTER ADD INDEX, ALTER DROP INDEX, ALTER MATERIALIZE INDEX ON default.* TO 'user';System tables
Langfuse v4 reads a small set of ClickHouse system tables to schedule background work. Only the columns that Langfuse actually reads need to be granted:
-- Partition and part discovery: event propagation, historic backfill, deleted-mask cleaner
GRANT SELECT(database, table, name, partition, partition_id, active, rows) ON system.parts TO 'user';
-- Mutation backpressure for the deleted-mask cleaner
GRANT SELECT(database, table, is_done) ON system.mutations TO 'user';
-- Table engine detection for the historic backfill
GRANT SELECT(database, name, engine) ON system.tables TO 'user';
-- Progress tracking for long-running migration queries and v4 transition usage detection
GRANT SELECT ON system.processes TO 'user';
GRANT SELECT ON system.query_log* TO 'user';The wildcard in system.query_log* also covers the rotated query_log_N tables that ClickHouse creates when the log table schema changes between versions.
Clustered deployments
With CLICKHOUSE_CLUSTER_ENABLED=true, Langfuse reads the system tables above through clusterAllReplicas() and runs DDL ON CLUSTER, which requires two additional grants:
-- Read system tables across all replicas through clusterAllReplicas()
GRANT READ ON REMOTE TO 'user';
-- Run ON CLUSTER queries. Required unless
-- access_control_improvements.on_cluster_queries_require_cluster_grant is
-- disabled on the server; it defaults to true.
GRANT CLUSTER ON *.* TO 'user';Grants are local to the node they are created on, unless your cluster uses a replicated access storage backend.
Create every grant on all nodes of the cluster, for example by adding ON CLUSTER:
GRANT ON CLUSTER default SELECT ON system.query_log* TO 'user';Historic backfill scratch table
The v4 historic backfill freezes merges on its intermediate table while it copies data:
GRANT SYSTEM SYNC REPLICA, SYSTEM MERGES, ALTER SETTINGS ON default.observations_pid_tid_sorting TO 'user';Which of the three is used depends on the table engine โ SYSTEM MERGES on self-managed MergeTree, ALTER SETTINGS on replicated and SharedMergeTree engines, SYSTEM SYNC REPLICA on replicated engines โ so granting all three keeps the backfill working on any deployment.
The grants can be created before the table exists, i.e. before the backfill starts.
Lightweight updates
With CLICKHOUSE_USE_LIGHTWEIGHT_UPDATE=true, Langfuse issues native UPDATE statements instead of ALTER TABLE ... UPDATE mutations.
ClickHouse rejects those unless enable_lightweight_update is enabled for the user:
CREATE SETTINGS PROFILE langfuse_lightweight_update SETTINGS enable_lightweight_update = 1 TO 'user';Direct ClickHouse Access for Custom Tools
Self-hosted deployments give you control over the underlying ClickHouse database. You can query it directly for internal dashboards, audits, migrations, or one-off debugging.
For production integrations and custom applications, prefer the Public API, SDK query helpers, MCP server, or Blob Storage Export. These interfaces are the compatibility targets across Langfuse releases.
The ClickHouse schema is not a stable API contract.
Major Langfuse upgrades, background migrations, and performance work such as Simplify Langfuse for Scale can change tables, columns, deduplication behavior, or join patterns at any time.
Custom queries that read traces, observations, scores, or internal materialized views should be validated as part of every Langfuse upgrade.
If you do query ClickHouse directly:
- Use a dedicated read-only user or a dedicated read-only compute group where available.
- Keep direct analytical traffic away from the primary ingestion path. On ClickHouse Cloud or BYOC, use separate compute groups and configure
CLICKHOUSE_READ_ONLY_URLfor supported Langfuse read paths, especially Public API and filter/helper reads. - Always include project and time filters where possible. Langfuse tracing data is optimized around project and time access patterns including monthly partitioning.
- Do not write directly to Langfuse tables. Use the Public API or SDKs for creating and updating Langfuse data.
- If a missing API filter or field forces you to query ClickHouse directly, please open a GitHub issue with your use case; APIs are the preferred long-term extension point.
Custom Schema Changes
We recommend running Langfuse on the unmodified ClickHouse schema.
Langfuse's ClickHouse schema and migrations are designed, tested, and versioned as a unit with each release.
Customizing the observations, events, or other table definitions moves that schema outside of what we test against โ which means keeping it compatible with future upgrades becomes your responsibility.
We'll provide best-effort support for issues arising from custom schema changes.
If a missing column, index, or table setting makes you consider a custom schema change, please open a GitHub issue with your use case first; improvements to the standard schema benefit all deployments and are covered by our regular testing and upgrade process.
Deployment Options
This section covers different deployment options and provides example environment variables.
Cloud/BYOC (recommended)
ClickHouse Cloud is a scalable and fully managed deployment option for ClickHouse. You can provision it directly from ClickHouse or through one of the cloud provider marketplaces:
ClickHouse Cloud clusters will be provisioned outside your cloud environment and your VPC, but ClickHouse offers private links for AWS, GCP, and Azure.
If you need the operational model of ClickHouse Cloud while keeping the ClickHouse data plane in your own cloud account, consider ClickHouse BYOC. BYOC is a fully managed ClickHouse Cloud deployment on infrastructure in your cloud account and is designed for large-scale deployments with strict data residency, compliance, or VPC-boundary requirements.
We recommend ClickHouse Cloud or BYOC for larger Langfuse deployments because they provide cloud-native scaling primitives that are not available in the self-managed OSS ClickHouse setup used by Langfuse. ClickHouse Cloud and BYOC separate storage from compute through SharedMergeTree, which helps scale compute independently of stored data, reduces replica storage overhead, and avoids manual shard planning for growth. They also support compute-compute separation through warehouses, so you can isolate ingestion writes, supported Langfuse reads, analytical queries, or ad-hoc workloads on separate compute groups that share the same data but do not compete for the same CPU and memory. Langfuse can use this pattern via CLICKHOUSE_READ_ONLY_URL for public-API reads and selected UI/filter read traffic.
If you need assistance or want to talk to the ClickHouse team, you can reach out to them here.
Example Configuration
Set the following environment variables to connect to your ClickHouse instance:
CLICKHOUSE_URL=https://<identifier>.<region>.aws.clickhouse.cloud:8443
CLICKHOUSE_MIGRATION_URL=clickhouse://<identifier>.<region>.aws.clickhouse.cloud:9440
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=changeme
CLICKHOUSE_MIGRATION_SSL=trueTroubleshooting
- 'error: driver: bad connection in line 0' during migration: If you see the previous error message during startup of your web container, ensure that the
CLICKHOUSE_MIGRATION_SSLflag is set and that Langfuse Web can access your ClickHouse environment. Review the IP whitelisting if applicable and whether the instance has access to the Private Link. - Code: 80. DB::Exception: It's not initial query. ON CLUSTER is not allowed for Replicated database. (INCORRECT_QUERY) (on ClickHouse Cloud Azure): ClickHouse Cloud Azure does not seem to handle the ON CLUSTER and Replicated settings well. We recommend to set
CLICKHOUSE_CLUSTER_ENABLED=falsefor now. This should not make any difference on performance or high availability.
ClickHouse Kubernetes Operator
The official ClickHouse Kubernetes Operator (GitHub) automates the deployment, configuration, and management of self-managed ClickHouse and ClickHouse Keeper clusters on Kubernetes, including upgrades, scaling, and high availability. It is the officially supported option for running self-managed ClickHouse on Kubernetes.
Follow the operator documentation to provision a cluster, then connect Langfuse to it using the environment variables described above.
The same user permissions and timezone requirements apply.
The Langfuse Helm chart uses the operator to deploy the bundled ClickHouse from chart version v2.0.0 onwards.
Bundled ClickHouse in the Langfuse Helm chart
The Langfuse Helm chart can deploy ClickHouse for you via clickhouse.deploy: true.
From chart version v2.0.0 onwards it does so through the ClickHouse Kubernetes Operator, rendering a ClickHouseCluster and a KeeperCluster resource.
The operator and cert-manager must be installed in the cluster before you install the chart; see the deployment guide.
This deployment option is community-supported. For an officially supported setup, use ClickHouse Cloud or BYOC, or manage the cluster with the operator yourself and connect Langfuse to it with clickhouse.deploy: false.
Chart v1.x deployed the bundled ClickHouse from a third-party sub-chart that cannot reach the ClickHouse version Langfuse v4 requires. If you still run chart v1.x with clickhouse.deploy: true, upgrade the chart to v2 before you upgrade Langfuse to v4.
Example Configuration
For a minimum production setup, we recommend the following values.yaml overrides:
clickhouse:
deploy: true
auth:
username: default
password: changeme # or point auth.existingSecret at a secret you manage
cluster:
replicas: 3
storage:
size: 100Gi # Start with a large volume to prevent early resizing. Alternatively, consider a blob storage-backed disk.
resources:
requests:
cpu: "2"
memory: 8Gi
limits:
memory: 16Gi
keeper:
replicas: 3- Shards: Shards are used for horizontally scaling ClickHouse. A single ClickHouse shard can handle multiple Terabytes of data. Today, Langfuse does not support a multi-shard cluster, and the chart always deploys a single shard. Please get in touch with us if you hit scaling limits of a single shard cluster, or consider ClickHouse Cloud/BYOC.
- cluster.replicas: ClickHouse counts all instances towards the number of replicas, i.e. a replica count of 1 means no redundancy at all. We recommend a minimum of 3 replicas for production setups. The number of replicas cannot be increased at runtime without manual intervention or downtime.
- cluster.resources: ClickHouse is CPU and memory intensive for analytical and highly concurrent requests. The chart defaults are sized for local experimentation; start from the minimum infrastructure requirements and scale up for larger deployments.
- keeper.replicas: ClickHouse Keeper coordinates replication and requires an odd replica count. Use 3 for production high availability.
- auth: The username and password Langfuse uses to connect. Overwrite these values according to your preferences, or mount them from a secret via
auth.existingSecret. - Disk: The chart uses the default storage class unless you set
cluster.storage.className. Ensure that the storage class hasallowVolumeExpansion = true, as observability workloads tend to be very disk heavy. For cloud providers like AWS, GCP, and Azure this should be the default.
Langfuse assumes that certain parameters are set in the ClickHouse configurations. To perform our database migrations, the following values must be provided:
<!--
Substitutions for parameters of replicated tables.
Optional. If you don't use replicated tables, you could omit that.
See https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/replication/#creating-replicated-tables
-->
<!--
<macros>
<shard>01</shard>
<replica>example01-01-1</replica>
</macros>
-->
<!--
<default_replica_path>/clickhouse/tables/{database}/{table}</default_replica_path>
<default_replica_name>{replica}</default_replica_name>
-->macros and default_replica_* configuration is handled by the chart and the operator without any further configuration.
When clickhouse.deploy is true, the chart wires Langfuse to the bundled cluster automatically. For a ClickHouse you run yourself in the same cluster and namespace, set clickhouse.deploy: false and the following environment variables:
CLICKHOUSE_URL=http://<clickhouse-service>:8123
CLICKHOUSE_MIGRATION_URL=clickhouse://<clickhouse-service>:9000
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=changemeTroubleshooting
-
NOT_ENOUGH_SPACE error: This error occurs when ClickHouse runs out of disk space. In Kubernetes environments, this typically means the persistent volume claims (PVCs) need to be expanded. Here's how to resolve it:
1. Check current disk usage:
# List the ClickHouse PVCs; their names depend on how ClickHouse was deployed kubectl get pvc # Check disk usage inside ClickHouse pods kubectl exec -it <clickhouse-pod-name> -- df -h /var/lib/clickhouse2. Expand the PVC (requires storage class with allowVolumeExpansion: true):
# Edit the PVC directly kubectl edit pvc <clickhouse-pvc-name> # Or patch it in place; repeat for the PVC of every replica kubectl patch pvc <clickhouse-pvc-name> -p '{"spec":{"resources":{"requests":{"storage":"200Gi"}}}}'3. Monitor expansion progress:
# Watch PVC status kubectl get pvc -w # Check if pods recognize the new space kubectl exec -it <clickhouse-pod-name> -- df -h /var/lib/clickhouse4. Restart StatefulSet:
# Restart all pods individually to make use of the larger volumes kubectl rollout restart statefulset <clickhouse-statefulset-name>Prevention tips:
- Set up monitoring alerts for disk usage (recommend alerting at 80% capacity)
- Use storage classes with
allowVolumeExpansion: true(default for most cloud providers) - Consider implementing automatic PVC expansion using tools like volume-autoscaler
- For high-growth environments, consider using blob storage as disk for automatic scaling
Docker
You can run ClickHouse in a single Docker container for development purposes. As there is no redundancy, this is not recommended for production workloads.
Example Configuration
Start the container with
docker run --name clickhouse-server \
-e CLICKHOUSE_DB=default \
-e CLICKHOUSE_USER=clickhouse \
-e CLICKHOUSE_PASSWORD=clickhouse \
-d --ulimit nofile=262144:262144 \
-p 8123:8123 \
-p 9000:9000 \
-p 9009:9009 \
clickhouse/clickhouse-serverSet the following environment variables to connect to your ClickHouse instance:
CLICKHOUSE_URL=http://localhost:8123
CLICKHOUSE_MIGRATION_URL=clickhouse://localhost:9000
CLICKHOUSE_USER=clickhouse
CLICKHOUSE_PASSWORD=clickhouse
CLICKHOUSE_CLUSTER_ENABLED=falseMigrating to a New Instance
You may want to move Langfuse to a different ClickHouse instance, e.g. when switching providers or moving from a single-node to a clustered setup. We recommend the following approach:
- Point Langfuse to the new ClickHouse instance so that incoming data is captured there.
- Create a backup of the existing instance to blob storage and restore it into the new instance.
A zero-downtime switch where data is written to both instances concurrently is technically possible, but we have not tested it and it is not recommended by ClickHouse. Please reach out to Langfuse Support if you want to explore this option.
Refer to the ClickHouse migration guides for backup and restore instructions:
Encryption
ClickHouse supports disk encryption for data at rest, providing an additional layer of security for sensitive data.
Automatic Encryption with Blob Storage
When using blob storage as disk (AWS S3, Azure Blob Storage, Google Cloud Storage), data is automatically encrypted at rest using the cloud provider's default encryption:
- AWS S3: Uses AES-256 encryption by default
- Azure Blob Storage: Uses AES-256 encryption by default
- Google Cloud Storage: Uses AES-256 encryption by default
Manual Disk Encryption
For local disk storage or additional encryption layers, ClickHouse supports configurable disk encryption using the AES_128_CTR algorithm.
Kubernetes Configuration
On Kubernetes, mount the following ClickHouse server configuration into /etc/clickhouse-server/config.d/:
<!-- encrypted_storage.xml -->
<clickhouse>
<storage_configuration>
<disks>
<encrypted_disk>
<type>encrypted</type>
<disk>default</disk>
<path>encrypted/</path>
<algorithm>AES_128_CTR</algorithm>
<key_hex id="0" from_env="CLICKHOUSE_ENCRYPTION_KEY"></key_hex>
</encrypted_disk>
</disks>
<policies>
<encrypted_policy>
<volumes>
<main>
<disk>encrypted_disk</disk>
</main>
</volumes>
</encrypted_policy>
</policies>
</storage_configuration>
<merge_tree>
<storage_policy>encrypted_policy</storage_policy>
</merge_tree>
</clickhouse>With the ClickHouse Kubernetes Operator, add the file to the configuration of your cluster resource. With the Langfuse Helm chart, pass the same settings via clickhouse.cluster.settings.
Provide the key to the ClickHouse pods through a CLICKHOUSE_ENCRYPTION_KEY environment variable that reads from a secret:
kubectl create secret generic clickhouse-encryption-key \
--from-literal=key="00112233445566778899aabbccddeeff"Blob Storage as Disk
ClickHouse supports blob storages (AWS S3, Azure Blob Storage, Google Cloud Storage) as disks. This is useful for auto-scaling storages that live outside the container orchestrator and increases availability und durability of the data. For a full overview of the feature, see the ClickHouse External Disks documentation.
Below, we give a config.xml example to use S3 and Azure Blob Storage as disks for ClickHouse Docker containers using Docker Compose. Keep in mind that metadata is still stored on local disk, i.e. you need to use a persistent volume for the ClickHouse container or risk losing access to your tables.
We recommend the following settings when using Blob Storage as a disk for your ClickHouse deployment:
- Do not enable bucket versioning: ClickHouse will write and update many files within its merge processing. Having versioned buckets will retain the full history and quickly grow your storage consumption.
- Do not enable lifecycle policies for deletion: Avoid deletion lifecycle policies as this may break ClickHouse's internal consistency model. Instead, delete data via the Langfuse application or using ClickHouse TTLs.
- Enable lifecycle policies for aborted multi-part uploads: If ClickHouse attempts an upload, but aborts it before completion undesirable artifacts may remain.
This is being derived from this ClickHouse issue.
S3 Example
Create a config.xml file with the following contents in your local working directory:
<clickhouse>
<merge_tree>
<storage_policy>s3</storage_policy>
</merge_tree>
<storage_configuration>
<disks>
<s3>
<type>object_storage</type>
<object_storage_type>s3</object_storage_type>
<metadata_type>local</metadata_type>
<endpoint>https://s3.eu-central-1.amazonaws.com/example-bucket-name/data/</endpoint>
<access_key_id>ACCESS_KEY</access_key_id>
<secret_access_key>ACCESS_KEY_SECRET</secret_access_key>
</s3>
</disks>
<policies>
<s3>
<volumes>
<main>
<disk>s3</disk>
</main>
</volumes>
</s3>
</policies>
</storage_configuration>
</clickhouse>Replace the Access Key Id and Secret Access key with appropriate AWS credentials and change the bucket name within the endpoint element.
Alternatively, you can replace the credentials with <use_environment_credentials>1</use_environment_credentials> to automatically retrieve AWS credentials from environment variables.
Now, you can start ClickHouse with the following Docker Compose file:
services:
clickhouse:
image: clickhouse/clickhouse-server
user: "101:101"
container_name: clickhouse
hostname: clickhouse
environment:
CLICKHOUSE_DB: default
CLICKHOUSE_USER: clickhouse
CLICKHOUSE_PASSWORD: clickhouse
volumes:
- ./config.xml:/etc/clickhouse-server/config.d/s3disk.xml:ro
- langfuse_clickhouse_data:/var/lib/clickhouse
- langfuse_clickhouse_logs:/var/log/clickhouse-server
ports:
- "8123:8123"
- "9000:9000"
volumes:
langfuse_clickhouse_data:
driver: local
langfuse_clickhouse_logs:
driver: localAzure Blob Storage Example
Create a config.xml file with the following contents in your local working directory. The credentials below are the default Azurite credentials and considered public.
<clickhouse>
<merge_tree>
<storage_policy>blob_storage_disk</storage_policy>
</merge_tree>
<storage_configuration>
<disks>
<blob_storage_disk>
<type>object_storage</type>
<object_storage_type>azure_blob_storage</object_storage_type>
<metadata_type>local</metadata_type>
<storage_account_url>http://azurite:10000/devstoreaccount1</storage_account_url>
<container_name>langfuse</container_name>
<account_name>devstoreaccount1</account_name>
<account_key>Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==</account_key>
</blob_storage_disk>
</disks>
<policies>
<blob_storage_disk>
<volumes>
<main>
<disk>blob_storage_disk</disk>
</main>
</volumes>
</blob_storage_disk>
</policies>
</storage_configuration>
</clickhouse>You can start ClickHouse together with an Azurite service using the following Docker Compose file:
services:
clickhouse:
image: clickhouse/clickhouse-server
user: "101:101"
container_name: clickhouse
hostname: clickhouse
environment:
CLICKHOUSE_DB: default
CLICKHOUSE_USER: clickhouse
CLICKHOUSE_PASSWORD: clickhouse
volumes:
- ./config.xml:/etc/clickhouse-server/config.d/azuredisk.xml:ro
- langfuse_clickhouse_data:/var/lib/clickhouse
- langfuse_clickhouse_logs:/var/log/clickhouse-server
ports:
- "8123:8123"
- "9000:9000"
depends_on:
- azurite
azurite:
image: mcr.microsoft.com/azure-storage/azurite
container_name: azurite
command: azurite-blob --blobHost 0.0.0.0
ports:
- "10000:10000"
volumes:
- langfuse_azurite_data:/data
volumes:
langfuse_clickhouse_data:
driver: local
langfuse_clickhouse_logs:
driver: local
langfuse_azurite_data:
driver: localThis will store ClickHouse data within the Azurite bucket.
FAQ
Is ClickHouse required for self-hosting Langfuse?
Yes, ClickHouse is currently a required component for self-hosting Langfuse. There is no alternative OLAP database supported at this time. Langfuse cannot be self-hosted without using ClickHouse as the main storage solution for traces, observations, and scores.
All self-hosted deployments must include a ClickHouse instance.
How do I manage ClickHouse storage growth?
Langfuse has a built-in Data Retention feature that automatically deletes traces, observations, scores, and media assets older than a configured number of days. This runs nightly and handles cleanup across both ClickHouse and blob storage. You do not need to set ClickHouse TTLs manually.
If ClickHouse disk usage keeps growing despite retention being configured, the cause is often system log tables (trace_log, text_log, opentelemetry_span_log, etc.) that ship without a TTL. See Scaling โบ ClickHouse system log tables for how to disable or cap them.
If you experience any issues when self-hosting Langfuse, please:
- Check out Troubleshooting & FAQ page.
- Use Ask AI to get instant answers to your questions.
- Ask the maintainers on GitHub Discussions.
- Create a bug report or feature request on GitHub.
Enterprise-grade support is available when self-hosting Langfuse. Learn more on our pricing page.
Last edited