How to Self-Host Langfuse on a VPS for LLM Tracing, Metrics, and Evals
Building AI tools is exciting, but knowing exactly how they work inside can be hard. Langfuse is a powerful and open-source platform for LLM tracing, metrics, and evals. If you want to keep your data private and lower your costs, the best option is to self host Langfuse on VPS.
This guide will show you how to deploy Langfuse using Docker, Postgres, ClickHouse, and a reverse proxy with SSL.
Table of Contents
Why You Should Self Host Langfuse on VPS
Many engineering teams rely on cloud services, but data privacy is so important for AI applications. When you self host Langfuse on VPS, your prompts, completions, and user data never leave your server. Also, you avoid paying expensive cloud fees, which makes your observability stack completely free besides server costs.
This method is ideal for startups, enterprise technical buyers, and security-focused teams who want full control over their infrastructure.
Server Resource Requirements for Self-hosting Langfuse
Langfuse runs multiple microservices, including a web UI, a background worker, PostgreSQL for settings, ClickHouse for fast analytical queries, Redis for queues, and MinIO for file storage.
To self host Langfuse on VPS smoothly for a production environment, you need at least 4 CPU cores, 16GB of RAM, and 100GB of disk space. A reliable Linux VPS server provides the best foundation for this stack.
However, if your AI application involves image generation workflows like Automatic1111 or ComfyUI alongside your LLMs, you will need dedicated hardware. You can check this guide on the best GPU server for Stable Diffusion to see which graphics cards can handle heavy inference while your VPS runs Langfuse in the background.
Once you are done with the foundation, you can proceed to the following steps to deploy Langfuse.
Step 1. Install Docker and Git
Before deploying the platform, log in to your server via SSH and update your system packages. Docker is essential because it isolates the application components, which ensures they run the same everywhere.
Run the following commands to install Docker and Git:
sudo apt update && sudo apt upgrade -y
sudo apt install docker.io docker-compose git -y
sudo systemctl enable docker
sudo systemctl start docker
Step 2. Create the Environment File
Instead of downloading files directly from GitHub, it is better to create a directory and define your configurations manually. When you self host Langfuse on VPS, you must define secure database passwords and encryption keys so your environment remains safe.
Create a directory and the .env file:
sudo mkdir langfuse && sudo cd langfuse
sudo nano .env
Paste the following values in the file, and make sure to replace the dummy passwords and keys with secure strings:
POSTGRES_PASSWORD=YourSecurePostgresPassword
CLICKHOUSE_PASSWORD=YourSecureClickHousePassword
MINIO_PASSWORD=YourSecureMinioPassword
NEXTAUTH_SECRET=YourGeneratedNextAuthSecret
SALT=YourGeneratedSalt
ENCRYPTION_KEY=0000000000000000000000000000000000000000000000000000000000000000
Tip: You can generate the ENCRYPTION_KEY securely by running openssl rand -hex 32 in your terminal.
Step 3. Create the Docker Compose File
At this point, you need to define the services. Create the configuration file by running the command below:
sudo nano docker-compose.yml
This file tells Docker to pull the Langfuse images and connect them to PostgreSQL, ClickHouse, Redis, and MinIO.
Paste the following complete configuration into the file:
services:
langfuse-web:
image: langfuse/langfuse:3
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://langfuse:${POSTGRES_PASSWORD}@postgres:5432/langfuse
- NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
- SALT=${SALT}
- ENCRYPTION_KEY=${ENCRYPTION_KEY}
- CLICKHOUSE_URL=http://clickhouse:8123
- CLICKHOUSE_MIGRATION_URL=clickhouse://clickhouse:9000
- CLICKHOUSE_USER=default
- CLICKHOUSE_PASSWORD=${CLICKHOUSE_PASSWORD}
- REDIS_CONNECTION_STRING=redis://redis:6379/0
- LANGFUSE_S3_EVENT_UPLOAD_BUCKET=langfuse
- LANGFUSE_S3_EVENT_UPLOAD_REGION=auto
- LANGFUSE_S3_EVENT_UPLOAD_ACCESS_KEY_ID=langfuse
- LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY=${MINIO_PASSWORD}
- LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT=http://minio:9000
- LANGFUSE_S3_EVENT_UPLOAD_FORCE_PATH_STYLE=true
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
clickhouse:
condition: service_started
minio:
condition: service_started
langfuse-worker:
image: langfuse/langfuse-worker:3
environment:
- DATABASE_URL=postgresql://langfuse:${POSTGRES_PASSWORD}@postgres:5432/langfuse
- SALT=${SALT}
- ENCRYPTION_KEY=${ENCRYPTION_KEY}
- CLICKHOUSE_URL=http://clickhouse:8123
- CLICKHOUSE_MIGRATION_URL=clickhouse://clickhouse:9000
- CLICKHOUSE_USER=default
- CLICKHOUSE_PASSWORD=${CLICKHOUSE_PASSWORD}
- REDIS_CONNECTION_STRING=redis://redis:6379/0
- LANGFUSE_S3_EVENT_UPLOAD_BUCKET=langfuse
- LANGFUSE_S3_EVENT_UPLOAD_REGION=auto
- LANGFUSE_S3_EVENT_UPLOAD_ACCESS_KEY_ID=langfuse
- LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY=${MINIO_PASSWORD}
- LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT=http://minio:9000
- LANGFUSE_S3_EVENT_UPLOAD_FORCE_PATH_STYLE=true
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
clickhouse:
condition: service_started
minio:
condition: service_started
postgres:
image: postgres:17-alpine
environment:
- POSTGRES_USER=langfuse
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=langfuse
volumes:
- langfuse_postgres:/var/lib/postgresql/data
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U langfuse -d langfuse"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
clickhouse:
image: clickhouse/clickhouse-server:latest
user: "101:101"
environment:
- CLICKHOUSE_DB=default
- CLICKHOUSE_USER=default
- CLICKHOUSE_PASSWORD=${CLICKHOUSE_PASSWORD}
volumes:
- langfuse_clickhouse:/var/lib/clickhouse
- langfuse_clickhouse_logs:/var/log/clickhouse-server
restart: unless-stopped
minio:
image: minio/minio:latest
entrypoint: sh
command: -c 'mkdir -p /data/langfuse && minio server /data --console-address ":9001"'
environment:
- MINIO_ROOT_USER=langfuse
- MINIO_ROOT_PASSWORD=${MINIO_PASSWORD}
volumes:
- langfuse_minio:/data
restart: unless-stopped
redis:
image: redis:7-alpine
volumes:
- langfuse_redis:/data
restart: unless-stopped
volumes:
langfuse_postgres:
langfuse_clickhouse:
langfuse_clickhouse_logs:
langfuse_minio:
langfuse_redis:
Once you are done, save and close the file.
Step 4. Run the Platform
Now you can use the following command to run the application:
docker-compose up -d
This tells your server to download the required container images and start all the services in the background. It takes about two to three minutes for the databases to initialize and the main web container to become completely healthy.
Step 5. Configure Nginx Reverse Proxy and SSL
By default, the application runs on port 3000. To secure the application and access it via a domain name, you must configure Nginx and install a free Let’s Encrypt SSL certificate.
Install Nginx and Certbot:
sudo apt install nginx certbot python3-certbot-nginx -y
Create the server block with:
sudo nano /etc/nginx/sites-available/langfuse
Add the following configuration to the file:
server {
listen 80;
server_name ai.yourdomain.com;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
}
}
Enable the site and apply the SSL certificate:
sudo ln -s /etc/nginx/sites-available/langfuse /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
sudo certbot --nginx -d ai.yourdomain.com
What to Monitor After Launching Langfuse
After you successfully self host Langfuse on VPS, you must monitor your system resources closely. Because the platform records every LLM prompt and response, your databases will grow quickly over time. ClickHouse requires significant RAM to process fast analytical queries.
You need to watch your server’s memory, CPU, and disk space. You can see how much RAM and CPU each Docker container is using in real-time by running this command:
docker stats
If you notice that clickhouse or langfuse-worker is constantly hitting 100% of your available memory, you will need to upgrade your server to prevent crashes.
Next, you must monitor your storage. Because PostgreSQL and MinIO store your application data and files, they will consume disk space. Run this command to check your remaining storage:
df -h
Finally, if the web interface ever feels slow or stops loading, you can check the background logs to see if there are any database connection errors. Run this command inside your langfuse directory:
docker-compose logs --tail=50 -f
By regularly checking these basic commands on your AI hosting infrastructure, you ensure that your traces and evals process in real time without losing any valuable data.
Conclusion
It is a smart technical decision to self host Langfuse on VPS for total control over your AI data. You learned how to prepare your server, configure Docker with ClickHouse and Postgres, and secure your setup.
Once you self host Langfuse on VPS, you can track every LLM call and token cost easily.
We hope you enjoy this guide. When you are ready to deploy, you can run your AI observability stack on PerLod AI Hosting or Linux VPS for the best speed and reliability.
Scaling an AI observability platform can become challenging as your team grows. If you are a growing company looking for the right infrastructure to support both your LLMs and your self-hosted Langfuse setup securely, read this breakdown of the best AI hosting for startups.
FAQs
Is it free to self host Langfuse on VPS?
Yes, the open-source platform is MIT licensed and free to deploy. You only pay for your server costs.
Do I need ClickHouse for Langfuse?
Yes, modern versions use PostgreSQL for state and ClickHouse as the primary database for fast trace analytics.
Can I run Langfuse on my local computer?
Yes, you can run the same Docker Compose setup locally to test it before moving to a remote server.