The Problem

LLM developers lack an integrated, low‑overhead observability stack that can run locally without external services. Existing solutions often need ClickHouse, Redis, or S3, making local debugging and edge deployment difficult.

What This Does

Peri‑Fuse is a self‑contained LLM observability server that stores traces, spans, generations, and scores in an embedded Turso database. It exposes a Langfuse‑compatible REST API, an OpenTelemetry OTLP ingestion endpoint, and a Vite‑powered dashboard. The codebase is split into packages/cli, packages/gateway, packages/langfuse‑mcp, and packages/server. The CLI (packages/cli/src/index.ts) manages the lifecycle of the gateway (packages/gateway/src/app.ts) and the web dashboard (packages/server). The gateway routes LLM calls, applies rate‑limit and budget‑limit hooks, and forwards them to providers defined in packages/gateway/src/provider/*.

How It Is Wired

Execution starts in packages/cli/src/index.ts where the start command launches the gateway. The gateway’s entry point is packages/gateway/src/app.ts, which registers middleware (middleware/auth.ts, middleware/request‑limits.ts) and mounts routers (router/index.ts). The admin router (admin-router.ts) exposes endpoints for audit, budgets, and credentials. The proxy router (proxy-router.ts) forwards /chat, /messages, and /models to provider adapters (provider/openai.ts, provider/anthropic.ts). These adapters call the external LLM APIs and return responses that are logged by hooks/peri‑fuse‑logger.ts. All database interactions happen through packages/gateway/src/db.ts, which uses the Prisma schema (prisma/schema.prisma) and Drizzle migrations located under drizzle/. The minimal call chain for a chat request is: client → gateway/app.ts → router/proxy/chat.ts → provider/openai.ts → external API → provider/openai.ts → gateway/app.ts → db.ts. Only 2–3 hops touch the filesystem (database writes) or network (LLM calls). The gateway’s hooks provide the widest blast radius: changing rate‑limiter.ts affects every request, while budget‑reset.ts touches only budget tables.

How To Use It

Setup

git clone https://github.com/moses-y/peri-fuse
cd peri-fuse
pnpm install

Configuration Copy .env.example to .env and set LITE_SERVER_PORT if you need a custom port. For remote Turso storage, supply TURSO_URL and TURSO_TOKEN.

Running locally

pnpm dev

The API is available at http://localhost:23432, and the dashboard at http://localhost:5173. Alternatively, build the production assets and run as a background service:

pnpm build
pnpm svc:start
pnpm svc:status
pnpm svc:logs
pnpm svc:stop

Docker

docker compose up -d
curl http://localhost:23332/api/public/health

The image uses the same Bun runtime and keeps the ./data volume for persistence.

Real‑World Use

A data‑science team can proxy all OpenAI calls through Peri‑Fuse to enforce a daily spend budget. By configuring packages/gateway/src/spend/calculator.ts with a 10 USD limit and adding a project key, every request is checked against the budget. If exceeded, the provider adapter throws a 429 and the gateway returns a friendly error. The team can then query the audit logs (/admin/audit) to see which prompts consumed the budget.

Code Health & Issues

  • Low – Secret‑shaped paths in packages/gateway/test/admin-provider-secrets.test.ts (potential accidental commit of sensitive data).
  • Low – The repo contains 173 test files, but integration tests rely on a running Turso instance; CI may fail if the service is unavailable.
  • Moderate – No explicit linting configuration; the repo uses biome.json, but no GitHub Actions step invokes it.
  • Low – The README specifies Bun 1.4.2 as a requirement, but the Dockerfile uses Debian with Node 22; there is no automated check for Bun availability.

The Bottom Line

Peri‑Fuse delivers a compact, fully local LLM observability stack that fits small teams and edge deployments. Its clear package split and minimal external dependencies make it easy to modify. The main trade‑off is the reliance on Bun for runtime, which may limit adoption in environments that cannot install Bun. Overall, it is a practical choice for developers who need instant tracing, budgeting, and a Langfuse‑compatible API without running heavyweight infrastructure.