Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Langfuse Langfuse Traces UI Table Service

From Leeroopedia
Knowledge Sources
Domains Tracing, ClickHouse, UI
Last Updated 2026-02-14 00:00 GMT

Overview

This service provides functions for querying trace data from ClickHouse and converting it into UI-friendly table row formats for the Langfuse web application's traces table view.

Description

The traces-ui-table-service.ts module is the primary data access layer for the traces table displayed in the Langfuse web UI. It constructs complex ClickHouse SQL queries that join traces with observations and scores, applies dynamic filters, handles search, supports pagination, and returns data in multiple select modes: count, rows, metrics, and identifiers.

The core internal function getTracesTableGeneric uses TypeScript function overloads to provide type-safe return types based on the select parameter. It builds a Common Table Expression (CTE) query that aggregates observation statistics (token usage, cost, latency, error/warning counts) and score averages, then joins them with trace data. The service intelligently skips joins for observations or scores when they are not needed by the current query, improving performance for default views.

Key design decisions include:

  • Using FINAL on ClickHouse tables only when non-default ordering is used, avoiding unnecessary deduplication overhead.
  • Propagating timestamp filters to observation and score subqueries for query optimization, since 98% of observations have start times within 5 minutes of trace timestamps.
  • Supporting OTel projects that use immutable spans by skipping observation deduplication entirely.
  • Using LIMIT 1 BY id, project_id for default ordering to handle deduplication without FINAL.

Four public convenience functions wrap the generic function: getTracesTableCount, getTracesTableMetrics, getTracesTable, and getTraceIdentifiers. Two converter functions (convertToUiTableRows and convertToUITableMetrics) transform raw ClickHouse row formats into UI-friendly types with proper BigInt, Decimal, and Date conversions.

Usage

Use this service when you need to:

  • Fetch paginated trace data for the traces table UI with filtering, search, and ordering.
  • Retrieve trace counts for pagination controls.
  • Fetch trace metrics (latency, token usage, costs, scores, observation counts) for the metrics columns in the traces table.
  • Get trace identifiers for bulk operations or exports.

Code Reference

Source Location

Signature

// Types
export type TracesTableReturnType = Pick<TraceRecordReadType, "project_id" | "id" | "name" | "timestamp" | "bookmarked" | "release" | "version" | "user_id" | "session_id" | "environment" | "tags" | "public">;

export type TracesTableUiReturnType = Pick<TraceDomain, "id" | "projectId" | "timestamp" | "tags" | "bookmarked" | "name" | "release" | "version" | "userId" | "environment" | "sessionId" | "public">;

export type TracesMetricsUiReturnType = {
  id: string;
  projectId: string;
  promptTokens: bigint;
  completionTokens: bigint;
  totalTokens: bigint;
  latency: number | null;
  level: ObservationLevelType;
  observationCount: bigint;
  calculatedTotalCost: Decimal | null;
  calculatedInputCost: Decimal | null;
  calculatedOutputCost: Decimal | null;
  scores: ScoreAggregate;
  usageDetails: Record<string, number>;
  costDetails: Record<string, number>;
  errorCount: bigint;
  warningCount: bigint;
  defaultCount: bigint;
  debugCount: bigint;
};

export type FetchTracesTableProps = {
  select: "count" | "rows" | "metrics" | "identifiers";
  projectId: string;
  filter: FilterState;
  searchQuery?: string;
  searchType?: TracingSearchType[];
  orderBy?: OrderByState;
  limit?: number;
  page?: number;
  clickhouseConfigs?: ClickHouseClientConfigOptions | undefined;
  tags?: Record<string, string>;
};

// Converter functions
export const convertToUiTableRows: (row: TracesTableReturnType) => TracesTableUiReturnType;
export const convertToUITableMetrics: (row: TracesTableMetricsClickhouseReturnType) => Omit<TracesMetricsUiReturnType, "scores">;

// Public query functions
export const getTracesTableCount: (props: { projectId: string; filter: FilterState; searchQuery?: string; searchType: TracingSearchType[]; orderBy?: OrderByState; limit?: number; page?: number; }) => Promise<number>;

export const getTracesTableMetrics: (props: { projectId: string; filter: FilterState; searchQuery?: string; orderBy?: OrderByState; limit?: number; page?: number; clickhouseConfigs?: ClickHouseClientConfigOptions; }) => Promise<Array<Omit<TracesMetricsUiReturnType, "scores">>>;

export const getTracesTable: (p: { projectId: string; filter: FilterState; searchQuery?: string; searchType?: TracingSearchType[]; orderBy?: OrderByState; limit?: number; page?: number; clickhouseConfigs?: ClickHouseClientConfigOptions; }) => Promise<TracesTableUiReturnType[]>;

export const getTraceIdentifiers: (props: { projectId: string; filter: FilterState; searchQuery?: string; searchType?: TracingSearchType[]; orderBy?: OrderByState; limit?: number; page?: number; clickhouseConfigs?: ClickHouseClientConfigOptions; }) => Promise<Array<{ id: string; projectId: string; timestamp: Date }>>;

Import

import {
  getTracesTableCount,
  getTracesTableMetrics,
  getTracesTable,
  getTraceIdentifiers,
  convertToUiTableRows,
  convertToUITableMetrics,
} from "@langfuse/shared/src/server/services/traces-ui-table-service";

I/O Contract

Inputs

Name Type Required Description
projectId string Yes The project ID to filter traces for
filter FilterState Yes Array of filter conditions (e.g. timestamp ranges, trace names, user IDs, score filters)
select "rows" | "metrics" | "identifiers" Yes Determines the shape of the returned data
searchQuery string No Free-text search query to match against traces
searchType TracingSearchType[] No Types of search to perform (e.g. trace name, user ID)
orderBy OrderByState No Column and direction for ordering results
limit number No Maximum number of results to return (for pagination)
page number No Page number for pagination (0-indexed)
clickhouseConfigs ClickHouseClientConfigOptions No Optional ClickHouse client configuration overrides
tags Record<string, string> No Tags to attach to the ClickHouse query for tracing/logging

Outputs

Name Type Description
count result number Total number of matching traces (when select="count")
rows result TracesTableUiReturnType[] Array of trace row data with UI-friendly field names and types (when select="rows")
metrics result Omit<TracesMetricsUiReturnType, "scores">[] Array of trace metrics including latency, token usage, costs, and observation counts (when select="metrics")
identifiers result { id: string; projectId: string; timestamp: Date }[] Array of trace identifiers (when select="identifiers")

Usage Examples

// Get paginated trace rows for the UI table
const traceRows = await getTracesTable({
  projectId: "my-project-id",
  filter: [],
  searchQuery: "user query",
  searchType: ["trace-name"],
  orderBy: { column: "timestamp", order: "DESC" },
  limit: 50,
  page: 0,
});

// Get total count for pagination
const totalCount = await getTracesTableCount({
  projectId: "my-project-id",
  filter: [],
  searchType: [],
});

// Get metrics (latency, costs, token usage) for trace rows
const metrics = await getTracesTableMetrics({
  projectId: "my-project-id",
  filter: [],
  limit: 50,
  page: 0,
});

// Get trace identifiers for bulk operations
const identifiers = await getTraceIdentifiers({
  projectId: "my-project-id",
  filter: [],
  limit: 1000,
  page: 0,
});

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment