Short answer: Langfuse gives you traces of every LLM call, with inputs, outputs, latency and cost, and you can run it yourself with Docker Compose. Plan for 4 cores, 16 GiB of RAM and a big disk, change every CHANGEME secret in docker-compose.yml, put HTTPS in front of port 3000, and remember that Langfuse itself calls this setup a trial, not a production deployment.
Disclosure: the Hostinger and AICredits links are affiliate links. The commands come from Langfuse's self-hosting docs, read on 23 Oct 2026. I did not run the stack on a VPS for this post, so the Python snippet is unrun and the resource figures are the vendor's, not my measurements.
You add observability when you can't answer "why did that request cost so much?" or "what did the model actually see?" from your app logs. A tracing tool records each call as a trace you can open and search. Langfuse is open source and can be self-hosted, which matters if prompts contain customer data you don't want to send to another SaaS.
What server does Langfuse need?
From the Docker Compose page: a VM running Ubuntu with SSH access, at least 4 cores and 16 GiB of memory, and a large disk (it suggests 100 GiB) because observability data grows quickly.
Against Hostinger's plans on 23 Oct 2026, KVM 4 (4 vCPU, 16 GB RAM, 200 GB NVMe, $12.99/mo advertised, $28.99/mo renewal) lines up. KVM 2 has half the cores and half the RAM, so you'd be running below the vendor's own suggestion. Check the renewal price before you commit, since that is what you pay after the first term.
How do you install it?
git clone https://github.com/langfuse/langfuse.git
cd langfuse
Now edit docker-compose.yml. The docs say the secrets live there, not in a .env file, and lines with sensitive values are marked # CHANGEME. Replace all of them with long random values. A quick way to make one:
openssl rand -hex 32
Then install Docker (Docker's official Ubuntu guide) and start the stack:
docker compose up
Wait about 2 to 3 minutes until the langfuse-web-1 container logs "Ready". Use docker compose up -d once you're happy so it keeps running after you close SSH.
Open http://<server-ip>:3000. There is no default login: click Sign up, create the first user, then an organization and a project. Create the project's API keys in the project settings, which gives you a public key (pk-lf-...) and a secret key (sk-lf-...).
How do you put HTTPS in front of it?
The services Langfuse lists on host ports are the web UI on 3000, MinIO blob storage on 9090 (console on 9091, bound to 127.0.0.1), the worker on 127.0.0.1:3030, and the databases on 127.0.0.1. The docs say that on a VM only langfuse-web and MinIO need to be reachable from outside.
My approach, which is my inference and not something their page prescribes: put Caddy in front of port 3000 with a domain, and keep 3000 itself blocked at the firewall.
langfuse.example.com {
reverse_proxy localhost:3000
}
If you change a host port, Langfuse says you must update NEXTAUTH_URL to match, and LANGFUSE_S3_MEDIA_UPLOAD_ENDPOINT on langfuse-web if you move MinIO. The docs also warn that multimodal tracing may not work out of the box because MinIO is not reachable from outside the Docker network for direct uploads. If you only trace text, you can ignore that at first. More on firewalling in the hardening checklist.
What goes wrong on a single VPS?
Langfuse's own warnings are the checklist:
- No backups. The Compose setup lacks backup functionality. Schedule your own, using something like the Restic routine, and test a restore.
- Logs fill the disk. The default
json-filelogging driver does not rotate. Setmax-sizeandmax-fileon the logging options, then restart Docker and recreate containers. Don't rotate the JSON log files with external tools. - No high availability. If the VM dies, tracing stops. Your app should keep working without it, so wrap tracing so a Langfuse outage never breaks a user request.
- Scaling. You scale vertically (a bigger VM), not horizontally, without adding a load balancer.
Upgrades are two steps: stop the containers, then run docker compose up --pull always.
How do you trace a call?
Install the SDK, set the three environment variables from the quickstart, and swap the OpenAI import. Here is the shape, unrun, pointed at an OpenAI-compatible endpoint:
pip install langfuse
export LANGFUSE_PUBLIC_KEY="pk-lf-..."
export LANGFUSE_SECRET_KEY="sk-lf-..."
export LANGFUSE_BASE_URL="https://langfuse.example.com"
import os
from langfuse.openai import openai # drop-in replacement for the OpenAI client
client = openai.OpenAI(
base_url="https://api.aicredits.in/v1",
api_key=os.environ["AICREDITS_API_KEY"],
)
resp = client.chat.completions.create(
model="openai/gpt-4o-mini",
messages=[{"role": "user", "content": "Reply with the word ok."}],
)
print(resp.choices[0].message.content)
The Langfuse quickstart documents LANGFUSE_BASE_URL and the from langfuse.openai import openai drop-in. It gives no example URL for self-hosted, so I used the domain from the Caddy step. The model ID format follows the AICredits setup guide. I haven't confirmed that the wrapper records cost for a third-party gateway's model names, so open the trace and check what it shows before you rely on the cost column.
For short-lived scripts and workers, the SDK docs recommend calling flush() before exit so buffered data is sent. For long-running services, call shutdown() on a shutdown signal.
If you don't have an international card for the model side, AICredits takes UPI in rupees from ₹50. Pair that with tracing and you can see which prompts burn your budget, as in the cost-per-feature log script.
Should you self-host at all?
Self-host if prompts contain data you want to keep on your own server, you're comfortable running Docker, and you can put up with trial-grade operations. Otherwise use the vendor's hosted offering, or start with a lighter option such as logging requests to a table. If you do go ahead, KVM 4 is the plan that matches the docs.



