feat(load_test): add --session-mode for progressively growing prompts - #131
feat(load_test): add --session-mode for progressively growing prompts#131nithiyn wants to merge 1 commit into
Conversation
The default workload re-sends one fixed prefix, so a prompt cache is either warm for that whole block or not warm at all. Agent traffic instead grows a single conversation a turn at a time, and DeepSeek-V4 only serves a cheap hit when a request is an exact continuation of the previous one, so the two patterns produce very different TTFT. In session mode each Locust user owns one conversation. A turn appends (-p minus -pcml) tokens of fresh dataset text plus the previous response, and the conversation restarts once the prompt passes 2x -p, which keeps the average request at the requested -p. -pcml only sizes the turns here and is no longer sent to the server, since capping the cacheable prefix at -pcml would leave the later turns re-prefilling what they just cached. Every request in a session carries the same user id so consecutive turns land on the same generator.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit dd35067. Configure here.
| # Prefer the server's prompt count so the estimate re-syncs every turn instead | ||
| # of drifting on per-message chat template overhead. | ||
| served_prompt_tokens = prompt_tokens or self._history_tokens + self._pending_user_tokens | ||
| self._history_tokens = served_prompt_tokens + (completion_tokens or 0) |
There was a problem hiding this comment.
History counts reasoning tokens
Medium Severity
complete_turn grows _history_tokens by full completion_tokens / num_tokens, but the committed assistant message is only assistant_content (visible text, reasoning stripped). On reasoning models those totals include thinking tokens that never enter messages, so sessions hit the 2 * -p restart threshold too early and average prompt length drifts below -p.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit dd35067. Configure here.




The default workload re-sends one fixed prefix, so a prompt cache is either warm for that whole block or not warm at all. Agent traffic instead grows a single conversation a turn at a time, and DeepSeek-V4 only serves a cheap hit when a request is an exact continuation of the previous one, so the two patterns produce very different TTFT.
In session mode each Locust user owns one conversation. A turn appends (-p minus -pcml) tokens of fresh dataset text plus the previous response, and the conversation restarts once the prompt passes 2x -p, which keeps the average request at the requested -p. -pcml only sizes the turns here and is no longer sent to the server, since capping the cacheable prefix at -pcml would leave the later turns re-prefilling what they just cached. Every request in a session carries the same user id so consecutive turns land on the same generator.
Note
Low Risk
Benchmark-only changes with unit tests; default workload is unchanged unless
--session-modeis enabled.Overview
Adds
--session-modetollm_benchso each Locust user runs one growing chat conversation instead of repeating a fixed prompt prefix—closer to agent clients and to cache behavior that only hits on exact continuation (e.g. DSv4).Each turn sends prior messages plus a new user chunk sized as
-pminus-pcml, echoes visible assistant content only (not reasoning) into history, reuses a stableuserid for Fireworks session affinity, and resets the thread once estimated prompt size reaches 2×-p.-pcmlis not sent to Fireworks in this mode (it only sizes turns). Dataset drawing drops the shared prefix;session_turnis recorded as a metric.README documents usage;
test_session_mode.pycovers limits, growth, restart, failed-turn rollback, and session id stability.Reviewed by Cursor Bugbot for commit dd35067. Bugbot is set up for automated code reviews on this repo. Configure here.