llama.cpp Request Budget
Find out the prompt doesn't fit before you wait for it
- connection
- profile
- image_1
- image_2
- image_3
- image_4
- image_5
- image_6
- image_7
- image_8
- image_9
- image_10
- structured_output
- token_ban
- messages
- summary
- budget_json
- budget
The problem it solves
You've wired a 3,000-word style guide into the system prompt, a six-turn history, two reference images and a 4,096-token output ceiling onto a model with an 8k slot context. You queue it. Ninety seconds later you get a response that starts mid-thought and stops mid-sentence, and you spend the next hour blaming your sampler.
The model didn't fail. You asked for more tokens than the slot holds, and something upstream silently did its best. Request Budget counts the complete request - prompt, system prompt, profile wrapping, earlier messages, images, structured-output scaffolding, the whole assembled payload - without generating a single token, and tells you whether it fits.
That's the entire pitch. It's the least glamorous node in the pack and the one that saves the most afternoons.
How the count actually happens
It goes through the same request-preparation path as llama.cpp Generate, so what gets counted is what would have been sent - not a rough character count. Your prompt is rendered with the connected profile, history is appended, media is processed, the model is resolved exactly, and then the payload goes to llama-server's /v1/chat/completions/input_tokens.
Two facts matter and the node is strict about both. input_tokens comes from that count endpoint. context_limit comes only from /props.default_generation_settings.n_ctx - the effective slot context, not the total server context and not the model's training context. Those are three different numbers, and using the wrong one is how people conclude they have room when they don't.
Unknown stays unknown. If the count endpoint isn't available you get null, never a zero. A real zero is preserved as zero, because zero is a legitimate answer. The policy is explicit and local: input_tokens + max_tokens <= context_limit. max_tokens here isn't an output setting - the node generates nothing - it's the output allowance you're reserving. Exactly zero remaining fits; negative overflows.
What you set, what you get
prompt is the only required input, plus everything Generate takes so the count matches reality: system_prompt, messages, profile, connection, server_url, model, image_amount and the image_1…image_10 sockets, structured_output, token_ban, max_tokens, request_timeout.
The one input that's unique to this node is budget_policy, and it has only two values. report - the default - returns fit / overflow / unknown and moves on. enforce fails the node unless both numbers are known and the allowance fits. Counting happens either way; the policy only decides whether a bad result is an observation or a stop.
Three outputs. summary is the human-readable verdict with input count, requested output, effective context and remaining capacity. budget_json is the versioned envelope - payload SHA-256, runtime epoch, elapsed time, release evidence, and deliberately no prompt text or credentials, so it's safe to look at or share. budget is the typed observation for adapters that want to branch on it, which is how you'd wire "if it overflows, regenerate my prompt shorter" without parsing prose.
It is a snapshot, not a permission slip
This is the subtle bit and the pack says it about as plainly as it can: a Request Budget node is a measurement of one payload at one moment. Change the model, the runtime, the prompt, an image, the profile, or the output allowance and the measurement is stale. Generate never accepts another node's green light - its own budget_policy (default off, with report and enforce available) counts its own request again immediately before generation.
So why run it separately at all? Because Generate's enforce fails at the last possible moment, and if you've queued a 32-image caption batch or a long chain, you want the bad news early rather than after the model loads. A budget node upstream of the expensive part is a smoke test. Generate's own policy is the seatbelt.
Nothing in either path truncates, summarises, shortens history or lowers your output allowance. The count is read-only. That's a deliberate choice - a node that silently fixes your request is a node that silently changes your output.
One thing to know before you queue it
Counting is not free. The node needs a running target, takes the runtime's operation lease, and can do real model and media work - loading a router model, processing images, running the tokenizer over the finished payload. In router mode the target has to be loaded first; discovery and label refreshes deliberately don't count anything or autoload a model. So don't put it on a loop and expect a no-op; treat it like a small generation.
It also carries a release_after_generation toggle, which asks the owned runtime for terminal release after counting - handy when the budget check is the last thing before a diffusion step. Check budget_json for the evidence. An attached server the pack didn't start can't be released this way, and terminal release is a process/residency fact, not instant driver memory convergence.
Installing
Part of the pack:
comfy node install comfyui-llamacpp
Or ComfyUI Manager → search "comfyui-llamacpp". The pack's own dependencies are light (aiohttp, numpy, pillow, psutil, requests); the runtime you supply is a llama-server binary, plus a GGUF in ComfyUI/models/LLM/gguf/.
Honest take: if your prompts are short and your context is 32k, you'll never think about this node. The moment you start chaining refinements, feeding long style guides, or attaching images, it earns its slot in the graph.
Where people get burned
Reading remaining as output room. It subtracts both input and the requested allowance. If you set max_tokens to 2048 out of habit but only need 200, the node will tell you you're tighter than you are. Set it to what you actually reserve.
Expecting it to match your chat client. Counts are model- and build-dependent, and multimodal numbers haven't been validated for every model. Compare against actual usage on the model and media type you're using before treating it as gospel.
Measuring a different request than the one you'll send. If the downstream Generate has a different max_tokens or a different model, you counted something else. Keep them identical or the number is fiction.
Inputs (40)
| Name | Type | Default | Description |
|---|---|---|---|
| prompt | STRING | User prompt sent through the connected profile snapshot. | |
| connectionopt | LLAMACPP_CONNECTION | Reusable secret-free local or attached server connection. | |
| profileopt | LLAMACPP_PROFILE | Portable task-profile snapshot. Controls remain unchanged. | |
| server_urlopt | STRING | Advanced attached or Start-node URL. Leave empty for the managed runtime, and do not combine with Connection. | |
| modelopt | COMBO | (use running model) | Exact router model ID, or the running direct model. |
| system_promptopt | STRING | An exactly empty value may be filled by the connected profile. | |
| thinking_modeopt | COMBO | auto | Auto omits an override; Off and On send an explicit request. |
| max_tokensopt | INT | 20481–1048576 | Requested output allowance reserved for budgeting. This node generates no text. |
| sampling_modeopt | COMBO | default | Default delegates samplers to the server; Custom sends all controls. |
| temperatureopt | FLOAT | 0.700–2 | Custom sampling randomness. |
| top_popt | FLOAT | 0.900–1 | Custom cumulative-probability cutoff. |
| top_kopt | INT | 400–1000000 | Custom top-K token cutoff; zero disables it. |
| min_popt | FLOAT | 0.050–1 | Custom probability floor relative to the best token. |
| repeat_penaltyopt | FLOAT | 1.101–2 | Custom penalty for recently repeated tokens. |
| presence_penaltyopt | FLOAT | 0.0-2–2 | Custom penalty for tokens that have appeared at least once. |
| frequency_penaltyopt | FLOAT | 0.0-2–2 | Custom penalty proportional to prior token frequency. |
| seedopt | INT | 00–2147483647 | Fixed or Comfy-controlled random seed. |
| cache_promptopt | BOOLEAN | false | Reuse a matching llama.cpp prompt-prefix KV cache. |
| stop_sequencesopt | STRING | Stop sequences. JSON arrays preserve commas and whitespace. | |
| api_key_envopt | STRING | LLAMACPP_API_KEY | Key variable: LLAMACPP_API_KEY or LLAMACPP_API_KEY_<UPPERCASE_SUFFIX>. The key itself is never saved. |
| verify_tlsopt | BOOLEAN | true | Verify HTTPS certificates. |
| request_timeoutopt | INT | 3001–86400 | Overall request and terminal-release wait deadline. |
| image_amountopt | INT | 00–10 | Number of IMAGE sockets to expose, from zero through ten. |
| include_image_batchopt | BOOLEAN | false | Send every frame from each connected Comfy IMAGE batch. |
| release_after_generationopt | BOOLEAN | false | Wait for terminal managed runtime/model release after counting. Unavailable for attached endpoints. |
| partial_output_policyopt | COMBO | raise_error | Counts never return partial results; this setting has no effect on counting. |
| image_1opt | IMAGE | Optional image 1; visibility follows Image Amount. | |
| image_2opt | IMAGE | Optional image 2; visibility follows Image Amount. | |
| image_3opt | IMAGE | Optional image 3; visibility follows Image Amount. | |
| image_4opt | IMAGE | Optional image 4; visibility follows Image Amount. | |
| image_5opt | IMAGE | Optional image 5; visibility follows Image Amount. | |
| image_6opt | IMAGE | Optional image 6; visibility follows Image Amount. | |
| image_7opt | IMAGE | Optional image 7; visibility follows Image Amount. | |
| image_8opt | IMAGE | Optional image 8; visibility follows Image Amount. | |
| image_9opt | IMAGE | Optional image 9; visibility follows Image Amount. | |
| image_10opt | IMAGE | Optional image 10; visibility follows Image Amount. | |
| structured_outputopt | STRUCTURED_OUTPUT | Optional JSON, JSON Schema, or grammar constraint. | |
| token_banopt | LOGIT_BIAS | Optional token bans from llama.cpp Token Ban. | |
| messagesopt | LLAMACPP_MESSAGES | Explicit earlier text turns. Current prompt and images are appended. | |
| budget_policyopt | COMBO | report | Report returns fit, overflow or unknown. Enforce fails unless input plus requested output fits a known effective context. Counting always runs. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| summary | STRING | Fit, overflow or unknown for input tokens plus the requested output allowance. |
| budget_json | STRING | Versioned budget with payload hash, runtime epoch, timing and release evidence. |
| budget | LLAMACPP_REQUEST_BUDGET | Typed budget observation. A later Generate node checks its own request again. |