Show HN: Spanlight – open-source LLM observability platform Spanlight, an open-source LLM observability platform built on a single Postgres database, launched publicly with a live demo running on real Claude calls under a small monthly budget. Spanlight records every LLM call — prompts, completions, latency, time to first token, tokens, cost and errors — grouped into traces and sessions, and accepts data via Python and TypeScript SDKs, any OpenTelemetry exporter over OTLP/HTTP, or by changing one base_url to its built-in gateway for OpenAI and Anthropic. The platform adds cost auditing against Anthropic or OpenAI admin-key bills, 15 deterministic failure detectors, budgets that can block spend, versioned prompts and evals with 95% confidence intervals, and Postgres row-level security isolating each project's data. Open-source observability for LLM applications, on one Postgres. Live demo https://spanlight.dev · Docs https://spanlight.dev/docs/ · Features features · Getting started getting-started · How it works how-it-works · Discussions https://github.com/dheerajkarwasra/spanlight/discussions Spanlight records every LLM call your application makes: prompts and completions, latency, time to first token, tokens, cost and errors, grouped into traces and user sessions. Send traces with the Python or TypeScript SDK, any OpenTelemetry exporter over OTLP/HTTP, or by changing one base url to the built-in gateway. Then go past tracing: audit what each call cost, check it against the provider's bill, find out why calls fail, and review yesterday's traffic every morning. Tip Want to look before you install? The live demo https://spanlight.dev runs on real Claude calls under a small monthly budget. - Trace explorer and sessions. Search traces by name or by what the model was sent and said, read a span waterfall with agent, tool and model steps, compare two traces step by step, and replay multi-turn conversations as chat with cost and latency per turn. Inputs and outputs are kept up to 1 MB each, so long RAG contexts stay readable. - Cost you can audit. Prices come from a versioned table that covers cache writes, long-prompt tiers, batch, flex and priority rates, and web search fees. Every call has a line-by-line cost breakdown. A cost that cannot be known shows as unknown with the reason, never as $0. - Checked against the bill. Connect an Anthropic or OpenAI admin key, or upload a CSV, and Spanlight compares traced spend with what the provider billed, every day. - Attribution and budgets. Tag traces with up to 32 metadata pairs customer, feature, team and see spend, calls and errors per value. Budgets can alert on, or block, spend per project, gateway key, user, model, metadata pair or trace name. - The Doctor and provider health. Fifteen deterministic detectors flag known failure patterns retry storms, ignored Retry-After , truncated outputs, tool loops, cost and latency spikes and more , each with its evidence and a suggested fix. Provider health tells a provider outage or rate limit apart from your own bug, with the provider's status page incidents alongside. - A gateway for OpenAI and Anthropic. Gemini and Bedrock work through their OpenAI-compatible endpoints, with cost unknown until you add a price for their models. The official SDKs work against it unchanged, streaming and tool calls included. It adds sealed provider credentials, routes with retries and fallbacks, per-key rate limits, an exact-match cache, and an Integration Lab that injects real provider failures on non-production keys. - Prompts, evals and a daily review. Versioned prompts with labels, a playground, exact replay of any recorded call, datasets, experiments with 95% confidence intervals on pass rates, and a nightly queue of the traces worth reading. LLM judges show their agreement with your reviewers κ, F1, confusion matrix . - OpenTelemetry native. POST /v1/otlp/traces OTLP over HTTP, as JSON or protobuf; gRPC through an OpenTelemetry Collector https://spanlight.dev/docs/otlp/ sending-from-a-grpc-exporter reads the GenAI conventions gen ai. , also written by LiteLLM , OpenInference, OpenLLMetry Traceloop and the Vercel AI SDK, and counts usage once across nested spans. Recorded fixtures cover LangChain, LangGraph, LlamaIndex, Pydantic AI and the OpenAI Agents SDK. A Python SDK is on PyPI; a TypeScript SDK for Node.js is in sdks/typescript/ https://github.com/dheerajkarwasra/spanlight/blob/main/sdks/typescript its npm release job is ready; install it from a tarball until the first release . - Built for teams, private by design. Organizations, projects, roles, scoped API keys and an audit log. Postgres row-level security isolates every project's data, and secrets are redacted from payloads before storage. - Self-hosted on one database. Postgres is the only datastore, the job queue included. The core is MIT licensed. Note Spanlight is pre-1.0. The current server release is 0.8.1 changelog https://github.com/dheerajkarwasra/spanlight/blob/main/CHANGELOG.md , and the Python SDK on PyPI is 0.3.0. - Docker https://docs.docker.com/get-docker/ with Compose v2 - Python 3.10 or newer for the SDK - An OpenAI or Anthropic API key in your own application git clone https://github.com/dheerajkarwasra/spanlight.git cd spanlight cp deploy/.env.example deploy/.env fill in POSTGRES PASSWORD, APP DB PASSWORD and SECRET KEY docker compose -f deploy/compose.yaml --env-file deploy/.env up -d This pulls the released images named in deploy/.env SPANLIGHT IMAGE and SPANLIGHT WEB IMAGE . To build from the checkout instead, comment out those two lines and add --build . Open http://localhost:8080 http://localhost:8080 , create an account, and follow the setup wizard to create a project and an API key. Tip Generate each secret with python3 -c "import secrets; print secrets.token urlsafe 32 " . To host it instead, see deploy to Railway https://github.com/dheerajkarwasra/spanlight/blob/main/docs/deploy/railway.md . Install the SDK with the extra for your provider anthropic or openai : pip install "spanlight anthropic " python import spanlight from anthropic import Anthropic spanlight.init api key="spl live …", host="http://localhost:8080" client = spanlight.wrap anthropic Anthropic @spanlight.observe def answer question: str - str: reply = client.messages.create model="claude-haiku-5-5", max tokens=300, messages= {"role": "user", "content": question} , return reply.content 0 .text No SDK: use the gateway Add a provider credential and a gateway key in the dashboard Gateway , then point your existing client at Spanlight: python from openai import OpenAI client = OpenAI base url="http://localhost:8080/gw/v1", api key="spl gw …" For Anthropic, use Anthropic base url="http://localhost:8080/gw", api key="spl gw …" . No SDK: use OpenTelemetry Point any OTLP/HTTP exporter at http://localhost:8080/v1/otlp/traces with the header Authorization: Bearer spl live … . JSON and protobuf are both accepted. See the OTLP guide https://spanlight.dev/docs/otlp/ for the attributes each library sends. The wizard shows your first trace live. From there you have the overview dashboard, the trace explorer, sessions, cost, attribution and the Doctor. In one sentence: your app sends a record of every LLM call to Spanlight, Spanlight prices it, stores it in Postgres and checks it for problems, and you read the results in the dashboard. flowchart LR app "Your app" subgraph spanlight "Spanlight one Docker image " web "web