---
title: "Tracing & Observability"
description: "Comprehensive execution tracing with input/output/error/timing capture for complete observability"
---

Events are **not persisted to memory** - they are **immutable** temporary notifications that stream during execution. They provide immediate feedback about what's happening (_e.g._ start, progress chunks, completion) but are not stored permanently. Events are consumed as they're generated and are ideal for real-time monitoring, progress tracking, and streaming responses. For permanent storage and analysis, this information is captured in Traces.

## Traces

A Trace is the core data structure that captures execution information for every runnable execution, providing a complete audit trail of what happened. This tracing system enables complete observability into your application's behavior and performance.

For the previous llm example events, a trace would look like this:

```python
from timbal.state.tracing import Trace

trace = Trace(
    run_id="068c4458382e79bb80006dc019ac3039",
    parent_run_id=None,
    path="agent.llm",
    call_id="068c4458383678be800031537a8df42e", 
    parent_call_id="068c4458382e708f8000cc0f9b19d970",
    input={
        "model": "openai/gpt-4o-mini", 
        "messages": [{
            "role": "user", 
            "content": [{"type": "text", "text": "Hello"}]
        }], 
    },
    output={
        "role": "assistant", 
        "content": [{"type": "text", "text": "Hello! How can I assist you today?"}]
    },
    error=None,
    t0=1640995200000, # Start time
    t1=1640995201000, # End time
    usage={
        "gpt-4o-mini-2024-07-18:input_text_tokens": 32, 
        "gpt-4o-mini-2024-07-18:output_text_tokens": 10,
    },
    metadata={
        "type": "LLM", 
        "model_provider": "openai", 
        "model_name": "gpt-4o-mini", 
        "ttft": 1.218775834015105, # Time To First Token
        "tps": 103.44992571967803, # Tokens Per Second
    },
)
```

That's a single trace, but traces don't usually come in isolation - they're organized into larger execution units: Runs.

## Runs

A Run represents the complete execution of your application - from the moment you invoke a runnable until it finishes. Think of it as the lifecycle of a single request or operation, whether that's a simple function call or a complex multi-step agent workflow.

Every Run is composed of a collection of traces:

- **Simple execution**: Running a single tool generates one trace - the tool's input, output, timing, and metadata
- **Complex execution**: Running an agent generates multiple traces as it decides which tools to use, calls LLMs for reasoning, executes tools, and processes results

All traces within a run share the same `run_id`, creating a complete execution history that you can analyze, debug, or replay.

### The Run Context

Traces are stored in the RunContext - a central hub that manages all run data. You can access traces during execution, control storage behavior, and use this system to share data between different parts of your run.

More on this in the [Context](./context) section.
