feat(serve): add GET /v1/load for load-aware routing - #102
Merged
Merged
Conversation
Report running, prefilling, waiting and admitted requests, configured concurrency and admission capacity, KV capacity and occupancy, and monotonic prefill/decode token counters, so a gateway in front of several engines can route and account by engine-true load instead of guessing. Capacity facts are captured once at attach; each poll reads only the published runtime stats and the ingress counter, never the Engine execution lock, so polling cannot stall decode. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0152Jc7HkHQ9Ww56WXfM4j8u
There was a problem hiding this comment.
✅ No action needed — ship it.
Correctness: No actionable defects found. Readability/Architecture: Rendering is isolated and capacity is published before readiness. Security: Existing authentication and readiness middleware protect the route. Performance: Polling avoids the execution lock. Verification: CI is green; focused tests cover report shape, capacities, counters, and zero-page handling. Project execution was not performed per the static-review constraint.
Reviewed by CodePulse · AI C++ review with a senior engineer's eye · codepulse.review →
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a cheap, pollable
GET /v1/loadendpoint toninfer-serve, so a load balancer or gateway that schedules across several servers can see engine-true load instead of guessing from its own bookkeeping.What it reports
capacity: fixed once the Engine is ready.max_concurrency,max_pending_requests,max_admitted_requests,max_contextrequests:admitted(holding ingress capacity),running,prefilling,decode_ready,waiting(in the Engine FIFO, including requests held back for KV entitlement),materializing.occupancy: Main KV pages/tokens in use, StateImage slots, Host KV bytes.counters: monotonic since startup, so callers derive tok/s by differencing two polls.computed_prefill_tokens,committed_decode_tokens,reused_prompt_tokens,decode_rounds,decode_row_rounds.uptime_seconds: counted from when the server became ready.Auth and readiness work like every other route: the endpoint needs the API key when one is configured, and returns
503 model_loadinguntil warmup completes. The response is sent withCache-Control: no-store. The full contract is indocs/serving.mdunder Load.Design notes
memory_summary()takes the execution lock, so capacity facts are captured once inattach(), beforeready_is published. Each poll only reads the already-publishedruntime_stats()snapshot and the ingress counter (GenerationService::admitted_requests(), a small mutex on the request-capacity struct). Polling therefore can't stall decode.src/serve/load_report.{h,cpp}, separate from the HTTP handler, so it's unit-testable without a server.Motivation
This is used by a gateway that fronts several engines with per-user parallel limits and a fair queue. It polls
/v1/loadevery 2 s:--max-concurrency;The endpoint is purely additive and opt-in by use. Nothing in the generation path changes.
Verification
tests/test_load_report.cpp(ninfer_load_report_test) covers:EngineOptions+MemorySummary;max_admitted_requests= concurrency + pending.tests/test_load_report.cppalso covers a zero-capacity report (kv_page_tokens= 0 with no pages).master, this built and the serving tests passed in the worktree's build tree. The gateway's parser for this payload is tested separately, but it has not polled a liveninfer-serveyet.master(merge: catch up with neroued/master (materialization search rework), adapted for MSVC #94–Port upstream #197 (ignore_eos) and #221 (MTP graph topology class) #101) applied without conflicts. The post-rebase rebuild was still running when this was pushed, so CI or a localctest -R "load_report|openai|anthropic|serve_options|request_log"should confirm it.🤖 Generated with Claude Code
https://claude.ai/code/session_0152Jc7HkHQ9Ww56WXfM4j8u