Laminar is a free, open source machine learning infrastructure project written in TypeScript and released under Apache-2.0. It has 3,265 GitHub stars, 239 forks and 116 open issues, and was last pushed 7 hours ago. On this registry it ranks #38 of 57 tracked projects in Machine Learning Infrastructure, with 5 head-to-head comparisons available. It gained 16 stars over the last 6 tracked days.

What is Laminar?

What it is

Laminar is an open-source observability platform purpose-built for AI agents, distributed under the Apache-2.0 license and written primarily in TypeScript. It was built by the team behind Y Combinator's S24 batch and lives in the AI and machine learning infrastructure ecosystem, with a topic list spanning agent observability, LLM evaluation, LLMOps and AIOps. The project ships as a tracing and evaluation stack rather than a general-purpose APM tool, and its homepage at laminar.sh hosts both documentation and a managed offering.

The concrete problem it solves is the gap between what an agent actually does and what a developer can see. Agent runs fan out across model providers, tool calls and multi-step chains, and conventional logging does not capture that structure. Laminar provides an OpenTelemetry-native tracing SDK that instruments Vercel AI SDK, Browser Use, Stagehand, LangChain, OpenAI, Anthropic, Gemini and others with one line of code, then stores and queries the resulting spans. It also addresses evaluation and monitoring: Signals lets a developer describe a behavior in plain English, such as an agent stuck in a loop, and Laminar reads every run and pings Slack when it occurs.

Key capabilities

  • OpenTelemetry-native tracing SDK with one-line auto-instrumentation for Vercel AI SDK, Browser Use, Stagehand, LangChain, OpenAI, Anthropic and Gemini.
  • Signals: plain-English descriptions of agent behavior that are checked against every run, with Slack notifications when a condition fires.
  • Evals: an unopinionated, extensible SDK and CLI for running evaluations locally or inside a CI/CD pipeline, plus a UI for visualizing and comparing results.
  • MCP and CLI access that lets a coding agent query traces and investigate issues directly.
  • SQL querying over traces, spans, metrics and events, with a dashboard builder that supports custom SQL queries.
  • Data annotation and dataset creation through a custom data rendering UI.
  • Performance work in the Rust core: 20x trace compression, a custom realtime engine for live trace viewing, ultra-fast full-text search over span data, and a gRPC exporter.

Who uses it and how

  • Teams instrumenting agents built on LangChain, Vercel AI SDK, Browser Use, Stagehand, OpenAI, Anthropic or Gemini and needing trace visibility without hand-rolled logging.
  • Developers running evals in CI/CD pipelines through the SDK and CLI, then comparing runs in the UI.
  • Engineers using MCP or the CLI to let a coding agent investigate and debug issues from trace data.
  • Operators building custom dashboards over traces, metrics and events with SQL.
  • Annotators and evaluation authors creating datasets through the data rendering UI.

Getting started

Fastest path is the managed platform at laminar.sh. Self-hosting starts by cloning the repository and running docker compose up -d, which brings up a lightweight full-featured stack reachable at http://localhost:5667; production deployments use docker compose -f docker-compose-full.yml up -d. The SDK then needs baseUrl and correct ports configured.

When to use it — and when not to

Self-hosters take on the full Compose stack, including ClickHouse, whose configuration disables internal telemetry logs and retains query and error logs for three days; upgrading requires recreating the ClickHouse container and truncating disabled log tables to reclaim disk. The repository shows 116 open issues and a listed contributor count of zero, so a self-hoster should expect to operate the stack largely without upstream staffing signals. Managed hosting is the recommended route for production.

project readme (upstream, from github) — read inline

Static Badge X (formerly Twitter) Follow LinkedIn Static Badge

Laminar banner

Laminar

