CLAUDE LABJP
SONNET — Claude Sonnet 5 is now the default model in Claude Code, with a native 1M-token context window and introductory pricing through August 31CHROME — Claude in Chrome reaches general availability, letting you hand browser work directly to ClaudeCOWORK — Cowork expands to mobile and web so sessions and files follow you across devices, starting in beta for Max usersDATAVIZ — Claude Code adds a /dataviz skill offering guidance for designing charts and dashboardsAGENTS — Agent workflows gain background notifications, draft PR handoff, and improved failoverENTERPRISE — Claude Enterprise adds richer admin analytics, model-level entitlements, and spend alertsSONNET — Claude Sonnet 5 is now the default model in Claude Code, with a native 1M-token context window and introductory pricing through August 31CHROME — Claude in Chrome reaches general availability, letting you hand browser work directly to ClaudeCOWORK — Cowork expands to mobile and web so sessions and files follow you across devices, starting in beta for Max usersDATAVIZ — Claude Code adds a /dataviz skill offering guidance for designing charts and dashboardsAGENTS — Agent workflows gain background notifications, draft PR handoff, and improved failoverENTERPRISE — Claude Enterprise adds richer admin analytics, model-level entitlements, and spend alerts
Articles/API & SDK
API & SDK/2026-07-12Advanced

A Long Non-Streaming Response Was Billed Twice Past the 10-Minute Wall: Redesigning the SDK's Default Timeout and Retries

The Anthropic SDK's default 10-minute timeout and two automatic retries can silently re-run a long non-streaming response and bill you twice. Here is how the trap works, and how to close it with streaming, explicit timeout/max_retries, and a small local ledger — with measured before/after numbers.

Claude44API26SDK4timeout8cost-optimization26

Premium Article

One week, the cost of my nightly batch crept up for no reason I could see. The number of summaries generated was the same as the week before, the number of articles processed was the same, yet the api-sdk line on the bill kept climbing. It took me half a day to find the culprit, and it was hiding somewhere I never thought to look.

I had a summarization task with max_tokens raised to 16,000, and I had written it the plain way: call client.messages.create(...), take the text back. During busy hours, though, that generation occasionally took nine to eleven minutes. And the Anthropic SDK's default request timeout is exactly ten minutes.

Cross that line by a single second and the SDK's read timeout fires. The SDK treats it as a transient failure and, under its default retry policy (up to two attempts), sends the same request again. Here is the trap: the first request is still generating on the server, and if it finishes, you are billed for the output tokens it produced. Then the retry runs as a second, independent request and bills you again. I receive one response, but I pay for two. That was the quiet cost creep.

What follows is a breakdown of that mechanism down to the SDK's behavior, and the three design changes that stop the double charge at the root — with the code I actually put into my nightly batch. If you run unattended jobs across a few sites as an indie developer, this is exactly the kind of spend you can keep paying without ever noticing.

Misreading the defaults bites hardest when nobody is watching

Start with the two defaults the SDK carries silently. In the Anthropic Python SDK, both of these are in effect the moment you construct a client.

SettingDefaultWhat it means for unattended jobs
timeout10 minutes (600s)A long generation that exceeds 10 minutes triggers a read timeout
max_retries2On transient errors, including timeouts, the same request is resent up to twice

Automatic retries are a good feature in general. For errors like 429 (rate limit), 5xx, or a dropped connection — the "just send it again and it will go through" kind — exponential backoff with jitter works well. The problem is that a read timeout is not that kind of error.

A timeout is only a signal that the client gave up waiting. The server has no idea about your side and keeps generating. Messages API billing is charged against the output tokens that get produced. So the first request, even if you never receive it, is billed once it completes. Layer a retry on top and you pay twice for the same generation.

The SDK is aware of this danger. For a non-streaming request with a large max_tokens, it emits a warning that the request may exceed ten minutes and recommends streaming instead. I am a little embarrassed to admit I had been scrolling past that warning in my logs for a long time. The warning was right.

Why timeout retries specifically are the dangerous ones

Separating the safe retries from the dangerous ones is where the design clicks into place.

Failure typeServer-side stateRetry safety
429 / 529 (overloaded)Request rejected, not processedSafe. A resend is billed once
Connection failureRequest never reached the serverSafe. Nothing was generated yet
Read timeoutRequest in flight, likely still generatingDangerous. Double-billed if it completes

The key fact is that a single Messages API request has no idempotency key — no Stripe-style mechanism that folds a re-sent request into one. Unless we track "this is a resend" ourselves, the two requests are entirely separate as far as the server is concerned. That is precisely why retries that involve a timeout must not be delegated to the SDK.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
A breakdown of how the SDK's default 10-minute timeout plus two automatic retries quietly re-run a long non-streaming request and double the bill
Working code that stops the double charge with streaming, explicit timeout and max_retries, and an idempotent local ledger
The exact settings that took duplicate-billing from roughly 2% to zero in a nightly batch, plus how to verify it
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

API & SDK2026-06-22
Drop Your Static Claude API Keys: Moving CI and Production to Keyless Auth with Workload Identity Federation
Workload Identity Federation is now generally available on the Claude Platform. This guide walks through replacing long-lived sk-ant- keys with short-lived OIDC tokens, including keyless GitHub Actions auth, the migration steps, and token refresh design.
API & SDK2026-06-22
Putting a Ceiling on the pause_turn Loop: Running Long Server Tools Safely Unattended
A production design for continuing pause_turn safely in unattended runs, where long server tools like web_search and code execution are involved. Covers branching all four stop_reason values in one loop, capping continuations and wall-clock time, and accumulating usage across paused segments.
API & SDK2026-06-21
Connecting Managed Agents to Services You Don't Want to Expose: MCP Tunnel Design
How to connect Claude Managed Agents to an internal MCP server that is never exposed to the public internet. We cover the MCP tunnel, self-hosted sandboxes, authorization boundaries, and graceful degradation when things break.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →