Langfuse स्वतःच्या VPS वर कसे self-host करावे
Langfuse स्वतःच्या VPS वर चालवताना किमान resources, pinned image tags, TLS आणि ClickHouse retention आधी ठरवा. Disk भरू नये म्हणून काम करणारे backups तपासा.
AI agent चे trace मुळात का घ्यावे
तुमच्या agent ने एखाद्या run मध्ये प्रत्यक्षात काय केले हे पाहण्यासाठी तुम्ही Langfuse self-host करता. Langfuse हे open source LLM (large language model) observability tool आहे. ते प्रत्येक prompt, प्रत्येक model response, प्रत्येक tool call आणि प्रत्येक token नोंदवते. त्यानंतर या सर्व नोंदी तुम्ही उघडून वाचू शकता अशा एका trace अंतर्गत गटबद्ध केल्या जातात. ते तुमच्या स्वतःच्या VPS वर चालवल्यामुळे हे prompts तुमच्या नियंत्रणातील server सोडत नाहीत.
याची गरज स्पष्ट आहे. दिसत नसलेली cost problem किंवा quality problem तुम्ही दुरुस्त करू शकत नाही. Provider invoice तुम्हाला सांगते की Tuesday चा खर्च Monday च्या खर्चाच्या चार पट होता. Trace तुम्हाला सांगतो की कोणत्या agent run मुळे हे झाले, कोणता prompt 40,000 tokens पर्यंत वाढला आणि कोणता retry loop थांबण्यापूर्वी नऊ वेळा चालला. Invoice फक्त संख्या देते. Trace ती संख्या निर्माण करणारा code दाखवतो.
या guide मध्ये तीन संज्ञा वापरल्या आहेत. trace म्हणजे तुमच्या agent चा सुरुवातीपासून शेवटपर्यंतचा एक run. observation म्हणजे त्या run मधील एक step: सामान्य code साठी span आणि model ला केलेल्या call साठी generation. score म्हणजे trace शी जोडलेली संख्या, जी human review किंवा automated evaluator कडून मिळते. Langfuse OpenTelemetry (OTel) वापरते. हे distributed tracing साठीचे vendor neutral standard आहे. त्यामुळे तुमच्याकडे आधीपासून असलेले instrumentation Langfuse कडे निर्देशित करता येते.
स्वतः Langfuse होस्टिंगमध्ये प्रत्यक्षात काय चालते
Langfuse v4 हा एकच container नाही. त्यात दोन application containers आणि चार storage services असतात. Single VPS वर हे सर्व सहा घटक तुमच्या मशीनवर चालतात.
langfuse-webweb interface आणि ingestion API उपलब्ध करून देतो.langfuse-workerपार्श्वभूमीत queue रिकामी करतो. तो ingestion batches parse करतो, cost मोजतो आणि nightly retention job चालवतो.- Postgres मध्ये users, organisations, projects, API keys आणि prompts यांसारखा transactional data साठवला जातो.
- ClickHouse मध्ये trace data स्वतः साठवला जातो; म्हणजे observations आणि scores. हा analytical queries साठी तयार केलेला column store आहे. त्यामुळे शंभर दशलक्षपेक्षा अधिक rows असलेल्या dashboard कडूनही उत्तर लवकर मिळते.
- Redis हा web आणि worker यांच्या दरम्यानचा queue आणि cache आहे.
- MinIO तुमच्या मशीनवर S3 compatible object storage उपलब्ध करून देतो. त्यात प्रत्येक raw incoming event आणि तुम्ही जोडलेली कोणतीही media साठवली जाते.
काम करणाऱ्या तीन components साठी Langfuse किमान resources प्रकाशित करते.
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 memory आवश्यक असते. Web container आणि worker यांना प्रत्येकी 4 GiB memory आवश्यक असते. Langfuse ज्या 3 components साठी sizing देते, त्यांच्यासाठी ही प्रकाशित किमान मर्यादा आहे. याशिवाय Postgres, Redis आणि MinIO यांनाही memory आवश्यक असते. प्रकल्पाच्या स्वतःच्या Docker Compose मार्गदर्शकात 4 cores, 16 GiB memory आणि सुमारे 100 GiB storage असलेली मशीन सुचवली आहे. हे प्रमाण padding न करता याच गणनेशी जुळते.
2 GiB plan वर हे चालवण्याचा प्रयत्न करू नका. ClickHouse सुरू होते आणि काही काळ writes स्वीकारते. त्यानंतर background merge दरम्यान ते बंद पडते, कारण merge मुळे table चे मोठे parts memory मध्ये load होतात. docker compose ps मध्ये clickhouse container ची स्थिती restarting असल्याचे दिसेल. dmesg मध्ये Out of memory: Killed process 1234 (clickhouse-serv) सारखी line दिसेल. त्यानंतर प्रत्येक Langfuse dashboard 500 error परत करेल. दबाव कमी असताना ClickHouse query नाकारते आणि DB::Exception: Memory limit (total) exceeded log करते. दिवसाला काही हजार traces पाठवणाऱ्या एका developer साठी 8 GiB वापरण्यायोग्य आहे. नियोजनासाठी 16 GiB गृहीत धरा.
Docker Compose वापरून Langfuse तैनात करा
रिपॉझिटरी clone करा. Stack, wiring आणि default environment हे सर्व त्याच्या docker-compose.yml मध्ये असतात.
git clone https://github.com/langfuse/langfuse.git
cd langfuseत्या फाइलमध्ये बदलणे आवश्यक असलेली प्रत्येक value # CHANGEME ने चिन्हांकित केलेली आहे. प्रथम application secrets तीनही तयार करा.
openssl rand -base64 32 # NEXTAUTH_SECRET
openssl rand -base64 32 # SALT
openssl rand -hex 32 # ENCRYPTION_KEYENCRYPTION_KEY हे 64 hex characters म्हणून लिहिलेले 256 bits असणे आवश्यक आहे. openssl rand -hex 32 ने नेमके हेच output मिळते. हे rest अवस्थेतील संवेदनशील values encrypt करते. यात instance मध्ये साठवलेल्या LLM provider keys चाही समावेश आहे. Data तयार झाल्यानंतर ते बदलल्यास त्या rows पुन्हा decrypt करता येणार नाहीत. त्यामुळे पहिल्या boot पासूनच याला कायमस्वरूपी value समजा. SALT तुमच्या Langfuse API keys चा hash तयार करण्यासाठी वापरले जाते. ते बदलल्यास agents आधीपासून वापरत असलेल्या सर्व keys invalid होतात.
यानंतर POSTGRES_PASSWORD, CLICKHOUSE_PASSWORD, REDIS_AUTH आणि MINIO_ROOT_PASSWORD सेट करा. 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 सह नाकारते. हा error worker log मध्ये दिसतो, परंतु web interface अजूनही व्यवस्थित दिसत असते. Tracked compose file मध्ये values ठेवण्याऐवजी 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 घेतलेला नसतो. दोन्ही tags एका docker-compose.override.yml मध्ये एकाच release वर pin करा. Compose ही file दिलेल्या 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.1August 2026 पर्यंत 4.3.1 हा current 4.3 release होता (त्यानंतर 4.4.0 release झाला आहे). प्रकल्पाचे GitHub releases page तपासा. Deploy करताना त्या दिवशीची current आवृत्ती pin करा आणि नंतर तो number जाणीवपूर्वक बदला. दिलेल्या file मधील storage images आधीच major versions वर pinned आहेत: postgres:17, clickhouse-server:25.12 आणि redis:7. त्यांनाही अशाच प्रकारे pin करणे योग्य आहे.
Stack सुरू करा.
docker compose up -d
docker compose ps
docker compose logs -f langfuse-workerपहिल्या boot वेळी migrations चालतात. त्यामुळे कोणतीही सेवा response देण्यापूर्वी एक किंवा दोन मिनिटे द्या. docker compose ps ने state running मध्ये असलेल्या सहा services दाखवल्या पाहिजेत. Worker सतत restart होत असल्यास त्याच्या log मध्ये कारण दिसेल: CLICKHOUSE_MIGRATION_URL port 9000 वरील ClickHouse native protocol वापरते, HTTP port 8123 नाही. त्याला 8123 कडे निर्देश केल्यास worker अपयशी ठरतो, मात्र web container अद्याप व्यवस्थित दिसतो.
स्वतः server वरून 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 requests देत राहते. failIfDatabaseUnavailable=true form monitor कडे निर्देशित करण्यासाठी योग्य आहे. Database उपलब्ध नसल्यास तो 503 परत करतो. Migrations पूर्ण झाल्यानंतर /api/public/ready 200 परत करतो आणि container traffic स्वीकारतो. दोन्ही ordinary HTTP checks आहेत. त्यामुळे Uptime Kuma status page त्यांचे monitoring करू शकते आणि agents ना समस्या जाणवण्यापूर्वी stack down असल्याचे सांगू शकते.
TLS समोर ठेवून अतिरिक्त पोर्ट बंद करा
दिलेल्या Compose फाइलमध्ये वेब कंटेनरसाठी 3000:3000 आणि MinIO साठी 9090:9000 प्रकाशित केले आहेत. दोन्ही सर्व interface वर bind होतात. सार्वजनिक IP वर याचा अर्थ असा की port 3000 स्कॅन करणारा कोणताही वापरकर्ता तुमच्या sign up पेजपर्यंत पोहोचू शकतो. तसेच, port 9090 स्कॅन करणारा कोणताही वापरकर्ता तुमच्या raw prompts असलेल्या bucket शी संवाद साधू शकतो.
केवळ firewall rule वापरून हे पोर्ट बंद होत नाहीत. Docker nat table मध्ये स्वतःचे DNAT rules लिहितो. ufw चे filter rules packet पाहण्यापूर्वीच ही rules लागू होतात. त्यामुळे ufw deny 3000 केल्याने प्रकाशित port उघडाच राहतो. ही समस्या इतक्या वेळा आढळते की तिच्यासाठी स्वतंत्र guide आहे: Docker चे प्रकाशित 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 ला पोहोचता न येणाऱ्या ठिकाणी पाठवते.
आता 127.0.0.1:3000 कडे reverse proxy निर्देशित करा आणि certificate त्याच्याकडे ठेवू द्या. त्याच Compose project मधील Traefik हा नेहमीचा पर्याय आहे. routing labels एका Traefik reverse proxy मागे अनेक अॅप्स चालवणे येथे वर्णन केलेल्या labels आहेत. Langfuse हे या मशीनवरील एकमेव अॅप असल्यास Caddy हेच काम दोन lines मध्ये करतो. curl -sI https://langfuse.example.com/api/public/ready वापरून पडताळा. त्यानंतर दुसऱ्या मशीनवरून curl http://YOUR_IP:3000 आता timeout होते याची खात्री करा.
MinIO बाबत एक महत्त्वाची अट आहे. Langfuse presigned URLs द्वारे तुमच्या browser ला संलग्न media उपलब्ध करून देतो. या URLs त्या S3 endpoint कडे निर्देश करतात. त्यामुळे images किंवा audio असलेले multi-modal traces वापरत असल्यास, केवळ loopback वर उपलब्ध असलेले MinIO हे attachments लोड करू शकणार नाही. त्याला proxy करण्यापूर्वी blob storage configuration पेज वाचा. Presigned URL मध्ये लिहिलेला endpoint तुम्ही प्रकाशित केलेल्या endpoint शी जुळला पाहिजे. Plain text traces वर याचा परिणाम होत नाही.
पहिल्यांदा भेट दिल्यावर तुमचे account तयार करा आणि नंतर ही instance तुमचीच ठेवा. LANGFUSE_ALLOWED_ORGANIZATION_CREATORS तुमच्या स्वतःच्या email address वर सेट करा. त्यामुळे पेजपर्यंत पोहोचणारा अनोळखी वापरकर्ता तुमच्या server वर organisation तयार करू शकणार नाही. तुम्ही आधीपासून तुमचा स्वतःचा identity provider म्हणून Authentik चालवत असाल, तर Langfuse standard OIDC connection स्वीकारतो. त्यामुळे accounts तुमच्या इतर अॅप्ससोबत तयार आणि हटवले जातात. ते फक्त या मशीनला माहीत असलेल्या password list मध्ये स्वतंत्रपणे ठेवावे लागत नाहीत.
तुमचा पहिला 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 name आहे. SDK v4 March 2026 मध्ये release झाले. जुन्या code आणि जुन्या guides मध्ये LANGFUSE_HOST वापरले जाते. तुमचे traces तुमच्या server ऐवजी Langfuse Cloud वर पोहोचत असतील, तर त्याचे कारण base URL unset असणे आहे. कारण default URL hosted instance कडे निर्देश करते.
pip install langfuse opentelemetry-instrumentation-anthropic anthropicimport 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 करतो आणि आधीपासून active असलेल्या observation अंतर्गत ते nest करतो. AnthropicInstrumentor हे Anthropic client साठीचे OpenTelemetry instrumentation आहे. ते प्रत्येक messages.create call चे model name, token usage आणि latency असलेल्या generation मध्ये रूपांतर करते. यासाठी call site मध्ये कोणताही बदल करावा लागत नाही.
दोन calls तुमच्यासाठी तपासणी करतात. चुकीच्या keys किंवा चुकीच्या base URL साठी langfuse.auth_check() False return करते. Dashboard रिकामे का आहे याचा अंदाज लावण्यापेक्षा ही पद्धत जलद आहे. langfuse.flush() queued spans पाठवले जाईपर्यंत थांबते. अल्पकाळ चालणाऱ्या processes साठी हे आवश्यक आहे, कारण SDK background मध्ये batching करते आणि लगेच exit होणारी script तिच्यासोबत न पाठवलेला batch घेऊन जाते.
ClickHouse सतत का वाढत राहते?
Traces हा बहुतेक लोक self-host केलेला सर्वांत वेगाने वाढणारा डेटा आहे. प्रत्येक agent run मध्ये प्रत्येक step साठी एक row लिहिली जाते आणि inputs व outputs पूर्ण स्वरूपात साठवले जातात. त्यामुळे लांब prompts असलेला chatty agent ज्या application वर लक्ष ठेवतो, त्या application पेक्षा दररोज कितीतरी जास्त bytes निर्माण करू शकतो. हे तसेच सोडल्यास ClickHouse डिस्क भरतो. डिस्क पूर्ण झाल्यावर ingestion मंद होत नाही, तर थांबते.
येथे दोन स्वतंत्र गोष्टी वाढतात. त्यांच्यासाठी दोन स्वतंत्र उपाय आवश्यक आहेत.
पहिली गोष्ट म्हणजे तुमचा स्वतःचा trace data. त्यासाठी retention setting बदलावी लागते. Web interface मधील project settings उघडा आणि data retention period दिवसांमध्ये सेट करा. Langfuse किमान 3 दिवस स्वीकारतो. त्यानंतर nightly job त्या कालावधीपेक्षा जुने traces, observations, scores आणि media assets निवडते आणि ते ClickHouse तसेच blob storage मधून हटवते. या job ला bucket वर DeleteObject permission आवश्यक आहे. Default compose file मधील MinIO root credentials कडे ही permission आधीपासून असते. Deletion कायमस्वरूपी असते. त्यामुळे दीर्घकालीन history आवश्यक असल्यास आधी blob storage export configure करा. Langfuse च्या स्वतःच्या tables वर TTL clauses हाताने लिहू नका. Retention job मुळे ClickHouse आणि bucket मध्ये सुसंगती राहते. Manual TTL फक्त एका बाजूचा data हटवतो.
तुम्ही प्रत्यक्षात कशासाठी data वापरता, त्यानुसार window निवडा. Cost आणि quality review महिन्यांपूर्वीच्या data वर नव्हे, तर काही दिवस जुन्या data वर होते. Small team साठी 30 days ही योग्य सुरुवात आहे. एखादी गोष्ट बिघडल्यावरच trace उघडत असाल, तर 14 days पुरेसे आहेत.
दुसरी गोष्ट म्हणजे ClickHouse च्या स्वतःच्या system log tables. Retention configure केल्यानंतरही डिस्क वाढत राहते, याचे हे कारण अनेकांना अनपेक्षित वाटते. ClickHouse स्वतःच्या diagnostics साठी trace_log, text_log, opentelemetry_span_log, metric_log आणि asynchronous_metric_log लिहितो. या tables सोबत 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" सह चालवा. System tables वरच्या स्थानांवर दिसत असल्यास config overlay वापरून त्या बंद करा. ClickHouse सुरू होताना /etc/clickhouse-server/config.d/ मधील प्रत्येक file मुख्य config वर लागू करतो.
<clickhouse>
<trace_log remove="1"/>
<text_log remove="1"/>
<opentelemetry_span_log remove="1"/>
<asynchronous_metric_log remove="1"/>
<metric_log remove="1"/>
</clickhouse>ते mount करा आणि ClickHouse restart करा.
services:
clickhouse:
volumes:
- ./clickhouse-config.d/system-logs.xml:/etc/clickhouse-server/config.d/system-logs.xml:roयामुळे नवीन writes थांबतात. डिस्कवर आधीपासून असलेल्या rows तिथेच राहतात. त्यामुळे DROP TABLE IF EXISTS system.trace_log वापरून जागा स्पष्टपणे reclaim करा आणि हटवलेल्या प्रत्येक table साठी हीच प्रक्रिया करा. Diagnostics जतन करायचे असल्यास remove="1" ऐवजी प्रत्येक table वर aggressive TTL लावणे हा पर्याय आहे. Langfuse scaling docs मध्ये त्याची सविस्तर माहिती दिली आहे.
आणखी एक table माहिती असणे उपयुक्त आहे. blob_storage_file_log तुमच्या bucket वर upload केलेल्या event files चा मागोवा ठेवते. Bucket वर lifecycle policy देखील सेट केली असल्यास table साठी matching TTL द्या, जेणेकरून दोन्हीमध्ये विसंगती निर्माण होणार नाही.
ALTER TABLE blob_storage_file_log MODIFY TTL created_at + INTERVAL 30 DAY DELETE;Data disk वर plain df -h alert देखील configure करा. Traces सातत्याने वाढत नाहीत. नवीन agent ship केल्याच्या दिवशी त्यांची वाढ होऊ शकते. त्या वाढीची पहिली सूचना ingestion fail होणे नसावे.
Postgres आणि ClickHouse चा बॅकअप घ्या
Langfuse बॅकअपचे तीन भाग असतात. Postgres मध्ये तुमचे users, organisations, projects आणि API keys साठवलेले असतात. ClickHouse मध्ये traces साठवलेले असतात. MinIO मध्ये raw events साठवलेले असतात. फक्त Postgres restore केल्यास history नसलेला login कार्यरत मिळतो. फक्त ClickHouse restore केल्यास login करू न शकणाऱ्या कोणालाही न दिसणारी history मिळते.
Postgres हा साधा pg_dump आहे. Langfuse च्या बॅकअप documentation मध्ये हीच पद्धत सुचवली आहे.
docker compose exec -T postgres pg_dump -U postgres postgres \
| gzip > langfuse-pg-$(date +%F).sql.gzClickHouse साठी अधिक काळजी घ्यावी लागते, कारण merges सुरू असताना live data directory कॉपी केली, तर तो consistent backup राहत नाही. एकाच box वर सोपी पद्धत म्हणजे 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 clickhousedocker volume ls दाखवणारे volume name वापरा. YAML मध्ये लिहिलेले volume name वापरू नका. File मध्ये langfuse_clickhouse_data घोषित केलेले आहे आणि Compose त्यापुढे project name जोडते. त्यामुळे langfuse नावाच्या directory मधील clone साठी langfuse_langfuse_clickhouse_data तयार होते. हे चुकीचे असल्यास docker run कोणतीही तक्रार न करता नवीन रिकामा volume तयार करते आणि तुमच्या archive मध्ये काहीही येत नाही.
Worker त्यावर प्रक्रिया करण्यापूर्वी web container प्रत्येक incoming event bucket मध्ये लिहितो. त्यामुळे ClickHouse थोड्या वेळासाठी थांबवल्यास worker नंतर बहुतेक वेळा पुन्हा प्रयत्न करतो. हे कमी वापराच्या वेळेत करा आणि थांबवण्याचा कालावधी कमी ठेवा. अधिक व्यस्त instance साठी ClickHouse चे स्वतःचे BACKUP DATABASE default TO S3(...) statement server न थांबवता consistent backup लिहिते. MinIO हा तिसरा भाग आहे. mc mirror किंवा off-box bucket वर MinIO replication वापरल्यास त्याचा बॅकअप होतो. तुम्ही कोणताही बॅकअप तयार केला तरी तो server च्या बाहेर ठेवा. यासाठी VPS वरील encrypted restic backups वापरता येतात.
Redis साठी बॅकअप आवश्यक नाही. त्यात queue आणि cache असतात. त्यामुळे Redis गमावल्यास सध्या प्रक्रियेत असलेले events गमावतात; त्यापूर्वीचे events गमावत नाहीत.
Consistency बाबतची सूचना महत्त्वाची आहे आणि ती स्पष्टपणे सांगणे आवश्यक आहे. Postgres आणि ClickHouse चे dumps वेगवेगळ्या वेळी घेतले जातात. त्यामुळे restore केल्यानंतर एखादा project row traces शिवाय राहू शकतो किंवा आता अस्तित्वात नसलेल्या project शी संबंधित traces राहू शकतात. Langfuse ही स्थिती सहन करते. तरीही दोन्ही dumps शक्य तितक्या जवळच्या वेळी आणि कमी traffic असताना घ्या. Event bucket हा खरा safety net आहे, कारण Langfuse प्रत्येक incoming event वर प्रक्रिया करण्यापूर्वी तो तेथे persist करते.
किमान एकदा scratch stack मध्ये restore करून पाहा. चुकीचे volume name outage च्या वेळी नव्हे, तर आधीच लक्षात येण्याचा हा मार्ग आहे.
प्रथम काय तपासावे
पहिल्या आठवड्यात चार गोष्टींना प्राधान्य द्या.
- प्रति trace खर्च. Langfuse model name आणि token usage वरून खर्च मोजते. त्यामुळे traces खर्चानुसार क्रमवारीत लावा आणि सर्वाधिक खर्चिक trace सुरुवातीपासून शेवटपर्यंत वाचा. याचे कारण सहसा वाढलेला prompt असतो: संपूर्ण document context मध्ये paste केलेला असतो किंवा कोणीही trim न केलेला conversation history असतो. हे दिसू लागल्यानंतर, AI agent चा खर्च नियंत्रित करणे हा अंदाजाचा विषय न राहता engineering task बनतो.
- Input आणि output नुसार token usage चे विभाजन. Input tokens ची संख्या जास्त आणि किंमत कमी असते. Output tokens ची संख्या कमी आणि किंमत जास्त असते. Cached input ची किंमत त्याहूनही कमी असते. याच accounting चे स्पष्टीकरण Claude Code token usage कसे मोजले जाते येथे दिले आहे. तुम्ही स्वतः लिहिलेल्या कोणत्याही agent ला हे लागू होते.
- Latency percentiles. Median मुळे समस्या लपते. Timeout बहुतेकदा p95 आणि p99 मध्ये दिसतात. Agent loop मध्ये p95 वरील धीमा tool call iterations च्या संख्येने अनेकदा वाढतो.
- अपयशी tool calls. Observations ला level
ERRORनुसार filter करा. एखादा tool 5% वेळा अपयशी ठरत असेल, तर aggregate success rate मध्ये तो दिसणार नाही. मात्र traces मध्ये तो स्पष्ट दिसेल; तिथे model पुन्हा प्रयत्न करताना आणि त्याभोवती काम करण्यासाठी tokens खर्च करताना दिसतो.
Retention window निश्चित करा. Deploy करतानाच प्रत्येक आठवड्यात कोणत्या दिवशी dashboard तपासायचा ते ठरवा. कोणीही उघडत नसलेले observability tool disk भरत जाणारा database ठरतो.
FAQ
self-hosted Langfuse साठी किती memory आवश्यक आहे?
4 CPU cores आणि 16 GiB memory नियोजित करा. एका virtual machine साठी Langfuse Docker Compose guide मध्ये याची शिफारस केली आहे. याशिवाय सुमारे 100 GiB storage आवश्यक आहे. प्रकाशित component minimums नुसार ClickHouse साठी 8 GiB आणि web व worker containers साठी प्रत्येकी 4 GiB memory आवश्यक आहे. याशिवाय Postgres, Redis आणि MinIO यांनाही memory लागते. 8 GiB memory एका developer च्या instance साठी पुरेशी आहे. 2 GiB पुरेशी नाही. Background merges दरम्यान kernel ClickHouse बंद करते आणि 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 मध्ये data लिहिते. या tables सोबत TTL दिलेले नसते. कोणती table सर्वात मोठी आहे हे पाहण्यासाठी system.parts नुसार table ने group करा. त्यानंतर /etc/clickhouse-server/config.d/ अंतर्गत असलेल्या file मध्ये remove="1" entry देऊन न वापरलेल्या tables disable करा. ClickHouse restart करा. आधी वापरलेली जागा परत मिळवण्यासाठी विद्यमान tables drop करा.
Langfuse मध्ये minimum data retention period किती आहे?
तीन दिवस. Retention प्रत्येक project साठी project settings मध्ये किंवा projects API द्वारे सेट करता येते. Nightly job या कालावधीपेक्षा जुने traces, observations, scores आणि media assets ClickHouse व blob storage या दोन्ही ठिकाणांहून delete करते. Deletion पूर्ववत करता येत नाही. त्यामुळे या कालावधीपलीकडील history आवश्यक असल्यास आधी blob storage export configure करा.
Postgres आणि ClickHouse या दोन्हींचा backup घ्यावा लागतो का?
होय, कारण दोन्ही ठिकाणी वेगवेगळा data असतो. Postgres मध्ये users, organisations, projects आणि API keys असतात. ClickHouse मध्ये trace data असतो. केवळ Postgres restore केल्यास login करता येईल अशी instance मिळेल, परंतु त्यात कोणताही trace data नसेल. MinIO bucket चा देखील backup घ्या. त्यात Langfuse arrival वेळी persist करत असलेले raw events असतात. या stack मध्ये source of truth च्या सर्वात जवळचे हेच data आहे.
माझ्या विद्यमान OpenTelemetry setup कडून self-hosted Langfuse कडे data पाठवता येतो का?
होय. 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() वापरून पडताळणी करा.