Laminar is an open-source observability platform purpose-built for AI agents.

  • Tracing. Docs
    • OpenTelemetry-native powerful tracing SDK - 1 line of code to automatically trace Vercel AI SDK, Browser Use, Stagehand, LangChain, OpenAI, Anthropic, Gemini, and more.
  • Signals. Docs
    • Describe any behavior of your agent that you want to track in plain English (e.g. "agent is stuck in a loop")
    • Laminar reads every agent run and pings you in Slack when it happens.
  • Evals. Docs
    • Unopinionated, extensible SDK and CLI for running evals locally or in CI/CD pipeline.
    • UI for visualizing evals and comparing results.
  • MCP / CLI access for your coding agent
    • Query traces, spans, metrics, and events with SQL
    • Let your coding agent investigate and debug issues based on your traces
  • Dashboards. Docs
    • Powerful dashboard builder for traces, metrics, and events with support of custom SQL queries.
  • Data annotation & Datasets. Docs
    • Custom data rendering UI for fast data annotation and dataset creation for evals.
  • Extremely high performance.
    • Written in Rust 🦀
    • 20x trace compression for efficient ingestion and storage. Read more about it here.
    • Custom realtime engine for viewing traces as they happen.
    • Ultra-fast full-text search over span data.
    • gRPC exporter for tracing data.

Traces

Documentation

Check out the full documentation here laminar.sh/docs.

Getting started

The fastest and easiest way to get started is with our managed platform -> laminar.sh

Self-hosting with Docker compose

Laminar is very easy to self-host locally. For a quick start, clone the repo and start the services with docker compose:

git clone https://github.com/lmnr-ai/lmnr
cd lmnr
docker compose up -d

This will spin up a lightweight but full-featured version of the stack. This is good for a quickstart or for lightweight usage. You can access the UI at http://localhost:5667 in your browser.

You will also need to properly configure the SDK, with baseUrl and correct ports. See guide on self-hosting.

For production environment, we recommend using our managed platform or docker compose -f docker-compose-full.yml up -d.

Upgrading existing self-hosted installations

The ClickHouse configuration disables internal telemetry logs that are not useful for a single-node installation and retains query and error logs for three days. After pulling this change, recreate the ClickHouse container to apply the configuration. The examples below use docker-compose.yml; pass -f with the Compose file used by your deployment when it differs:

docker compose up -d --force-recreate clickhouse

Disabling a system log stops new writes but does not clear an existing table. To reclaim its disk space while preserving the table structure, truncate the disabled log tables after ClickHouse restarts:

docker compose exec -T clickhouse clickhouse-client --multiquery <<'SQL'
TRUNCATE TABLE IF EXISTS system.trace_log;
TRUNCATE TABLE IF EXISTS system.text_log;
TRUNCATE TABLE IF EXISTS system.part_log;
TRUNCATE TABLE IF EXISTS system.metric_log;
TRUNCATE TABLE IF EXISTS system.asynchronous_metric_log;
TRUNCATE TABLE IF EXISTS system.background_schedule_pool_log;
TRUNCATE TABLE IF EXISTS system.query_metric_log;
TRUNCATE TABLE IF EXISTS system.query_thread_log;
TRUNCATE TABLE IF EXISTS system.query_views_log;
TRUNCATE TABLE IF EXISTS system.session_log;
TRUNCATE TABLE IF EXISTS system.crash_log;
TRUNCATE TABLE IF EXISTS system.opentelemetry_span_log;
TRUNCATE TABLE IF EXISTS system.zookeeper_log;
TRUNCATE TABLE IF EXISTS system.blob_storage_log;
TRUNCATE TABLE IF EXISTS system.processors_profile_log;
TRUNCATE TABLE IF EXISTS system.asynchronous_insert_log;
SQL

When ClickHouse applies the new TTL to an existing query_log or error_log, it may rename the previous table with a numeric suffix such as query_log_0. Inspect any suffixed tables before dropping them if you also want to reclaim their historical data.

Configuring LLM provider (optional)

Frontend AI features (chat-with-trace, SQL-with-AI) and server-side AI workers require an LLM provider. Configure one in your .env file at the repo root.

Pick one of the following provider setups. LLM_MODEL_SMALL|MEDIUM|LARGE are optional — per-provider defaults apply when unset. LLM_DEFAULT_HEADERS_JSON is optional for any provider or gateway that requires static headers.

# Optional for any provider/gateway that requires static headers
# LLM_DEFAULT_HEADERS_JSON='{"X-Gateway-Tenant":"tenant"}'

# Option A: Gemini
LLM_PROVIDER=gemini
LLM_API_KEY=your_gemini_key

# Option B: OpenAI (or any OpenAI-compatible gateway such as LiteLLM, OpenRouter, vLLM)
LLM_PROVIDER=openai
# LLM_BASE_URL=http://localhost:4000   # optional, for OpenAI-compatible gateways
LLM_API_KEY=your_openai_key

# Option C: AWS Bedrock (Anthropic Claude). Uses AWS credentials instead of LLM_API_KEY.
LLM_PROVIDER=bedrock
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
AWS_REGION=us-east-1

# Option D: Azure AI Foundry. One resource serves three API shapes; pick the one
# matching your deployment. Model ids are deployment names, so set LLM_MODEL_*
# unless your deployments are named after the models.
#   azure_chat_completions -> <resource>.services.ai.azure.com/openai/v1/chat/completions
#   azure_responses        -> <resource>.services.ai.azure.com/openai/v1/responses
#   azure_anthropic        -> <resource>.services.ai.azure.com/anthropic/v1/messages (Claude)
LLM_PROVIDER=azure_chat_completions
LLM_API_KEY=your_azure_key
AZURE_RESOURCE_ID=your_resource_name   # or AZURE_BASE_URL for private endpoints
# AZURE_API_VERSION=preview            # optional; only for resources that require it

Custom Postgres schema (optional)

By default Laminar uses the public schema. To target a different schema (e.g. when deploying alongside other services in a shared Postgres instance), set the same value for both the frontend and the app-server:

POSTGRES_SCHEMA=laminar
# Set to false if the schema is pre-provisioned or the DB role lacks CREATE.
# POSTGRES_CREATE_SCHEMA=true

The schema is applied as the connection search_path, so all tables, foreign keys, and migrations target it. When a non-public schema is set, the frontend also tracks migrations inside that schema (.__drizzle_migrations) rather than the shared drizzle schema. Note that running Laminar alongside another Drizzle-managed service in the same database may still require manual intervention, since Drizzle's migration journal is versioned per-schema.

Anonymous usage telemetry

Self-hosted deployments collect anonymized usage telemetry. To opt out, set LAMINAR_TELEMETRY_DISABLED=true in your .env.

Contributing

For running and building Laminar locally, or to learn more about docker compose files, follow the guide in Contributing.

TS quickstart

First, create a project and generate a project API key. Then,

npm add @lmnr-ai/lmnr

It will install Laminar TS SDK and all instrumentation packages (OpenAI, Anthropic, LangChain ...)

To start tracing LLM calls just add

import { Laminar } from '@lmnr-ai/lmnr';
Laminar.initialize({ projectApiKey: process.env.LMNR_PROJECT_API_KEY });

To trace inputs / outputs of functions use observe wrapper.

import { OpenAI } from 'openai';
import { observe } from '@lmnr-ai/lmnr';

const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

const poemWriter = observe({name: 'poemWriter'}, async (topic) => {
  const respons

readme truncated — read the full docs on github

Frequently asked questions

Is Laminar free to use?

Laminar is open source under the Apache-2.0 licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does Laminar do?

AI-powered platform for engineering LLM products

What is Laminar written in?

Laminar is primarily written in TypeScript. Its source is publicly available at https://github.com/lmnr-ai/lmnr, and it has 3,265 GitHub stars.