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

# Observability Hooks

> Capture component-level latency and token usage without changing the data flow.

Observability hooks capture component-level latency and token usage without changing the data flow. They are side-effect-only, so you can register many safely, each fires at the end of a component's turn with a payload of metrics (a `dict`).

## Component Metrics

Register a metrics hook with the `@pipeline.metrics.on("<component>")` decorator. Each component delivers different payload keys.

| Component  | Mode              | Key Payload Fields                                                                                                                                                                                                      |
| :--------- | :---------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `stt`      | Cascade           | `stt_latency`                                                                                                                                                                                                           |
| `llm`      | Cascade           | `llm_ttft`, `llm_duration`, `prompt_tokens`, `completion_tokens`, `total_tokens`                                                                                                                                        |
| `tts`      | Cascade           | `ttfb`, `tts_latency`                                                                                                                                                                                                   |
| `eou`      | Cascade           | `eou_latency`, `eou_wait_ms`                                                                                                                                                                                            |
| `realtime` | Realtime / Hybrid | `realtime_ttfb`, `realtime_input_tokens`, `realtime_output_tokens`, `realtime_total_tokens`, `realtime_input_text_tokens`, `realtime_output_text_tokens`, `realtime_input_audio_tokens`, `realtime_output_audio_tokens` |

## Use cases

Use `stt`, `llm`, `tts`, and `eou` metrics with Cascade pipelines. Use `realtime` metrics when the pipeline runs in Realtime or Hybrid mode with a realtime model as the LLM.

<Tabs>
  <Tab title="STT">
    <CodeGroup>
      ```python title="Python" Python theme={null}
      @pipeline.metrics.on("stt")
      def on_stt_metrics(metrics: dict):
          """Fired when an STT turn completes."""
          print(f"[METRICS] STT Latency: {metrics.get('stt_latency')}ms")
      ```

      ```typescript title="Node JS" Node JS theme={null}
      pipeline.metrics.on('stt', async (metrics: Record<string, any>) => {
        // Fired when an STT turn completes.
        console.log(`[METRICS] STT Latency: ${metrics.stt_latency}ms`);
      });
      ```
    </CodeGroup>
  </Tab>

  <Tab title="LLM">
    <CodeGroup>
      ```python title="Python" Python theme={null}
      @pipeline.metrics.on("llm")
      def on_llm_metrics(metrics: dict):
          """Fired when LLM generation completes."""
          print(
              f"[METRICS] LLM TTFT: {metrics.get('llm_ttft')}ms | "
              f"Total Duration: {metrics.get('llm_duration')}ms"
          )
          print(
              "[METRICS] LLM Tokens (P/C/T): "
              f"{metrics.get('prompt_tokens')}/"
              f"{metrics.get('completion_tokens')}/"
              f"{metrics.get('total_tokens')}"
          )
      ```

      ```typescript title="Node JS" Node JS theme={null}
      pipeline.metrics.on('llm', async (metrics: Record<string, any>) => {
        // Fired when LLM generation completes.
        console.log(
          `[METRICS] LLM TTFT: ${metrics.llm_ttft}ms | ` +
          `Total Duration: ${metrics.llm_duration}ms`
        );
        console.log(
          '[METRICS] LLM Tokens (P/C/T): ' +
          `${metrics.prompt_tokens}/` +
          `${metrics.completion_tokens}/` +
          `${metrics.total_tokens}`
        );
      });
      ```
    </CodeGroup>
  </Tab>

  <Tab title="TTS">
    <CodeGroup>
      ```python title="Python" Python theme={null}
      @pipeline.metrics.on("tts")
      def on_tts_metrics(metrics: dict):
          """Fired when TTS finishes speaking."""
          print(
              f"[METRICS] TTS TTFB: {metrics.get('ttfb')}ms | "
              f"Total Latency: {metrics.get('tts_latency')}ms"
          )
      ```

      ```typescript title="Node JS" Node JS theme={null}
      pipeline.metrics.on('tts', async (metrics: Record<string, any>) => {
        // Fired when TTS finishes speaking.
        console.log(
          `[METRICS] TTS TTFB: ${metrics.ttfb}ms | ` +
          `Total Latency: ${metrics.tts_latency}ms`
        );
      });
      ```
    </CodeGroup>
  </Tab>

  <Tab title="EOU">
    <CodeGroup>
      ```python title="Python" Python theme={null}
      @pipeline.metrics.on("eou")
      def on_eou_metrics(metrics: dict):
          """Fired when the Turn Detector matches end-of-utterance."""
          print(
              f"[METRICS] EOU Latency: {metrics.get('eou_latency')}ms | "
              f"EOU Wait: {metrics.get('eou_wait_ms')}ms"
              )
      ```

      ```typescript title="Node JS" Node JS theme={null}
      pipeline.metrics.on('eou', async (metrics: Record<string, any>) => {
        // Fired when the Turn Detector matches end-of-utterance.
        console.log(
          `[METRICS] EOU Latency: ${metrics.eou_latency}ms | ` +
          `EOU Wait: ${metrics.eou_wait_ms}ms`
        );
      });
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Realtime">
    <CodeGroup>
      ```python title="Python" Python theme={null}
      @pipeline.metrics.on("realtime")
      def on_realtime_metrics(metrics: dict):
          """Fired for realtime (speech-to-speech) models."""
          print(
              "[METRICS] Realtime "
              f"TTFB: {metrics.get('realtime_ttfb')}ms | "
              f"Tokens (in/out/total): "
              f"{metrics.get('realtime_input_tokens')}/"
              f"{metrics.get('realtime_output_tokens')}/"
              f"{metrics.get('realtime_total_tokens')} | "
              f"TextTokens (in/out): "
              f"{metrics.get('realtime_input_text_tokens')}/"
              f"{metrics.get('realtime_output_text_tokens')} | "
              f"AudioTokens (in/out): "
              f"{metrics.get('realtime_input_audio_tokens')}/"
              f"{metrics.get('realtime_output_audio_tokens')}"
          )
      ```

      ```typescript title="Node JS" Node JS theme={null}
      pipeline.metrics.on('realtime', async (metrics: Record<string, any>) => {
        // Fired for realtime (speech-to-speech) models.
        console.log(
          '[METRICS] Realtime ' +
          `TTFB: ${metrics.realtime_ttfb}ms | ` +
          `Tokens (in/out/total): ` +
          `${metrics.realtime_input_tokens}/` +
          `${metrics.realtime_output_tokens}/` +
          `${metrics.realtime_total_tokens} | ` +
          `TextTokens (in/out): ` +
          `${metrics.realtime_input_text_tokens}/` +
          `${metrics.realtime_output_text_tokens} | ` +
          `AudioTokens (in/out): ` +
          `${metrics.realtime_input_audio_tokens}/` +
          `${metrics.realtime_output_audio_tokens}`
        );
      });
      ```
    </CodeGroup>
  </Tab>
</Tabs>

## What's Next

<CardGroup cols={2}>
  <Card title="Observability and Analytics" icon="chart-line" href="/build/observability-and-monitoring/analytics/overview">
    View the captured metrics, traces, and logs on the Dashboard.
  </Card>

  <Card title="Run Your Agent" icon="play" href="/build/run-the-runtime">
    Monitor agent and user state changes.
  </Card>
</CardGroup>

## References

<Tabs>
  <Tab title="Python">
    #### Examples

    <CardGroup cols={2}>
      <Card title="Observability Hooks" icon="github" href="https://github.com/ZeroRuntimeAI/zeroruntime-python-examples/blob/main/observability/observability_hooks.py">
        Emit metrics and traces from pipeline hooks.
      </Card>
    </CardGroup>
  </Tab>

  <Tab title="Node JS">
    #### Examples

    <CardGroup cols={2}>
      <Card title="Observability Hooks" icon="github" href="https://github.com/ZeroRuntimeAI/zeroruntime-js-examples/blob/main/observability/pipeline_events.ts">
        Emit metrics and traces from pipeline hooks.
      </Card>
    </CardGroup>
  </Tab>
</Tabs>
