This page contains a reference of the table schemas and Laminar-specific syntax.

Table schemas and enum types

This section contains subsets of the table schemas and enumerated types (enums) that are relevant to the SQL Editor.

spans

ColumnTypeExample value
span_idUUID"00000000-0000-0000-1234-426614174000"
statusString"error"
nameString"openai.chat"
pathString"workflow.process.step1.openai.chat"
trace_idUUID"12345678-90ab-cdef-1234-426614174000"
parent_span_idUUID"00000000-0000-0000-a456-abcd5667ef09"
span_typeUInt81
start_timeDateTime64"2021-01-01 00:00:00+00"
end_timeDateTime64"2021-01-01 00:00:00+00"
inputString"[{\"role\": \"user\", \"content\": \"Hello, world!\"}]"
outputString"[{\"role\": \"assistant\", \"content\": \"Hi! How can I help you today?\"}]"
attributesString"{\"gen_ai.system\": \"openai\", \"gen_ai.model\": \"gpt-4o\"}"
request_modelString"gpt-4.1-mini"
response_modelString"gpt-4.1-mini-2025-04-14"
modelString"gpt-4.1-mini-2025-04-14"
providerString"openai"
input_tokensUInt64150
output_tokensUInt64100
total_tokensUInt64250
total_costFloat640.6897
input_costFloat640.5667
output_costFloat640.123

Path

Laminar span path is stored as an array of span names in span attributes. However, in the SQL queries, it is stored as a string with items joined by a dot. For example, if the span path is ["outer", "inner"], the path column will be "outer.inner". If needed, you can still access the array value by accessing the attributes using simpleJSONExtractRaw(attributes, 'lmnr.span.path').

Parent span ID

If the current span is the top span of the trace, the parent_span_id will be a 0 UUID, i.e. "00000000-0000-0000-0000-000000000000".

Span type

Here are the values of the span_type column and their meanings:
0: Default
1: LLM
3: Executor
4: Evaluator
5: Evaluation
6: Tool
7: HumanEvaluator

Input and output

The input and output columns are stored as either raw strings or stringified JSONs. The best way to parse them is to try to parse them as JSON, and if it fails, use the raw string. You can also use isValidJSON function right in the query to test for this. input and output columns are also indexed on content, so you can use them in WHERE conditions. Use ILIKE instead of LIKE, because the index is case-insensitive.

Attributes

The attributes column is stored as a string in JSON format. That is, you can safely JSON.parse / json.loads them. In addition, you can use JSON* and simpleJSON* functions on them right in the queries. Attributes are guaranteed to be a valid JSON object.

Model

The model column is set to the response model if present, otherwise it is set to the request model.

Total tokens and total cost

Usually, the total_tokens = input_tokens + output_tokens and total_cost = input_cost + output_cost. However, you can manually report these values using the relevant attributes. In this case, totals may not be equal to the sum of the input and output tokens and costs.

traces

ColumnTypeExample value
trace_idUUID"01234567-1234-cdef-1234-426614174000"
trace_typeUInt80
start_timeDateTime64"2021-01-01 00:00:00+00"
end_timeDateTime64"2021-01-01 00:00:00+00"
durationFloat641.23
input_tokensUInt64150
output_tokensUInt64100
total_tokensUInt64250
total_costFloat640.6897
input_costFloat640.5667
output_costFloat640.123
statusString"error"
user_idString"user_123"
session_idString"session_123"
metadataString"{\"key\": \"value\"}"
top_span_idUUID"00000000-0000-0000-1234-426614174000"

Trace type

Here are the values of the trace_type column and their meanings:
0: Default
2: Evaluation
3: Playground

Duration

The duration is in seconds, and is calculated as end_time - start_time.

Status

Status is set to error if any of the spans in the trace have status error. Empty status means success.

Metadata

Metadata is stored as a string in JSON format. That is, you can safely JSON.parse / json.loads it. In addition, you can use JSON* and simpleJSON* functions on it right in the queries. Metadata is guaranteed to be a valid JSON object.

events

ColumnTypeExample value
idUUID"01234567-89ab-4def-1234-426614174000"
span_idUUID"00000000-0000-0000-1234-426614174000"
nameString"My custom event"
timestampDateTime"2021-01-01 00:00:00+00"
attributesString"{\"key\": \"value\"}"
user_idString"user_123"
session_idString"session_123"

Notes

Attributes The attributes column is stored as a string in JSON format. That is, you can safely JSON.parse / json.loads it. In addition, you can use JSON* and simpleJSON* functions on it right in the queries. Attributes are guaranteed to be a valid JSON object.

evaluation_datapoints

ColumnTypeExample value
idUUID"01234567-89ab-4def-1234-426614174000"
trace_idUUID"01234567-1234-cdef-1234-426614174000"
evaluation_idUUID"98765432-1098-4654-3210-987654321098"
created_atDateTime64"2021-01-01 00:00:00+00"
dataString"{\"key\": \"value\"}"
targetString"{\"key\": \"value\"}"
metadataString"{\"key\": \"value\"}"
indexUInt640

evaluation_scores

Evaluation scores are stored in a separate table, linked to the evaluation datapoints. The scores are flattened into a single row per score. For example, if your evaluation has 3 scores, { "score1": 0.85, "score2": 0.90, "score3": 0.95 } will be stored as 3 rows in the evaluation_scores table.
ColumnTypeExample value
evaluation_idUUID"01234567-89ab-cdef-1234-426614174000"
evaluation_datapoint_idUUID"98765432-1098-7654-3210-987654321098"
timestampDateTime64"2021-01-01 00:00:00+00"
nameString"My custom score"
valueFloat640.85
metadataString"{\"key\": \"value\"}"
trace_idUUID"01234567-89ab-cdef-1234-426614174000"

Best practices

Avoid joins

ClickHouse is a columnar database, so, while JOINs are supported, they are not efficient. If you are joining tables with more than a few hundred rows, the query will likely timeout or fail.

Solution

Query the data you need, and join the relevant data in your application.

Add start_time filter

You almost certainly want to add a start_time filter to your query. Spans table (and thus traces aggregation on it) is sorted by start_time and trace_id, so if you apply a start_time WHERE condition, the query will run faster. Advantages:
  • Queries run faster
  • Queries will never fail because of running out of memory

Searching in span input or output

You can search in the input and output columns of the spans table. The search is optimized to be case-insensitive, so use ILIKE instead of LIKE.

Example

SELECT name, input, output
FROM spans
WHERE input ILIKE '%france%' AND output ILIKE '%paris%'