import { MessageTimingSample } from "@/components/docs/samples/message-timing";
This component is experimental. The API and displayed metrics may change in future versions. When used with the Vercel AI SDK, token counts and tok/s are **estimated** client-side and may be inaccurate — see [Accuracy](#accuracy) below.Getting Started#
Add message-timing#
<InstallCommand shadcn={["message-timing"]} />
This adds a /components/assistant-ui/message-timing.tsx file to your project.
Use in your application#
Place MessageTiming inside ActionBarPrimitive.Root in your thread.tsx. It will inherit the action bar's auto-hide behaviour and only renders after the stream completes.
import { ActionBarPrimitive } from "@assistant-ui/react";
import { MessageTiming } from "@/components/assistant-ui/message-timing";
const AssistantActionBar: FC = () => {
return (
<ActionBarPrimitive.Root
hideWhenRunning
autohide="not-last"
<ActionBarPrimitive.Copy />
<ActionBarPrimitive.Reload />
<MessageTiming />
</ActionBarPrimitive.Root>
);
};
What It Shows#
The badge displays totalStreamTime inline and reveals a popover on hover with the full breakdown:
| Metric | Description |
|---|---|
| First token | Time from request start to first text chunk (TTFT) |
| Total | Total wall-clock time from start to stream end |
| Speed | Output tokens per second (hidden for very short messages) |
| Chunks | Number of stream chunks received |
Accuracy#
Timing accuracy depends on how your backend is connected.
assistant-stream (accurate)#
When using assistant-stream on the backend, token counts come directly from the model's usage data sent in step-finish chunks. The tokensPerSecond metric is exact whenever your backend reports outputTokens.
Vercel AI SDK (estimated)#
When using the AI SDK integration (useChatRuntime), token counts are estimated client-side using a 4 characters per token approximation. This can overcount significantly for short messages.
API Reference#
MessageTiming component#
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Additional class names on the root element |
side | "top" | "right" | "bottom" | "left" | "right" | Side of the tooltip relative to the badge |
Renders null until totalStreamTime is available (i.e., while streaming or for user messages).
For the underlying useMessageTiming() hook, field definitions, and runtime-specific setup (LocalRuntime, ExternalStore, etc.), see the Message Timing guide.
Related#
- Message Timing guide —
useMessageTiming()hook, runtime support table, and custom timing UI - Thread — The action bar context that
MessageTimingis typically placed inside