Skip to content

Trace File Formats

Many trace files are formatted in ways that need to be specially handled to create an accurate replay. This guide covers all trace file formats currently supported by GuideLLM, along with the format-agnostic and format-specific data arguments.

Detailed use of the replay profile and file-based datasets as a whole is explained in Trace Replay Benchmarking.

Supported Formats

These are passed to the --data argument as kind=format:

  • trace_synthetic: A trace format that does the bare minimum needed to complete a fully functioning trace replay benchmark with synthetic prompt generation
  • mooncake: The trace format used by the serving platform Mooncake, as defined in https://doi.org/10.48550/arXiv.2407.00079
  • weka: The trace format used by WEKA's Augmented Memory Grid, as specified in the original research repository

Loading Trace Data

Trace replay always uses --profile kind=replay. Choose a format (trace_synthetic, mooncake, or weka) and a source type from one of the other deserializer kinds (json_file, huggingface, etc). For example:

trace_synthetic with local json_file:

guidellm run \
  --backend kind=openai_http,target=http://localhost:8000 \
  --profile kind=replay \
  --data kind=trace_synthetic,source.kind=json_file,source.path=replay.jsonl,time_scale=1.0

WEKA dataset from huggingface:

guidellm run \
  --backend kind=openai_http,target=http://localhost:8000 \
  --profile kind=replay \
  --data kind=weka,source.kind=huggingface,source.source=semianalysisai/cc-traces-weka-no-subagents-051226,load_kwargs.split=train

Mooncake dataset from huggingface

  --backend kind=openai_http,target=http://localhost:8000 \
  --profile kind=replay \
  --data kind=weka,source.kind=hf,source.src=valeriol29/mooncake-traces,load_kwargs.name=mooncake

Format-Agnostic Data Arguments

All trace formats can accept the following optional data arguments:

Argument Default Description
timestamp_column "timestamp" Column name for timestamps in the trace file
prompt_tokens_column "input_length" Column name for prompt token counts in the trace file
output_tokens_column "output_length" Column name for output token counts in the trace file
time_scale 1.0 Scale remaining relative timestamps after wait and pack caps
max_wait unset Maximum gap in original trace seconds between consecutive requests in one session
max_session_wait unset Maximum idle in original trace seconds from the previous session's last request to this session
min_concurrent_sessions unset Pack sessions so at least this many overlap during steady state
copies 1 Sequential full-dataset replays; pass k+1 starts at pass k's last scheduled request
copy_offset 1.0 Where the next copy starts relative to the prior span: 0 at the start, 1 at the end, >1 a gap

These are passed through the --data argument like below:

guidellm run \
    --backend kind=openai_http,target=http://localhost:8000 \
    --profile kind=replay \
    --data "kind=trace_synthetic,source.kind=json_file,source.path=replay.jsonl,timestamp_column=ts,prompt_tokens_column=input_tokens,output_tokens_column=generated_tokens,time_scale=1.0,max_session_wait=30"

trace_synthetic can be thought of as the format-agnostic option, only looking for the timestamp, prompt token count and output token count columns and ignoring all other features contained in a dataset. While primarily used for testing, trace_synthetic may be used as a fallback for trace formats not currently supported by GuideLLM.

trace_synthetic and mooncake replay each row as an independent, single-request conversation. Rows are sorted by timestamp and keep their offsets from the first request in the trace. Prompts are generated as rows are consumed, and Mooncake hash IDs remain shared across rows within one copies pass. Use max_session_wait to cap gaps between these independent requests; max_wait only caps gaps within multi-request conversations, such as WEKA sessions.

Raise parallelism with min_concurrent_sessions, wait caps, and time_scale first. Use copies only when that packed pass is too short for the benchmark (max_duration / max_requests). By default (copy_offset=1) copies replays the entire packed dataset back-to-back: the next pass starts at the previous pass's last request timestamp. copy_offset=0 starts at the prior pass's first timestamp; values between 0 and 1 interpolate; values above 1 add a gap. Hash-id formats (mooncake, weka) use a separately salted global token-block table per pass so later passes do not reuse earlier tokens and inflate prefix-cache hits.

Format-Specific Data Arguments

mooncake

The Mooncake format expects an additional column for prefix-based cache hash IDs. During prompt generation, hash IDs sharing the same previous ID are required to represent distinct blocks of token ids.

Argument Default Description
hash_ids_column "hash_ids" Column name for lists of hash IDs in the trace file
hash_id_block_size 512 Amount of tokens represented by one hash ID

weka

NOTE: Warm tool_tokens/system_tokens prefixes and hash-id LCP splitting of flattened agents are not implemented. Declared type: "subagent" groups and tool-call events (stop: tool_use, input_types: ["tool_result"]) are replayed.

The WEKA format expects a column with conversation UUIDs that is not wrapped within another column. The timestamp, input token length, output token length and hash IDs columns must all be wrapped inside one JSON column (ex. "requests"), in the form of a list of JSON objects.

Similar to Mooncake, WEKA uses prefix-based cache hash IDs. The original specification for the trace requires hash IDs to be 1 or greater, and for trailing hash IDs to be dropped if there are not enough input tokens to fill the hash ID block size. To accommodate for datasets which may not follow the specification exactly (ex. semianalysisai/cc-traces-weka-no-subagents-051226), GuideLLM will accept any non-negative integer as a valid hash ID, and will drop partially filled hash IDs if they exist.

GuideLLM will generate prompts starting from the first conversation. When the conversation ends, the next conversation will be used. Relative timestamps are offsets from the earliest request in the dataset, so later conversations can start later than the first.

Hash IDs follow the per-row hash_id_scope field:

  • "global" or omitted: hash IDs share one token-block table across conversations, matching Mooncake. The same hash ID in a later conversation reuses the earlier token block so prefix-cache hit rate stays close to the original trace. Each copies pass uses a separately salted global table.
  • "local": hash IDs apply only within that conversation. The table is discarded after the conversation is emitted. Local isolation also applies independently on each copies pass.

Declared type: "subagent" entries become isolated child chains. Each child spawns from the preceding parent API turn with a fresh history (history_context="new") and the following parent turn waits for every sibling spawned since that turn (history_context="last"). Multiple subagents listed between the same parent turns therefore run in parallel; the parent resumes only after all of them complete. Request-list order is preserved at every nesting level (it is the spawn/join topology) and is not sorted by timestamp.

Inner request timestamps follow the spec when they are relative to spawn, and published Hugging Face corpora when they are already absolute: if the first inner t is less than the subagent entry's spawn t, inner times are treated as spawn_t + inner_t; otherwise they are left as-is. Conversation timestamps are then absolute_t minus the earliest API request time in the dataset.

A single agent's consecutive turns are still serialized. If those turns overlap in time (t[i] + api_time[i] > t[i+1], or t[i+1] <= t[i] when api_time is absent), GuideLLM logs a debug message. Overlap between different subagents is intended parallelism and is not warned.

Tool-call events map onto GuideLLM's existing client tool-call pipeline. A request with stop: "tool_use" and user text input becomes a client_tool_call turn. The following request with input_types: ["tool_result"] (or, if input_types is absent, the next request after stop: "tool_use" on the same agent chain) becomes a tool_response_injection. When that injection row also has stop: "tool_use", it still sends tool results and keeps tools so the model may emit further tool calls. Traces do not contain real tool schemas or results. Pass tools and optionally tool_response_tokens the same way as synthetic data; otherwise GuideLLM uses the default synthetic tool definition and placeholder tool response. Chat handlers do not send the hash-id prompt as a user message on injection turns.

Argument Default Description
conversation_id_column "id" Column name for conversation UUIDs in the trace file
hash_ids_column "hash_ids" Column name for lists of hash IDs in the trace file
hash_id_block_size 64 Amount of tokens represented by one hash ID
tools None OpenAI-format tool definitions for tool-call turns. When unset, the built-in placeholder tool is used
tool_response_tokens None Average tokens for mocked tool results. When unset, a short placeholder ({"status": "ok"}) is used
tool_response_tokens_stdev None Standard deviation for tool response token count
tool_response_tokens_min None Minimum number of tokens for tool response
tool_response_tokens_max None Maximum number of tokens for tool response

Modified defaults:

Argument New Default
timestamp_column "t"
prompt_tokens_column "in"
output_tokens_column "out"