← Blog

How to Limit Claude API Token Usage (Without Breaking UX)

2026-10-26 · 5 min read · SubToAPI Team

If you're asking how to limit Claude API token usage, you're probably trying to solve one of two problems: a runaway cost bill, or unpredictable response lengths breaking your product. Both have the same root cause — token usage is uncapped by default, and you have to actively constrain it at multiple layers: the request itself, the conversation history you send, and the account or key level.

The short answer: set max_tokens on every request, trim or summarize conversation history before it grows unbounded, and enforce hard spending limits per API key or per user so a bug or abusive user can't blow through your budget. Below is how to do each one properly, with examples.

Why Token Usage Gets Out of Control

Claude bills on both input and output tokens. Most cost overruns come from one of these patterns:

Fixing the first two cuts cost per request. Fixing the last two caps total exposure. You need both.

1. Set max_tokens on Every Request

This is the most direct lever. max_tokens caps the output length, which is often the larger cost driver for generative tasks like summaries, code, or long-form writing.

curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-3-5-sonnet-20241022",
    "max_tokens": 400,
    "messages": [{"role": "user", "content": "Summarize this ticket in 3 sentences."}]
  }'

Don't set one generic max_tokens value for your whole app. Tune it per endpoint:

If the model consistently hits the cap and gets cut off mid-sentence, that's a signal to either raise it slightly or restructure the prompt to ask for a more concise answer — not just raise the limit blindly.

2. Control Input Tokens From Conversation History

Output caps don't help if your input keeps growing. In multi-turn chat, every prior message gets resent unless you manage it.

Three practical strategies:

Sliding window — only send the last N messages instead of the full history.

function trimHistory(messages, maxMessages = 10) {
  if (messages.length <= maxMessages) return messages;
  return messages.slice(-maxMessages);
}

Summarize-and-replace — periodically ask Claude to summarize the conversation so far, then replace the old turns with that summary as a single system or user message. This keeps context quality high while shrinking token count.

Truncate large pasted content — if users paste logs, documents, or code, cap the character count server-side before it reaches the prompt, or chunk it and only send the relevant section.

If your workload involves repeating the same large context (a system prompt, a document, instructions) across many requests, caching that content reduces cost further — that's a separate technique worth reading up on if you're hitting this a lot.

3. Enforce Hard Limits Per Key or Per User

Request-level tuning controls cost per call. It doesn't stop a compromised key, a buggy loop, or a single heavy user from running up thousands of calls. You need limits enforced outside the model call itself:

This is where tracking matters as much as limiting. If you can't see token usage broken down by key or user in near real time, you're setting limits blind. This is one of the practical reasons teams put something like SubToAPI in front of their Claude access: every application gets its own sub_live_... key, usage is tracked per key automatically, and you get visibility without building a metering layer yourself. It's not a token-limiting feature in itself, but it gives you the per-key usage data you need to set and enforce limits confidently. See /docs for how key-level metadata is exposed.

4. Catch Runaway Usage Before It Bills You

Add defensive checks around the API call itself:

const MAX_ALLOWED_TOKENS = 2000;

function validateRequest(requestBody) {
  if (requestBody.max_tokens > MAX_ALLOWED_TOKENS) {
    throw new Error("max_tokens exceeds allowed limit");
  }
}

Combine this with server-side logging of usage.input_tokens and usage.output_tokens from every response (both the Anthropic API and SubToAPI return this in the response payload) so you can alert on anomalies — a single request consuming far more tokens than normal is often a sign of a prompt injection, a loop, or a misconfigured client. Streaming responses (/docs/streaming) also let you cut off generation early client-side if output is clearly going off-track, which saves output tokens on bad responses before they finish.

Practical Checklist

None of these require giving up functionality — they just mean the model has fewer unbounded paths to blow through tokens. If you're testing this against a real API quickly, /docs/quickstart walks through a first authenticated request in a few minutes.

Questions

Does setting max_tokens lower cost even if the model doesn't need that many tokens? No — you're only billed for tokens actually generated, not the cap. max_tokens is a ceiling, not a target. It protects you from worst-case runs, not average cost.

Is limiting input tokens or output tokens more important for cost control? It depends on the workload. Chat apps with long histories are usually input-heavy; generation tasks (writing, code) are usually output-heavy. Check your actual usage data per request type before deciding where to optimize first.

Can I set different token limits for different users or API keys? Yes, and you should. Enforce it in your own application logic (per-user quotas in your database) or at the key level if you issue separate keys per customer or team, so limits map to your actual billing or fair-use policy.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →