SSD Nodes Learn 🎉 VPS $4.99/माह से
गाइड Matt Connorलेखक: Matt Connor · अपडेट किया गया: 2026-08-07

Langfuse को अपने VPS पर self-host कैसे करें

अपने VPS पर Langfuse को self-host करने का तरीका जानें। इसमें ClickHouse retention, TLS सेटअप, सही image tags और डेटा बैकअप की पूरी जानकारी दी गई है ताकि आपका सर्वर सुरक्षित रहे।

AI agent को trace करने की आवश्यकता क्यों है

आप अपने agent द्वारा किसी run के दौरान किए गए कार्यों को देखने के लिए Langfuse को self-host करते हैं। Langfuse एक open source LLM (large language model) observability tool है। यह प्रत्येक prompt, प्रत्येक model response, प्रत्येक tool call और प्रत्येक token को record करता है, और फिर उन्हें एक trace के अंतर्गत समूहबद्ध करता है जिसे आप खोलकर पढ़ सकते हैं। इसे अपने VPS पर चलाने का अर्थ है कि वे prompts कभी भी आपके नियंत्रण वाले सर्वर से बाहर नहीं जाते।

इसकी आवश्यकता स्पष्ट है। आप किसी cost या quality संबंधी समस्या को ठीक नहीं कर सकते जिसे आप देख नहीं सकते। एक provider invoice आपको बताता है कि मंगलवार का खर्च सोमवार की तुलना में चार गुना था। एक trace आपको बताता है कि किस agent run ने ऐसा किया, कौन सा prompt 40,000 tokens तक बढ़ गया, और कौन सा retry loop नौ बार चलने के बाद विफल हुआ। Invoice आपको संख्या देता है। Trace आपको वह code देता है जिसने उसे उत्पन्न किया।

इस guide में तीन शब्दों का प्रयोग किया गया है। Trace आपके agent का एक end-to-end run है। Observation उस run के भीतर का एक चरण है: सामान्य code के लिए एक span, और model को की गई call के लिए एक generation। Score एक trace से जुड़ी संख्या है, जो human review या automated evaluator से प्राप्त होती है। Langfuse, OpenTelemetry (OTel) का समर्थन करता है, जो distributed tracing के लिए vendor-neutral standard है, इसलिए आपके पास मौजूद instrumentation इसे point कर सकता है।

Langfuse वास्तव में क्या self-host करता है

Langfuse v4 केवल एक container नहीं है। इसमें दो application containers और चार storage services शामिल हैं, और एक ही VPS पर ये सभी छह आपके सिस्टम पर चलते हैं।

  • langfuse-web वेब इंटरफेस और ingestion API को सर्व करता है।
  • langfuse-worker बैकग्राउंड में queue को खाली करता है। यह ingestion batches को पार्स करता है, लागत की गणना करता है, और nightly retention job चलाता है।
  • Postgres transactional डेटा जैसे कि users, organisations, projects, API keys और prompts को सुरक्षित रखता है।
  • ClickHouse स्वयं trace डेटा को रखता है, जिसका अर्थ है observations और scores। यह analytical queries के लिए बना एक column store है, यही कारण है कि दस करोड़ rows वाला डैशबोर्ड भी तेजी से परिणाम देता है।
  • Redis वह queue और cache है जो वेब और worker के बीच स्थित होता है।
  • MinIO आपको बॉक्स पर S3 compatible object storage प्रदान करता है। यह हर raw incoming event और आपके द्वारा अटैच की गई किसी भी मीडिया फाइल को रखता है।

Langfuse काम करने वाले तीन घटकों के लिए न्यूनतम संसाधनों (minimum resources) को प्रकाशित करता है।

ChartLangfuse published minimum resources per component
The data behind this chart
[
  {
    "label": "ClickHouse",
    "cpu_cores": 2,
    "memory_gib": 8
  },
  {
    "label": "Langfuse web",
    "cpu_cores": 2,
    "memory_gib": 4
  },
  {
    "label": "Langfuse worker",
    "cpu_cores": 2,
    "memory_gib": 4
  }
]

अकेले ClickHouse को 8 GiB मेमोरी की आवश्यकता होती है। वेब कंटेनर और वर्कर को प्रत्येक के लिए 4 GiB की आवश्यकता होती है। ये उन 3 घटकों के लिए प्रकाशित न्यूनतम सीमाएं हैं जिनका Langfuse आकार निर्धारित करता है, और Postgres, Redis तथा MinIO को इसके अतिरिक्त मेमोरी की आवश्यकता होती है। प्रोजेक्ट की अपनी Docker Compose गाइड 4 cores, 16 GiB मेमोरी और लगभग 100 GiB स्टोरेज वाली मशीन की सिफारिश करती है, जो इस गणना से मेल खाती है।

इसे 2 GiB वाले प्लान पर चलाने का प्रयास न करें। ClickHouse शुरू होता है, कुछ समय के लिए writes स्वीकार करता है, लेकिन फिर बैकग्राउंड मर्ज के दौरान बंद हो जाता है, क्योंकि मर्ज प्रक्रिया टेबल के बड़े हिस्सों को मेमोरी में लोड करती है। आप देखेंगे कि docker compose ps, clickhouse कंटेनर को restarting के रूप में रिपोर्ट कर रहा है, dmesg में Out of memory: Killed process 1234 (clickhouse-serv) जैसी लाइन दिखाई देगी, और हर Langfuse डैशबोर्ड 500 एरर देगा। हल्के दबाव में ClickHouse क्वेरी को अस्वीकार कर देता है और DB::Exception: Memory limit (total) exceeded लॉग करता है। एक डेवलपर के लिए जो प्रतिदिन कुछ हजार ट्रेसेस भेजता है, 8 GiB काम कर सकता है। 16 GiB वह संख्या है जिसके लिए आपको योजना बनानी चाहिए।

Docker Compose के साथ Langfuse को Deploy करें

Repository को clone करें। Stack, wiring और default environment सभी इसके docker-compose.yml में मौजूद हैं।

git clone https://github.com/langfuse/langfuse.git
cd langfuse

आपको जिन भी values को बदलना है, उन्हें उस file में # CHANGEME के रूप में चिह्नित किया गया है। सबसे पहले तीन application secrets generate करें।

openssl rand -base64 32   # NEXTAUTH_SECRET
openssl rand -base64 32   # SALT
openssl rand -hex 32      # ENCRYPTION_KEY

ENCRYPTION_KEY को 256 bits का होना चाहिए जिसे 64 hex characters के रूप में लिखा जाता है, जो कि ठीक वही है जो openssl rand -hex 32 print करता है। यह sensitive values को at rest encrypt करता है, जिसमें आपके द्वारा instance में store की गई कोई भी LLM provider keys शामिल हैं। डेटा मौजूद होने के बाद इसे बदलने पर उन rows को decrypt नहीं किया जा सकेगा, इसलिए इसे पहली boot से ही स्थायी मानें। SALT का उपयोग आपकी Langfuse API keys को hash करने के लिए किया जाता है, इसलिए इसे बदलने से वे सभी keys अमान्य हो जाएंगी जिनका उपयोग आपके agents पहले से कर रहे हैं।

इसके बाद POSTGRES_PASSWORD, CLICKHOUSE_PASSWORD, REDIS_AUTH और MINIO_ROOT_PASSWORD को set करें। MinIO password चार स्थानों पर दिखाई देता है: एक बार MINIO_ROOT_PASSWORD के रूप में, फिर दोबारा LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY, LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY और LANGFUSE_S3_BATCH_EXPORT_SECRET_ACCESS_KEY के रूप में। यदि एक भी छूट गया, तो MinIO उस client को SignatureDoesNotMatch के साथ reject कर देगा, जो worker log में दिखाई देगा जबकि web interface सामान्य दिखेगा। इन values को tracked compose file के बजाय env file में रखना वह तरीका है जिसे Docker Compose env files and secrets में कवर किया गया है।

शुरू करने से पहले image tags को pin करें

दी गई file langfuse/langfuse:4 और langfuse/langfuse-worker:4 का उपयोग करती है। ये tags बदलते रहते हैं। Langfuse शुरू होने पर अपने Postgres और ClickHouse migrations को स्वचालित रूप से चलाता है, इसलिए महीनों बाद किया गया एक सामान्य docker compose pull उस database पर अनियोजित schema migration बन सकता है जिसका आपने उस सुबह backup नहीं लिया था। दोनों को एक docker-compose.override.yml में किसी एक release पर pin करें, जिसे Compose दी गई file के ऊपर merge करता है ताकि बाद में किया गया git pull आपके edits के साथ conflict न करे।

services:
  langfuse-web:
    image: docker.io/langfuse/langfuse:4.3.1
  langfuse-worker:
    image: docker.io/langfuse/langfuse-worker:4.3.1

August 2026 तक Version 4.3.1 वर्तमान 4.3 release थी (4.4.0 तब से release हो चुकी है)। project के GitHub releases page को देखें, जिस दिन आप deploy करें उस दिन जो भी current हो उसे pin करें, और फिर उस number को सोच-समझकर बदलें। दी गई file में storage images पहले से ही majors, postgres:17, clickhouse-server:25.12 और redis:7 पर pinned हैं, और उन्हें भी समान treatment मिलना चाहिए।

इसे start करें।

docker compose up -d
docker compose ps
docker compose logs -f langfuse-worker

पहली boot migrations चलाती है, इसलिए किसी भी response के लिए एक या दो मिनट का समय दें। docker compose ps को running state में छह services की सूची दिखानी चाहिए। यदि worker loop में restart होता है, तो उसका log कारण बताता है: CLICKHOUSE_MIGRATION_URL port 9000 पर ClickHouse native protocol का उपयोग करता है, न कि HTTP port 8123 का, और इसे 8123 पर point करने से वह fail हो जाता है जबकि web container ठीक दिखता है।

स्वयं box से health की जाँच करें।

curl -s "http://localhost:3000/api/public/health?failIfDatabaseUnavailable=true"
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3000/api/public/ready

एक साधारण /api/public/health call केवल यह साबित करती है कि API process जीवित है, क्योंकि यह जानबूझकर database को छोड़ देती है ताकि Postgres के रुकने पर भी service चलती रहे। failIfDatabaseUnavailable=true form वह है जिसे monitor पर point करना सार्थक है, और database के unreachable होने पर यह 503 return करता है। migrations पूरी होने और container के traffic स्वीकार करने के बाद /api/public/ready 200 return करता है। दोनों सामान्य HTTP checks हैं, इसलिए an Uptime Kuma status page उन्हें monitor कर सकता है और आपके agents के पता लगाने से पहले आपको बता सकता है कि stack down है।

TLS को सामने रखें और अतिरिक्त ports बंद करें

प्रदान की गई compose file वेब container के लिए 3000:3000 और MinIO के लिए 9090:9000 को publish करती है। दोनों ही सभी interfaces पर bind होते हैं। एक public IP पर इसका मतलब है कि port 3000 को scan करने वाला कोई भी व्यक्ति आपके sign up page तक पहुँच सकता है, और 9090 को scan करने वाला कोई भी व्यक्ति उस bucket से बात कर रहा है जिसमें आपके raw prompts मौजूद हैं।

केवल एक firewall rule इन्हें बंद नहीं करता है। Docker nat table में अपने स्वयं के DNAT rules लिखता है, और ufw के filter rules के पैकेट देखने से पहले ही उनका मूल्यांकन हो जाता है, इसलिए ufw deny 3000 published port को खुला छोड़ देता है। यह इतनी अधिक संख्या में लोगों को प्रभावित करता है कि इसके लिए एक अलग guide मौजूद है: Docker published ports ufw को क्यों bypass करते हैं। अपनी override file में loopback पर bind करें।

services:
  langfuse-web:
    ports:
      - "127.0.0.1:3000:3000"
    environment:
      NEXTAUTH_URL: https://langfuse.example.com
  minio:
    ports:
      - "127.0.0.1:9090:9000"
      - "127.0.0.1:9091:9001"

NEXTAUTH_URL को scheme सहित सटीक public address होना चाहिए, क्योंकि login flow उस मान से अपना callback URL बनाता है। यदि आप इसे HTTPS proxy के पीछे http://localhost:3000 छोड़ते हैं, तो sign in round trip browser को ऐसी जगह भेज देगा जहाँ वह पहुँच नहीं सकता।

अब एक reverse proxy को 127.0.0.1:3000 पर point करें और certificate को उसी पर रहने दें। उसी Compose project में Traefik का उपयोग करना एक सामान्य विकल्प है, और routing labels वही हैं जो एक Traefik reverse proxy के पीछे कई apps चलाना में बताए गए हैं। यदि server पर केवल Langfuse चल रहा है, तो Caddy दो lines में वही काम कर देता है। curl -sI https://langfuse.example.com/api/public/ready के साथ verify करें, फिर किसी दूसरे machine से पुष्टि करें कि curl http://YOUR_IP:3000 अब time out हो रहा है।

MinIO के संबंध में एक सावधानी बरतें। Langfuse attached media को आपके browser तक उस S3 endpoint की ओर इशारा करने वाले presigned URLs के माध्यम से पहुँचाता है, इसलिए यदि आप images या audio वाले multi-modal traces का उपयोग करते हैं, तो केवल loopback पर सीमित MinIO का मतलब है कि वे attachments load नहीं होंगी। इसे proxy करने से पहले blob storage configuration page को पढ़ें, क्योंकि presigned URL में लिखा गया endpoint आपके द्वारा publish किए गए endpoint से मेल खाना चाहिए। Plain text traces इससे प्रभावित नहीं होते हैं।

पहली बार visit करने पर अपना account बनाएँ, और फिर instance को अपने तक सीमित रखें। LANGFUSE_ALLOWED_ORGANIZATION_CREATORS को अपने email address पर set करें, ताकि page तक पहुँचने वाला कोई अनजान व्यक्ति आपके server पर organisation न बना सके।

अपना पहला trace भेजें

Web interface में एक project बनाएँ और project settings से अपनी public और secret keys कॉपी करें। Python SDK तीन environment variables को पढ़ता है।

export LANGFUSE_PUBLIC_KEY="pk-lf-..."
export LANGFUSE_SECRET_KEY="sk-lf-..."
export LANGFUSE_BASE_URL="https://langfuse.example.com"

LANGFUSE_BASE_URL, SDK v4 में variable का नाम है, जिसे March 2026 में release किया गया था। पुराना code और पुरानी guides LANGFUSE_HOST का उपयोग करती हैं। यदि आपके traces आपके सर्वर के बजाय Langfuse Cloud पर जा रहे हैं, तो इसका कारण unset base URL है, क्योंकि default setting hosted instance की ओर इशारा करती है।

pip install langfuse opentelemetry-instrumentation-anthropic anthropic
import os
from anthropic import Anthropic
from langfuse import get_client, observe
from opentelemetry.instrumentation.anthropic import AnthropicInstrumentor

AnthropicInstrumentor().instrument()
langfuse = get_client()
client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

@observe(as_type="tool")
def lookup_order(order_id: str) -> str:
    return f"order {order_id}: shipped"

@observe()
def handle_request(question: str) -> str:
    context = lookup_order("A-1042")
    message = client.messages.create(
        model="claude-haiku-4-5",
        max_tokens=512,
        messages=[{"role": "user", "content": f"{context}\n\n{question}"}],
    )
    return message.content[0].text

if __name__ == "__main__":
    assert langfuse.auth_check()
    print(handle_request("Where is my order?"))
    langfuse.flush()

@observe decorator function के चारों ओर एक observation खोलता है, उसके arguments और return value को capture करता है, और उसे किसी भी सक्रिय observation के अंतर्गत nest कर देता है। AnthropicInstrumentor, Anthropic client के लिए OpenTelemetry instrumentation है, और यह प्रत्येक messages.create call को एक generation में बदल देता है जिसमें model का नाम, token usage और latency शामिल होती है, और इसके लिए call site पर कोई बदलाव नहीं करना पड़ता।

दो calls आपके लिए जाँच का काम करती हैं। यदि keys गलत हों या base URL सही न हो तो langfuse.auth_check(), False return करता है, जो यह सोचने से बेहतर है कि dashboard खाली क्यों है। langfuse.flush() queued spans के भेजे जाने तक process को block करता है। कम समय तक चलने वाली processes के लिए इसकी आवश्यकता होती है, क्योंकि SDK background में batching करता है और जो script तुरंत exit हो जाती है, वह अपने unsent batch को भी साथ ले जाती है।

ClickHouse का आकार लगातार क्यों बढ़ता रहता है?

Traces सबसे तेजी से बढ़ने वाला डेटा है जिसे ज्यादातर लोग खुद होस्ट (self-host) करते हैं। हर एजेंट रन हर स्टेप के लिए एक रो (row) लिखता है, और इनपुट व आउटपुट को पूरा स्टोर किया जाता है। इसलिए, लंबे प्रॉम्प्ट वाला एक चैटी एजेंट उस एप्लिकेशन की तुलना में कहीं अधिक बाइट्स प्रतिदिन उत्पन्न करता है जिसकी वह निगरानी कर रहा है। यदि इसे ऐसे ही छोड़ दिया जाए, तो ClickHouse डिस्क को भर देता है, और डिस्क फुल होने पर डेटा का आना (ingestion) धीमा होने के बजाय पूरी तरह रुक जाता है।

यहाँ दो अलग-अलग चीजें बढ़ती हैं, और उन्हें दो अलग-अलग समाधानों की आवश्यकता है।

पहली चीज आपका अपना ट्रेस डेटा है, और इसका समाधान रिटेंशन सेटिंग है। वेब इंटरफेस में प्रोजेक्ट सेटिंग्स खोलें और दिनों में डेटा रिटेंशन अवधि सेट करें। Langfuse कम से कम 3 दिनों की अवधि स्वीकार करता है। इसके बाद एक नाइटली जॉब उस विंडो से पुराने ट्रेसेस, ऑब्जर्वेशन, स्कोर और मीडिया एसेट्स का चयन करती है और उन्हें ClickHouse तथा ब्लब स्टोरेज से हटा देती है। इस जॉब को बकेट पर DeleteObject अनुमति की आवश्यकता होती है, जो डिफ़ॉल्ट compose फाइल में MinIO रूट क्रेडेंशियल्स के पास पहले से होती है। डेटा हटाना स्थायी होता है, इसलिए यदि आपको लंबे समय के इतिहास की आवश्यकता है तो पहले ब्लब स्टोरेज एक्सपोर्ट कॉन्फ़िगर करें। Langfuse की अपनी टेबल्स पर खुद से TTL क्लॉज न लिखें: रिटेंशन जॉब ही ClickHouse और बकेट को तालमेल में रखती है, और मैन्युअल TTL केवल एक तरफ का डेटा हटाता है।

आप जो वास्तव में उपयोग करते हैं उसके आधार पर विंडो चुनें। लागत और गुणवत्ता की समीक्षा कुछ दिन पुराने डेटा पर होती है, महीनों पुराने डेटा पर नहीं। एक छोटी टीम के लिए 30 दिन एक उचित शुरुआत है, और यदि आप केवल तब ट्रेस खोलते हैं जब कुछ खराब होता है, तो 14 दिन पर्याप्त हैं।

दूसरी चीज ClickHouse की अपनी सिस्टम लॉग टेबल्स हैं, और यह लोगों को हैरान करती है, क्योंकि रिटेंशन कॉन्फ़िगर होने के बाद भी डिस्क का आकार बढ़ता रहता है। ClickHouse अपने डायग्नोस्टिक्स के लिए trace_log, text_log, opentelemetry_span_log, metric_log और asynchronous_metric_log लिखता है, ये बिना किसी TTL के आते हैं, और Langfuse इन्हें कभी नहीं पढ़ता है। सबसे पहले यह पता लगाएं कि डिस्क स्पेस वास्तव में कहाँ गया है।

SELECT table, formatReadableSize(size) AS size, rows FROM (
    SELECT table, database, sum(bytes) AS size, sum(rows) AS rows
    FROM system.parts
    WHERE active
    GROUP BY table, database
    ORDER BY size DESC
)

इसे docker compose exec clickhouse clickhouse-client --password "$CLICKHOUSE_PASSWORD" के साथ चलाएं। यदि सिस्टम टेबल्स सूची में सबसे ऊपर हैं, तो उन्हें कॉन्फ़िगरेशन ओवरले के साथ बंद कर दें, क्योंकि ClickHouse स्टार्ट होते समय /etc/clickhouse-server/config.d/ में मौजूद हर फाइल को अपने मुख्य कॉन्फ़िगरेशन पर मर्ज कर देता है।

<clickhouse>
    <trace_log remove="1"/>
    <text_log remove="1"/>
    <opentelemetry_span_log remove="1"/>
    <asynchronous_metric_log remove="1"/>
    <metric_log remove="1"/>
</clickhouse>

इसे माउंट करें और ClickHouse को रीस्टार्ट करें।

services:
  clickhouse:
    volumes:
      - ./clickhouse-config.d/system-logs.xml:/etc/clickhouse-server/config.d/system-logs.xml:ro

यह नई राइट्स को रोक देता है। डिस्क पर पहले से मौजूद रो वहीं रहती हैं, इसलिए DROP TABLE IF EXISTS system.trace_log के साथ स्पेस को स्पष्ट रूप से रिक्लेम करें और यही प्रक्रिया उन सभी टेबल्स के लिए दोहराएं जिन्हें आपने हटाया है। यदि आप डायग्नोस्टिक्स रखना चाहते हैं, तो विकल्प यह है कि remove="1" के बजाय प्रत्येक टेबल पर एक आक्रामक TTL सेट करें, जिसे Langfuse स्केलिंग डॉक्स में विस्तार से बताया गया है।

एक और टेबल के बारे में जानना उपयोगी है। blob_storage_file_log आपके बकेट में अपलोड की गई इवेंट फाइलों को ट्रैक करती है। यदि आप बकेट पर लाइफसाइकिल पॉलिसी भी सेट करते हैं, तो टेबल को एक मेल खाता हुआ TTL दें ताकि दोनों में अंतर न आए।

ALTER TABLE blob_storage_file_log MODIFY TTL created_at + INTERVAL 30 DAY DELETE;

डेटा डिस्क पर एक सामान्य df -h अलर्ट भी लगाएं। ट्रेसेस सुचारू रूप से नहीं बढ़ते हैं। वे उस दिन बढ़ते हैं जिस दिन आप एक नया एजेंट शिप करते हैं, और इसका पहला संकेत इनजेशन का फेल होना नहीं होना चाहिए।

Postgres और ClickHouse का बैकअप लेना

Langfuse बैकअप के तीन भाग होते हैं। Postgres आपके users, organisations, projects और API keys को सुरक्षित रखता है। ClickHouse traces को रखता है। MinIO raw events को स्टोर करता है। यदि आप केवल Postgres को restore करते हैं, तो आप login तो कर पाएंगे लेकिन कोई history नहीं दिखेगी। यदि आप केवल ClickHouse को restore करते हैं, तो history तो होगी लेकिन कोई भी उसे देखने के लिए login नहीं कर पाएगा।

Postgres एक साधारण pg_dump है, जिसकी सलाह Langfuse बैकअप docs में दी गई है।

docker compose exec -T postgres pg_dump -U postgres postgres \
  | gzip > langfuse-pg-$(date +%F).sql.gz

ClickHouse के लिए अधिक सावधानी की आवश्यकता होती है, क्योंकि merges चलने के दौरान कॉपी किया गया live data directory एक consistent बैकअप नहीं होता है। एक ही सर्वर पर इसका सरल तरीका यह है कि container को रोकें और volume को archive कर लें।

docker compose stop clickhouse
docker volume ls | grep clickhouse
docker run --rm -v langfuse_langfuse_clickhouse_data:/data -v "$PWD":/backup alpine \
  tar czf /backup/langfuse-ch-$(date +%F).tar.gz -C /data .
docker compose start clickhouse

docker volume ls द्वारा प्रिंट किए गए volume नाम का उपयोग करें, न कि YAML में लिखे गए नाम का। फाइल में langfuse_clickhouse_data घोषित होता है, और Compose इसमें project नाम का prefix जोड़ देता है, इसलिए langfuse नामक directory में clone करने पर langfuse_langfuse_clickhouse_data बनता है। यदि आप इसे गलत चुनते हैं, तो docker run बिना किसी चेतावनी के एक नया खाली volume बना देगा, और आपके archive में कुछ भी नहीं होगा।

Web container worker द्वारा process किए जाने से पहले हर incoming event को bucket में लिखता है, इसलिए ClickHouse को थोड़ी देर के लिए रोकने का मतलब है कि worker बाद में retry करेगा। इसे कम traffic वाले समय में करें और प्रक्रिया को संक्षिप्त रखें। अधिक व्यस्त instance के लिए, ClickHouse का अपना BACKUP DATABASE default TO S3(...) statement सर्वर को रोके बिना एक consistent बैकअप तैयार करता है। MinIO तीसरा हिस्सा है, और mc mirror या MinIO replication का उपयोग करके इसे off-box bucket पर सुरक्षित किया जा सकता है। आप जो भी बैकअप लें, उसे सर्वर से बाहर किसी सुरक्षित स्थान पर रखें, जिसके लिए VPS पर encrypted restic backups का उपयोग किया जाता है।

Redis के लिए किसी बैकअप की आवश्यकता नहीं है। यह queue और cache को रखता है, इसलिए इसे खोने का मतलब केवल उन events का नुकसान है जो उस समय process हो रहे थे, पुराना डेटा सुरक्षित रहता है।

Consistency की चेतावनी वास्तविक है और इसे स्पष्ट रूप से समझना आवश्यक है। Postgres और ClickHouse के dumps अलग-अलग समय पर लिए जाते हैं, इसलिए restore करने पर ऐसा हो सकता है कि किसी project row के traces न मिलें, या ऐसे traces मिलें जिनका project अब मौजूद ही न हो। Langfuse इसे संभाल लेता है, लेकिन दोनों dumps को कम traffic वाले समय में एक-दूसरे के करीब लें। Event bucket ही असली सुरक्षा कवच है, क्योंकि Langfuse processing से पहले हर incoming event को वहां सुरक्षित कर लेता है।

कम से कम एक बार scratch stack में restore करके देखें। इसी तरह आप outage के दौरान नहीं, बल्कि अभी गलत volume नाम जैसी समस्याओं का पता लगा सकते हैं।

सबसे पहले क्या देखें

पहले सप्ताह में चार चीजें महत्वपूर्ण होती हैं।

  • प्रति ट्रेस लागत (Cost per trace): Langfuse मॉडल के नाम और टोकन उपयोग के आधार पर लागत की गणना करता है। इसलिए, ट्रेसेस को लागत के अनुसार क्रमबद्ध करें और सबसे महंगे ट्रेस को शुरू से अंत तक पढ़ें। इसका कारण आमतौर पर एक बढ़ता हुआ प्रॉम्प्ट होता है: संदर्भ (context) में पेस्ट किया गया पूरा दस्तावेज़, या बातचीत का ऐसा इतिहास जिसे कोई ट्रिम नहीं करता। एक बार जब आप इसे देख लेते हैं, तो AI एजेंट की लागत को नियंत्रित करना अनुमान लगाने के बजाय एक इंजीनियरिंग कार्य बन जाता है।
  • इनपुट और आउटपुट के आधार पर टोकन उपयोग का विभाजन: इनपुट टोकन अधिक और सस्ते होते हैं, आउटपुट टोकन कम और महंगे होते हैं, और कैश किया गया इनपुट और भी सस्ता होता है। यही हिसाब Claude Code टोकन उपयोग की गणना कैसे की जाती है में समझाया गया है, और यह आपके द्वारा लिखे गए किसी भी एजेंट पर लागू होता है।
  • लेटेंसी पर्सेंटाइल (Latency percentiles): माध्य (median) समस्या को छिपा देता है। p95 और p99 वे स्थान हैं जहाँ टाइमआउट होते हैं, और एक एजेंट लूप के भीतर, p95 पर एक धीमा टूल कॉल पुनरावृत्तियों (iterations) की संख्या से गुणा हो जाता है।
  • विफल टूल कॉल (Failed tool calls): ऑब्जर्वेशन को ERROR स्तर के अनुसार फ़िल्टर करें। एक टूल जो 5% समय विफल होता है, वह कुल सफलता दर में अदृश्य रहता है, लेकिन ट्रेसेस में बहुत स्पष्ट दिखाई देता है, जहाँ आप मॉडल को पुनः प्रयास करते हुए और फिर उसे ठीक करने के लिए टोकन खर्च करते हुए देखते हैं।

रिटेंशन विंडो सेट करें और वह डैशबोर्ड चुनें जिसे आप हर सप्ताह उसी दिन चेक करेंगे जिस दिन आप डिप्लॉयमेंट करते हैं। एक ऑब्जर्वेबिलिटी टूल जिसे कोई नहीं खोलता, वह केवल एक ऐसा डेटाबेस है जो डिस्क को भरता है।

FAQ

self-hosted Langfuse के लिए कितनी memory की आवश्यकता होती है?

4 CPU cores और 16 GiB memory की योजना बनाएँ, जो कि एक single virtual machine के लिए Langfuse Docker Compose guide द्वारा अनुशंसित है, साथ ही लगभग 100 GiB storage की भी आवश्यकता होगी। प्रकाशित component minimums में ClickHouse के लिए 8 GiB और web, worker containers, Postgres, Redis तथा MinIO में से प्रत्येक के लिए 4 GiB memory की आवश्यकता होती है। 8 GiB memory पर एक developer instance चल सकता है। 2 GiB memory पर्याप्त नहीं है: background merges के दौरान kernel द्वारा ClickHouse को kill कर दिया जाता है और dmesg में Out of memory: Killed process दिखाई देता है।

data retention सेट करने के बाद भी मेरा ClickHouse disk क्यों भर जाता है?

Retention setting केवल Langfuse के अपने data को कवर करती है। ClickHouse अलग से अपनी diagnostic tables trace_log, text_log, opentelemetry_span_log, metric_log और asynchronous_metric_log लिखता है, और इनमें कोई TTL नहीं होता। यह देखने के लिए कि कौन सी table सबसे बड़ी है, table के अनुसार group करके system.parts query चलाएँ, फिर /etc/clickhouse-server/config.d/ के अंतर्गत किसी file में remove="1" entry के साथ unused tables को disable करें, ClickHouse को restart करें, और पहले से उपयोग की गई space को reclaim करने के लिए existing tables को drop करें।

Langfuse में न्यूनतम data retention अवधि क्या है?

तीन दिन। Retention को project settings में या projects API के माध्यम से प्रति project सेट किया जाता है, और एक nightly job उस अवधि से पुराने traces, observations, scores और media assets को ClickHouse और blob storage दोनों से हटा देती है। deletion को undo नहीं किया जा सकता है, इसलिए यदि आपको उस अवधि से अधिक का history चाहिए, तो पहले blob storage export configure करें।

क्या मुझे Postgres और ClickHouse दोनों का backup लेना होगा?

हाँ, क्योंकि वे अलग-अलग चीजें रखते हैं। Postgres में users, organisations, projects और API keys होती हैं, और ClickHouse में स्वयं trace data होता है। केवल Postgres को restore करने पर आपको एक ऐसा instance मिलेगा जिसमें login तो किया जा सकता है, लेकिन उसमें कोई data नहीं होगा। MinIO bucket का भी backup लें, क्योंकि इसमें वे raw events होते हैं जिन्हें Langfuse आने पर persist करता है, जो इस stack में source of truth के सबसे करीब है।

क्या मैं existing OpenTelemetry setup को self-hosted Langfuse की ओर point कर सकता हूँ?

हाँ। Langfuse v4 और इसके v4 SDKs OpenTelemetry पर आधारित हैं, और Anthropic तथा OpenAI OTel instrumentations सीधे इसी पर export करते हैं। Python में, pip install langfuse opentelemetry-instrumentation-anthropic चलाएँ, startup पर एक बार AnthropicInstrumentor().instrument() call करें, और LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY तथा LANGFUSE_BASE_URL को अपने host पर सेट करें। missing dashboard की तलाश करने से पहले langfuse.auth_check() के साथ पुष्टि करें।