Tự host Langfuse để trace AI agent trên VPS
Hướng dẫn tự host Langfuse trên VPS: mức tài nguyên tối thiểu thực tế, pin image tag, cấu hình TLS, retention ClickHouse và backup dùng được.
Vì sao phải trace AI agent
Bạn tự host Langfuse để xem agent thực sự đã làm gì trong một lần chạy. Langfuse là công cụ observability mã nguồn mở cho LLM (large language model). Công cụ này ghi lại mọi prompt, mọi phản hồi của model, mọi lần gọi tool và mọi token, rồi nhóm chúng vào một trace duy nhất để bạn mở và đọc. Chạy Langfuse trên VPS của bạn nghĩa là các prompt đó không rời khỏi server do bạn kiểm soát.
Lý do cần làm việc này rất rõ ràng. Bạn không thể xử lý vấn đề chi phí hoặc chất lượng nếu không nhìn thấy nguyên nhân. Hóa đơn của provider cho biết chi phí vào thứ Ba cao gấp 4 lần thứ Hai. Trace cho biết lần chạy agent nào gây ra việc đó, prompt nào tăng lên 40,000 token và vòng retry nào đã chạy 9 lần trước khi bỏ cuộc. Hóa đơn cho bạn con số. Trace cho bạn đoạn code tạo ra con số đó.
Hướng dẫn này sử dụng 3 thuật ngữ. Trace là một lần chạy end-to-end của agent. Observation là một bước trong lần chạy đó: span dành cho code thông thường, generation dành cho lần gọi model. Score là một con số gắn với trace, do người review hoặc evaluator tự động tạo ra. Langfuse sử dụng OpenTelemetry (OTel), tiêu chuẩn trung lập với vendor dành cho distributed tracing, nên instrumentation bạn đã có có thể trỏ đến Langfuse.
Langfuse self-hosting thực sự chạy những gì
Langfuse v4 không chỉ có một container. Nó gồm hai application container và bốn storage service. Trên một VPS đơn, cả sáu thành phần này đều chạy trên máy của bạn.
langfuse-webcung cấp web interface và ingestion API.langfuse-workerxử lý queue ở background. Nó phân tích các ingestion batch, tính chi phí và chạy retention job hằng đêm.- Postgres lưu dữ liệu giao dịch như user, organisation, project, API key và prompt.
- ClickHouse lưu chính trace data, gồm observation và score. Đây là column store được thiết kế cho analytical query, nên dashboard trên hơn một trăm triệu row vẫn trả kết quả nhanh.
- Redis là queue và cache nằm giữa web và worker.
- MinIO cung cấp S3-compatible object storage ngay trên máy. Nó lưu mọi raw event nhận vào cùng với mọi media bạn đính kèm.
Langfuse công bố resource tối thiểu cho ba component trực tiếp xử lý công việc.
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
}
]Riêng ClickHouse yêu cầu 8 GiB memory. Web container và worker mỗi container yêu cầu 4 GiB. Đây là mức tối thiểu được công bố cho 3 component mà Langfuse dùng để sizing. Postgres, Redis và MinIO vẫn cần thêm memory. Docker Compose guide của chính dự án khuyến nghị máy có 4 core, 16 GiB memory và khoảng 100 GiB storage. Con số này phù hợp với phép tính trên, không phải được cộng thêm một mức dự phòng lớn.
Không nên chạy cấu hình này trên plan 2 GiB. ClickHouse sẽ khởi động và nhận write trong một thời gian, sau đó chết trong lúc background merge vì merge phải nạp các part lớn của table vào memory. Bạn sẽ thấy docker compose ps báo clickhouse container ở trạng thái restarting, dmesg có một dòng tương tự Out of memory: Killed process 1234 (clickhouse-serv), và mọi Langfuse dashboard đều trả về 500. Khi áp lực thấp hơn, ClickHouse sẽ từ chối query và ghi log DB::Exception: Memory limit (total) exceeded. 8 GiB có thể đủ cho một developer gửi vài nghìn trace mỗi ngày. Nên lên kế hoạch với 16 GiB. Nếu cùng VPS đó còn chạy dịch vụ khác, hãy tính thêm resource riêng cho chúng, vì ngay cả stack tương đối nhẹ như một workspace AFFiNE tự host cũng cần vài GiB riêng, còn ClickHouse sẽ không nhường lại memory nào.
Triển khai Langfuse bằng Docker Compose
Clone repository. Stack, wiring và môi trường mặc định đều nằm trong docker-compose.yml.
git clone https://github.com/langfuse/langfuse.git
cd langfuseMọi giá trị bạn phải thay đều được đánh dấu # CHANGEME trong file đó. Trước tiên, tạo ba application secret.
openssl rand -base64 32 # NEXTAUTH_SECRET
openssl rand -base64 32 # SALT
openssl rand -hex 32 # ENCRYPTION_KEYENCRYPTION_KEY phải có độ dài 256 bit và được viết thành 64 ký tự hex. Đây chính xác là giá trị mà openssl rand -hex 32 in ra. Nó mã hóa các giá trị nhạy cảm khi lưu trữ, bao gồm cả các key của LLM provider mà bạn lưu trong instance. Nếu thay đổi sau khi đã có dữ liệu, các bản ghi đó sẽ không thể giải mã nữa. Vì vậy, hãy coi giá trị này là cố định ngay từ lần boot đầu tiên. SALT dùng để hash các Langfuse API key của bạn, nên thay đổi giá trị này sẽ vô hiệu hóa mọi key mà các agent đang sử dụng.
Tiếp theo, đặt POSTGRES_PASSWORD, CLICKHOUSE_PASSWORD, REDIS_AUTH và MINIO_ROOT_PASSWORD. Mật khẩu MinIO xuất hiện ở bốn vị trí: một lần dưới dạng MINIO_ROOT_PASSWORD, sau đó là LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY, LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY và LANGFUSE_S3_BATCH_EXPORT_SECRET_ACCESS_KEY. Nếu bỏ sót một vị trí, MinIO sẽ từ chối client đó với SignatureDoesNotMatch. Lỗi này xuất hiện trong worker log dù web interface vẫn có vẻ hoạt động bình thường. Lưu các giá trị này trong env file thay vì compose file được track là cách làm được đề cập trong Env file và secret trong Docker Compose.
Pin image tag trước khi bắt đầu
File đi kèm sử dụng langfuse/langfuse:4 và langfuse/langfuse-worker:4. Các tag này có thể thay đổi. Langfuse tự động chạy migration cho Postgres và ClickHouse khi khởi động. Vì vậy, một lần docker compose pull thông thường vài tháng sau có thể trở thành schema migration ngoài kế hoạch trên database mà sáng hôm đó bạn chưa backup. Pin cả hai image vào cùng một release trong docker-compose.override.yml. Compose sẽ merge file này lên trên file đi kèm, nên một lần git pull sau đó sẽ không ghi đè các chỉnh sửa của bạn.
services:
langfuse-web:
image: docker.io/langfuse/langfuse:4.3.1
langfuse-worker:
image: docker.io/langfuse/langfuse-worker:4.3.1Version 4.3.1 là bản 4.3 hiện tại vào tháng 2026-08 (4.4.0 đã được phát hành sau đó). Kiểm tra trang GitHub releases của project, pin phiên bản hiện tại vào ngày bạn triển khai, rồi chủ động cập nhật số phiên bản đó khi cần. Các storage image trong file đi kèm đã được pin theo major version: postgres:17, clickhouse-server:25.12 và redis:7. Các image này cũng nên được xử lý tương tự. Quy tắc này không chỉ áp dụng cho Langfuse: một trình theo dõi bài tập openGym tự host chỉ chạy một phần của stack này nhưng vẫn cần một named git tag, vì mọi ứng dụng tự migration database khi khởi động đều có thể biến một lần pull thông thường thành schema change.
Khởi động stack.
docker compose up -d
docker compose ps
docker compose logs -f langfuse-workerLần boot đầu tiên sẽ chạy migration, nên chờ một hoặc hai phút trước khi kiểm tra phản hồi. docker compose ps phải liệt kê sáu service ở trạng thái running. Nếu worker restart liên tục, log của worker sẽ cho biết nguyên nhân: CLICKHOUSE_MIGRATION_URL sử dụng ClickHouse native protocol trên port 9000, không phải HTTP port 8123. Trỏ nó đến 8123 sẽ gây lỗi ở đó, trong khi web container vẫn có vẻ hoạt động bình thường.
Kiểm tra health ngay trên server.
curl -s "http://localhost:3000/api/public/health?failIfDatabaseUnavailable=true"
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3000/api/public/readyMột lệnh gọi /api/public/health thông thường chỉ chứng minh API process đang chạy, vì endpoint này cố ý bỏ qua database để service vẫn tiếp tục phục vụ khi Postgres bị gián đoạn. Dạng failIfDatabaseUnavailable=true mới là endpoint nên cấu hình cho monitor. Nó trả về 503 khi không thể kết nối đến database. /api/public/ready trả về 200 sau khi migration hoàn tất và container đã sẵn sàng nhận traffic. Cả hai đều là HTTP check thông thường, nên một status page của Uptime Kuma có thể monitor chúng và báo stack bị down trước khi agent của bạn phát hiện.
Đặt TLS phía trước và đóng các cổng thừa
File compose đi kèm public 3000:3000 cho web container và 9090:9000 cho MinIO. Cả hai đều bind trên mọi interface. Trên một public IP, điều đó có nghĩa là bất kỳ ai scan cổng 3000 đều truy cập được trang đăng ký, còn bất kỳ ai scan cổng 9090 đều đang kết nối đến bucket chứa các prompt thô của bạn.
Chỉ thêm rule trên firewall không đóng được các cổng này. Docker tự ghi các rule DNAT vào bảng nat, và các rule đó được xử lý trước khi packet tới các filter rule của ufw, vì vậy ufw deny 3000 vẫn để cổng đã publish mở. Vấn đề này phổ biến đến mức có hẳn một guide riêng: vì sao cổng Docker publish vượt qua ufw. Thay vào đó, hãy bind vào loopback trong file override.
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 phải là địa chỉ public chính xác, bao gồm cả scheme, vì login flow tạo callback URL từ giá trị này. Nếu để là http://localhost:3000 phía sau một HTTPS proxy, vòng chuyển hướng đăng nhập sẽ đưa browser đến một địa chỉ mà nó không thể truy cập.
Bây giờ trỏ một reverse proxy vào 127.0.0.1:3000 và để reverse proxy quản lý certificate. Traefik trong cùng Compose project là lựa chọn thường dùng, còn các routing label là nội dung đã được đề cập trong chạy nhiều ứng dụng phía sau một reverse proxy Traefik. Nếu Langfuse là ứng dụng duy nhất trên máy, Caddy cũng làm được việc này chỉ với hai dòng. Xác minh bằng curl -sI https://langfuse.example.com/api/public/ready, sau đó dùng một máy thứ hai để xác nhận rằng curl http://YOUR_IP:3000 hiện đã timeout.
Có một điểm cần lưu ý về MinIO. Langfuse phân phối media đính kèm đến browser thông qua presigned URL trỏ đến S3 endpoint đó. Vì vậy, nếu bạn dùng trace đa phương thức có image hoặc audio, MinIO chỉ bind trên loopback sẽ khiến các file đính kèm không tải được. Hãy đọc trang cấu hình blob storage trước khi proxy MinIO, vì endpoint được ghi trong presigned URL phải khớp với endpoint bạn public. Trace chỉ có text không bị ảnh hưởng.
Tạo account trong lần truy cập đầu tiên, sau đó giữ instance này thuộc quyền kiểm soát của bạn. Đặt LANGFUSE_ALLOWED_ORGANIZATION_CREATORS thành địa chỉ email của bạn, để người lạ truy cập được trang cũng không thể tạo organisation trên server của bạn. Nếu bạn đã chạy Authentik làm identity provider của riêng bạn, Langfuse hỗ trợ kết nối OIDC tiêu chuẩn. Khi đó, account được tạo và xóa cùng với các ứng dụng khác, thay vì nằm trong một danh sách password mà chỉ máy này biết.
Gửi trace đầu tiên
Tạo một project trong giao diện web rồi sao chép public key và secret key từ phần cài đặt của project. Python SDK đọc 3 biến môi trường.
export LANGFUSE_PUBLIC_KEY="pk-lf-..."
export LANGFUSE_SECRET_KEY="sk-lf-..."
export LANGFUSE_BASE_URL="https://langfuse.example.com"LANGFUSE_BASE_URL là tên biến trong SDK v4, được phát hành vào tháng 3 năm 2026. Code và tài liệu hướng dẫn cũ dùng LANGFUSE_HOST. Nếu trace được gửi đến Langfuse Cloud thay vì server của bạn, nguyên nhân là base URL chưa được đặt, vì giá trị mặc định trỏ đến instance được host sẵn.
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()Decorator @observe tạo một observation bao quanh function, ghi nhận các argument và giá trị trả về của function, rồi lồng observation đó dưới observation hiện đang active. AnthropicInstrumentor là OpenTelemetry instrumentation cho Anthropic client. Nó biến mỗi lần gọi messages.create thành một generation chứa tên model, mức sử dụng token và latency, mà không cần thay đổi tại vị trí gọi.
Hai lệnh sẽ tự kiểm tra giúp bạn. langfuse.auth_check() trả về False nếu key không hợp lệ hoặc base URL sai. Cách này nhanh hơn việc phải đoán tại sao dashboard lại trống. langfuse.flush() chặn cho đến khi các span đang xếp hàng được gửi đi. Lệnh này cần thiết cho các process chạy trong thời gian ngắn, vì SDK batch dữ liệu trong background và một script thoát ngay sẽ kết thúc cùng batch chưa được gửi. Nếu cả team cùng gửi trace thay vì chỉ một script, hãy đặt 3 biến đó một lần trong gateway mà các agent của mọi người vốn đã đi qua, thay vì đặt trong shell của từng người. Đây là cách một harness OneCLI tự host giữ cho mọi lần chạy của đồng nghiệp đều được instrument, trong khi các key chỉ cần lưu ở một nơi.
Vì sao ClickHouse cứ tiếp tục tăng dung lượng?
Trace là loại dữ liệu tăng nhanh nhất trong hầu hết hệ thống tự host. Mỗi lần agent chạy sẽ ghi một row cho từng bước. Input và output cũng được lưu đầy đủ. Vì vậy, một agent hoạt động nhiều với prompt dài có thể tạo ra nhiều byte mỗi ngày hơn cả ứng dụng mà nó theo dõi. Nếu không xử lý, ClickHouse sẽ làm đầy disk. Khi disk đầy, hệ thống sẽ dừng ingestion thay vì chỉ chạy chậm hơn.
Ở đây có hai loại dữ liệu tăng độc lập với nhau. Mỗi loại cần một cách xử lý riêng.
Loại thứ nhất là dữ liệu trace của chính bạn. Cách xử lý là cấu hình retention. Mở phần cài đặt project trong web interface và đặt thời gian lưu dữ liệu theo số ngày. Langfuse chấp nhận tối thiểu 3 ngày. Mỗi đêm, một job sẽ chọn các trace, observation, score và media asset cũ hơn khoảng thời gian này rồi xóa chúng khỏi ClickHouse và blob storage. Job cần quyền DeleteObject trên bucket. Các credential MinIO root trong compose file mặc định đã có quyền này. Xóa là thao tác vĩnh viễn, nên hãy cấu hình blob storage export trước nếu cần lưu lịch sử dài hạn. Không tự viết các mệnh đề TTL trên bảng riêng của Langfuse. Retention job là cơ chế giữ ClickHouse và bucket đồng bộ với nhau. TTL thủ công chỉ xóa một phía.
Chọn khoảng thời gian dựa trên nhu cầu sử dụng thực tế. Việc kiểm tra cost và chất lượng thường dùng dữ liệu vài ngày gần đây, không phải dữ liệu nhiều tháng. 30 ngày là điểm bắt đầu hợp lý cho một team nhỏ. 14 ngày là đủ nếu bạn chỉ mở trace khi có lỗi.
Loại thứ hai là các bảng system log riêng của ClickHouse. Phần này thường gây bất ngờ vì disk vẫn tiếp tục tăng sau khi đã cấu hình retention. ClickHouse ghi trace_log, text_log, opentelemetry_span_log, metric_log và asynchronous_metric_log để phục vụ chẩn đoán của chính nó. Các bảng này không có TTL mặc định và Langfuse không đọc chúng. Trước tiên, hãy xác định chính xác disk đã được dùng vào đâu.
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
)Chạy lệnh này với docker compose exec clickhouse clickhouse-client --password "$CLICKHOUSE_PASSWORD". Nếu các system table nằm gần đầu danh sách, hãy tắt chúng bằng config overlay. ClickHouse sẽ merge mọi file trong /etc/clickhouse-server/config.d/ lên config chính khi khởi động.
<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 file đó rồi restart ClickHouse.
services:
clickhouse:
volumes:
- ./clickhouse-config.d/system-logs.xml:/etc/clickhouse-server/config.d/system-logs.xml:roCách này ngăn các bản ghi mới được ghi vào. Các row đã có trên disk vẫn còn, nên hãy chủ động giải phóng dung lượng bằng DROP TABLE IF EXISTS system.trace_log và làm tương tự với từng bảng đã xóa. Nếu muốn giữ lại dữ liệu chẩn đoán, bạn có thể dùng TTL ngắn trên từng bảng thay cho remove="1". Tài liệu scaling của Langfuse có mô tả cụ thể cách này.
Có thêm một bảng bạn nên biết. blob_storage_file_log theo dõi các event file đã upload lên bucket. Nếu bạn cũng đặt lifecycle policy trên bucket, hãy đặt TTL tương ứng cho bảng để hai cơ chế không bị lệch nhau.
ALTER TABLE blob_storage_file_log MODIFY TTL created_at + INTERVAL 30 DAY DELETE;Ngoài ra, hãy đặt một cảnh báo df -h đơn giản trên data disk. Trace không tăng đều. Dung lượng thường tăng mạnh vào ngày bạn deploy một agent mới. Dấu hiệu đầu tiên của việc đó không nên là ingestion bị lỗi.
Sao lưu Postgres và ClickHouse
Một bản sao lưu Langfuse có 3 phần. Postgres lưu người dùng, tổ chức, project và API key. ClickHouse lưu trace. MinIO lưu event thô. Chỉ khôi phục Postgres thì bạn có thể đăng nhập nhưng không có lịch sử. Chỉ khôi phục ClickHouse thì bạn có lịch sử nhưng không ai đăng nhập để xem được. Mô hình tách này không riêng của Langfuse. Một helpdesk Chatwoot tự host cũng có cấu trúc tương tự: nếu tạo dump Postgres mà không sao lưu thư mục uploads, các cuộc hội thoại được khôi phục sẽ mất toàn bộ file đính kèm.
Postgres là một pg_dump đơn giản. Đây cũng là cách tài liệu backup của Langfuse khuyến nghị.
docker compose exec -T postgres pg_dump -U postgres postgres \
| gzip > langfuse-pg-$(date +%F).sql.gzClickHouse cần cẩn thận hơn. Sao chép data directory khi các thao tác merge đang chạy sẽ không tạo ra bản sao lưu nhất quán. Cách đơn giản trên một máy là dừng container rồi archive volume.
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 clickhouseDùng tên volume mà docker volume ls in ra, không dùng tên được viết trong YAML. File khai báo langfuse_clickhouse_data, còn Compose thêm project name vào đầu tên đó. Vì vậy, bản clone trong thư mục tên langfuse sẽ tạo ra langfuse_langfuse_clickhouse_data. Nếu dùng sai tên, docker run sẽ âm thầm tạo một volume mới, rỗng, và archive của bạn sẽ không có dữ liệu.
Web container ghi từng event nhận được vào bucket trước khi worker xử lý. Vì vậy, việc dừng ClickHouse trong thời gian ngắn chủ yếu khiến worker retry sau đó. Thực hiện vào giờ ít tải và giữ thời gian dừng ngắn. Với instance bận hơn, câu lệnh BACKUP DATABASE default TO S3(...) riêng của ClickHouse có thể ghi một bản sao lưu nhất quán mà không cần dừng server. MinIO là phần thứ ba. Dùng mc mirror hoặc replication từ MinIO sang một bucket bên ngoài để sao lưu phần này. Dù tạo bản sao lưu theo cách nào, hãy đưa bản sao lưu ra khỏi server. Đây là mục đích của bản sao lưu restic được mã hóa trên VPS.
Redis không cần backup. Redis lưu queue và cache. Nếu mất Redis, bạn chỉ mất các event đang được xử lý và không mất dữ liệu cũ hơn.
Cần nêu rõ giới hạn về tính nhất quán. Postgres và ClickHouse được dump tại các thời điểm khác nhau. Vì vậy, bản khôi phục có thể chứa một project không có trace, hoặc chứa trace thuộc về một project đã bị xóa. Langfuse vẫn xử lý được tình huống này, nhưng hãy tạo cả 2 dump gần nhau và trong thời gian ít traffic. Event bucket mới là lớp bảo vệ quan trọng, vì Langfuse lưu từng event nhận được vào đó trước khi xử lý.
Hãy khôi phục vào một scratch stack ít nhất 1 lần. Đây là cách phát hiện lỗi tên volume ngay bây giờ, thay vì chờ đến khi xảy ra sự cố.
Điều cần xem trước tiên
Bốn mục này nên được thiết lập ngay trong tuần đầu tiên.
- Chi phí trên mỗi trace. Langfuse tính chi phí dựa trên tên model và lượng token đã sử dụng, vì vậy hãy sắp xếp các trace theo chi phí rồi đọc từ đầu đến cuối trace tốn kém nhất. Nguyên nhân thường là prompt đã phình to: toàn bộ tài liệu bị dán vào context hoặc lịch sử hội thoại không được cắt bớt. Khi đã nhìn thấy nguyên nhân, kiểm soát chi phí của AI agent trở thành một công việc kỹ thuật thay vì phỏng đoán.
- Lượng token tách theo input và output. Input token thường nhiều và rẻ, output token ít hơn nhưng đắt hơn, còn input được cache thì rẻ hơn nữa. Cách tính tương tự được trình bày trong cách tính lượng token của Claude Code, và áp dụng cho mọi agent do bạn tự viết.
- Các percentile của latency. Median che khuất vấn đề. p95 và p99 là nơi các timeout xảy ra, và trong một vòng lặp agent, một tool call chậm ở p95 sẽ bị nhân lên theo số lần lặp.
- Các tool call thất bại. Lọc các observation theo level
ERROR. Một tool thất bại 5% số lần sẽ khó thấy trong tỷ lệ thành công tổng thể, nhưng rất rõ trong trace, nơi bạn có thể theo dõi model retry rồi tiêu tốn token để xử lý vòng.
Hãy đặt retention window và chọn dashboard mà bạn sẽ kiểm tra hằng tuần vào cùng ngày bạn deploy. Một công cụ observability không ai mở sẽ trở thành database làm đầy disk.
FAQ
Self-hosted Langfuse cần bao nhiêu memory?
Hãy dự trù 4 CPU core và 16 GiB memory. Đây là mức mà hướng dẫn Langfuse Docker Compose khuyến nghị cho một máy ảo, cùng khoảng 100 GiB storage. Mức tối thiểu được công bố là 8 GiB cho ClickHouse và 4 GiB cho mỗi container web và worker. Postgres, Redis và MinIO vẫn cần thêm memory ngoài các mức này. Tám GiB đủ chạy instance cho một developer. Hai GiB thì không đủ: kernel sẽ kill ClickHouse trong lúc background merge, và dmesg hiển thị Out of memory: Killed process.
Vì sao disk của ClickHouse tiếp tục đầy sau khi tôi đặt data retention?
Thiết lập retention chỉ áp dụng cho dữ liệu riêng của Langfuse. ClickHouse vẫn ghi riêng các bảng chẩn đoán trace_log, text_log, opentelemetry_span_log, metric_log và asynchronous_metric_log. Các bảng này không có TTL. Query system.parts theo table để xem bảng nào lớn nhất, sau đó tắt các bảng không dùng bằng một entry remove="1" trong file thuộc /etc/clickhouse-server/config.d/, restart ClickHouse và drop các bảng hiện có để thu hồi phần space đã sử dụng.
Thời gian lưu trữ dữ liệu tối thiểu trong Langfuse là bao lâu?
Ba ngày. Retention được đặt theo từng project trong project settings hoặc thông qua projects API. Một nightly job sẽ xóa traces, observations, scores và media assets cũ hơn khoảng thời gian này khỏi cả ClickHouse và blob storage. Không thể hoàn tác việc xóa. Vì vậy, trước tiên hãy cấu hình blob storage export nếu bạn cần giữ history lâu hơn khoảng thời gian này.
Tôi có phải backup cả Postgres và ClickHouse không?
Có, vì chúng lưu các loại dữ liệu khác nhau. Postgres lưu users, organisations, projects và API keys. ClickHouse lưu chính trace data. Restore chỉ từ Postgres sẽ tạo ra một instance mà bạn có thể đăng nhập nhưng không có dữ liệu bên trong. Bạn cũng nên backup bucket MinIO, vì bucket này chứa raw events mà Langfuse lưu ngay khi nhận được. Đây là dữ liệu gần với source of truth nhất trong stack.
Tôi có thể trỏ một OpenTelemetry setup hiện có vào Langfuse self-hosted không?
Có. Langfuse v4 và các v4 SDK của nó được xây dựng trên OpenTelemetry. Các instrumentation OTel cho Anthropic và OpenAI có thể export trực tiếp vào Langfuse. Trong Python, chạy pip install langfuse opentelemetry-instrumentation-anthropic, gọi AnthropicInstrumentor().instrument() một lần khi startup, rồi đặt LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY và LANGFUSE_BASE_URL trỏ đến host của bạn. Xác nhận bằng langfuse.auth_check() trước khi tìm nguyên nhân dashboard bị thiếu.