Implementation:Langfuse Langfuse InMemoryFilterService
| Knowledge Sources | |
|---|---|
| Domains | Filtering, Evaluation, Data Processing |
| Last Updated | 2026-02-14 00:00 GMT |
Overview
The InMemoryFilterService evaluates Langfuse filter conditions against in-memory data objects, replicating the database filter logic in TypeScript for client-side or pre-query filtering.
Description
The InMemoryFilterService class provides a static method evaluateFilter that determines whether a given data object matches a set of FilterState conditions. This is the same filter system used by ClickHouse and PostgreSQL queries, but executed entirely in memory against TypeScript objects.
The service supports all Langfuse filter types:
- string - Exact match (
=),contains,does not contain,starts with,ends with - datetime - Comparison operators (
>,<,>=,<=) - number - Comparison operators (
=,>,<,>=,<=) - boolean - Equality (
=) and inequality (<>) - stringOptions -
any ofandnone offor multi-value selection - arrayOptions -
any of,none of,all offor array field matching - categoryOptions -
any ofandnone ofon nested object keys - stringObject - String filter on a nested object key value
- numberObject - Number filter on a nested object key value
- null -
is nullandis not nullchecks - positionInTrace - Ignored (only applied at database level)
A fieldMapper callback function is provided to the evaluator to map filter column names to the actual values in the data object, enabling flexible field resolution across different data shapes.
All filter conditions are evaluated with AND semantics -- every condition must match for the overall filter to pass. On any error, the evaluator safely returns false.
Usage
Use this service when you need to:
- Filter data objects in memory before or after database queries.
- Evaluate whether a newly ingested trace or score matches a saved filter configuration (e.g., for triggering evaluation jobs).
- Apply UI filter conditions to locally cached data.
- Test filter logic without requiring a database round-trip.
Code Reference
Source Location
- Repository: Langfuse
- File: packages/shared/src/server/services/InMemoryFilterService.ts
- Lines: 1-388
Signature
export class InMemoryFilterService {
static evaluateFilter<T>(
data: T,
filter: FilterState,
fieldMapper: (data: T, column: string) => unknown,
): boolean;
}
Import
import { InMemoryFilterService } from "@langfuse/shared/src/server/services/InMemoryFilterService";
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| data | T (generic) | Yes | The data object to evaluate against the filter conditions |
| filter | FilterState | Yes | Array of filter conditions (FilterCondition[]) to apply; empty array matches everything |
| fieldMapper | (data: T, column: string) => unknown | Yes | Callback function that maps a filter column name to the actual value in the data object |
Outputs
| Name | Type | Description |
|---|---|---|
| result | boolean | true if the data object matches all filter conditions; false otherwise (also false on any evaluation error)
|
Usage Examples
import { InMemoryFilterService } from "@langfuse/shared/src/server/services/InMemoryFilterService";
import { FilterState } from "@langfuse/shared";
// Define a trace-like data object
const trace = {
id: "trace-1",
name: "chat-completion",
timestamp: new Date("2024-03-15T10:00:00Z"),
userId: "user-1",
tags: ["production", "gpt-4"],
};
// Define filter conditions
const filters: FilterState = [
{ column: "name", type: "string", operator: "contains", value: "chat" },
{ column: "tags", type: "arrayOptions", operator: "any of", value: ["production"] },
];
// Map filter columns to trace fields
const fieldMapper = (data: typeof trace, column: string) => {
switch (column) {
case "name": return data.name;
case "tags": return data.tags;
case "timestamp": return data.timestamp;
default: return undefined;
}
};
// Evaluate
const matches = InMemoryFilterService.evaluateFilter(trace, filters, fieldMapper);
// matches === true