> ## Documentation Index
> Fetch the complete documentation index at: https://docs.uselemma.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Spans

> Trace retrieval, ranking, and app logic as child spans

A **span** is a unit of work inside a trace that is not an LLM call or a tool call — retrieval, reranking, planning, validation, parsing, a database query, or any app operation you want to see and time.

Spans are the catch-all. Use a [generation](/tracing/instrumentation/generations) for LLM calls and a [tool call](/tracing/instrumentation/tool-calls) for tools; use a span for everything else.

## Record a span

Create spans **inside** the trace root callback so they nest under the trace.

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    import { startActiveObservation } from "@langfuse/tracing";

    const ranked = await startActiveObservation(
      "rerank-results",
      async (span) => {
        span.update({ input: { candidates: candidates.length } });
        const result = await rerank(candidates);
        span.update({ output: { kept: result.length } });
        return result;
      },
      { asType: "span" },
    );
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    from langfuse import get_client

    langfuse = get_client()

    with langfuse.start_as_current_span(name="rerank-results") as span:
        span.update(input={"candidates": len(candidates)})
        result = rerank(candidates)
        span.update(output={"kept": len(result)})
    ```
  </Tab>
</Tabs>

`{ asType: "span" }` is the default, so you can omit it.

## Nesting spans

Spans can contain other spans, generations, and tool calls. Anything created inside a span's callback becomes its child, which is how you model a multi-step sub-task:

```text theme={null}
support-agent              ← trace root
└─ answer-question         ← span
   ├─ retrieve-context     ← span
   │  └─ search_docs       ← tool call
   └─ draft-reply          ← generation
```

## What to record

| Field                     | Use                                                        |
| ------------------------- | ---------------------------------------------------------- |
| `input`                   | Inputs to the operation (keep it a small summary if large) |
| `output`                  | Result or a summary of the result                          |
| `level` + `statusMessage` | Mark errors (`level: "ERROR"`)                             |
| `metadata`                | Operation-specific detail for debugging                    |

<Note>
  Spans are for app logic that the model and tools do not cover. Start with [generations](/tracing/instrumentation/generations) and [tool calls](/tracing/instrumentation/tool-calls); add spans where you need to time or debug a specific step.
</Note>

## Next steps

<CardGroup cols={2}>
  <Card title="Threads & context" icon="users" href="/tracing/instrumentation/context">
    Group conversations and attach users, sessions, and metadata.
  </Card>

  <Card title="Trace contract" icon="file-check" href="/reference/trace-contract">
    The exact shape Lemma reads.
  </Card>
</CardGroup>
