User Traces
Last updated
Was this helpful?
Last updated
Was this helpful?
User traces let you stream runtime information—such as generated tokens, intermediate data, or logs—directly into the Midio editor as your application runs. They provide a flexible, customizable way to inspect and visualize what your flow is doing in real time.
Unlike standard execution traces, which automatically capture all function calls in a flow and display them in sequence (like a timeline showing the exact order in which functions are invoked), user traces are explicitly defined by your own code or by libraries you use. This gives you full control over what gets traced and when.
User traces are hierarchical. Each trace can contain one or more spans, and spans can themselves contain child traces. This structure allows you to organize and group related operations visually. For example, if you're building an agent that calls multiple tools during execution, you can represent each tool call as a span inside a single trace, or even as a nested child trace.
A span is a unit of data within a trace. Spans can display various types of information:
Plain text
Structured objects (JSON-like data)
Labeled items (name-value pairs)
And more...
You can use spans to display things like:
Prompts sent to an AI model
Responses received from an API
Intermediate steps in a computation
Because spans can be nested within traces, they allow you to clearly see how data flows through different stages of a complex operation.
One of the most powerful features of user traces is that they can aggregate data from multiple processes into the same trace. This means you can observe how different concurrent flows interact, or how multiple parallel operations contribute to a single task. For instance, if multiple user requests trigger different processes that all contribute to building an AI response, they can all stream their updates into the same trace.
This is especially useful for debugging or understanding asynchronous or agent-like behaviors where work is distributed across many function calls and processes.
The above flow does the following:
Starts a new trace, with the name "My Trace"
, which you can see in as the yellow label in the user trace panel.
Creates a new text span, as a child of the trace created in (1).
Creates another text span, also as a child of the trace created in (1).
Finally, we append some more text to the span we created in (2).
Some builtin packages, like the LLM package, feed data to the user trace panel. If you want interact with it yourself, you can look at the nodes available in the module. Here is a quick example that starts a new trace, with two child spans.