◉CLAUDE LABJP
●CODE 2.1.322 — Fast mode now works on Vertex in the global, us and eu regions (11/10), falling back to standard speed if refused●FABLE 5.2 — Claude Code 2.1.321 makes Fable 5.2 the default Fable model: 1M context at $8/$40 per Mtok●MANAGED — Self-hosted Claude Managed Agents is out (11/12): you run the whole service yourself●SONNET 4.5 — Retires on the Claude API on 11/30, 17 days left. Migrate to Sonnet 5.5●MCP APPS — Users report local MCP app views no longer showing in Chat after a desktop update●NEW — Cowork or Claude Code First, With No Terminal Experience●CODE 2.1.322 — Fast mode now works on Vertex in the global, us and eu regions (11/10), falling back to standard speed if refused●FABLE 5.2 — Claude Code 2.1.321 makes Fable 5.2 the default Fable model: 1M context at $8/$40 per Mtok●MANAGED — Self-hosted Claude Managed Agents is out (11/12): you run the whole service yourself●SONNET 4.5 — Retires on the Claude API on 11/30, 17 days left. Migrate to Sonnet 5.5●MCP APPS — Users report local MCP app views no longer showing in Chat after a desktop update●NEW — Cowork or Claude Code First, With No Terminal Experience
Articles/API & SDK
⬡ API & SDK/2026-03-28Advanced

Production Voice Agents with Claude API: Latency Budgets, Cost, and Fallbacks

Orchestrating Whisper/Deepgram, Claude API, and TTS into a voice agent that survives production — latency budgets measured on Cloudflare Workers and Cloud Run, per-session cost math, three-tier fallbacks, and barge-in handling.

Claude API145voice agentsspeech-to-texttext-to-speechproduction architecture

✦ Premium Article

The 300ms that broke the conversation

The first time I put a voice agent in front of real users, the replies that had felt snappy in testing sounded noticeably slow on a real phone. The measurement said p95 was 1.8 seconds — only 300ms over budget.

Listeners still felt the pause. They repeated themselves, the repeat produced a duplicate transcript, and the duplicate made the next turn slower. A small overshoot on paper, a broken conversation in practice.

The hard part of voice agents is not model quality. It is how you spend time. Claude API handles the language reasoning; speech recognition and speech synthesis live in separate services, and milliseconds pile up at every seam between them.

What follows is a full stack — Whisper or Deepgram for input, Claude API for reasoning, several TTS engines for output — organized around four decisions: latency budget, cost math, failover, and monitoring. Everything is TypeScript/Node.js, with code you can run as written.


Voice Agent Architecture Overview

A production voice agent system spans multiple integrated layers:

┌─────────────────────────────────────────────────────────────┐
│              Client Layer (Web / Mobile)                    │
└─────────────────────┬───────────────────────────────────────┘
                      │ WebSocket / HTTP
┌─────────────────────▼───────────────────────────────────────┐
│           API Gateway / Auth / Rate Limiting                │
└─────────────────────┬───────────────────────────────────────┘
                      │
    ┌─────────────────┼─────────────────┐
    │                 │                 │
    ▼                 ▼                 ▼
┌─────────┐   ┌─────────────┐   ┌─────────────┐
│ STT     │   │ Response    │   │ TTS Engine  │
│ (Whisper│   │ Generation  │   │ (Multi-     │
│/Deepgram)  │ (Claude API) │   │  Provider)  │
└─────────┘   └─────────────┘   └─────────────┘
                      │
    ┌─────────────────┼─────────────────┐
    │                 │                 │
    ▼                 ▼                 ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│Cache (Redis) │ │ Conversation │ │Analytics &   │
│              │ │ Storage      │ │Logging       │
│              │ │(PostgreSQL)  │ │              │
└──────────────┘ └──────────────┘ └──────────────┘

Core responsibilities of each layer:

  • STT (Speech-to-Text): Whisper for high accuracy and offline capability; Deepgram for low-latency streaming
  • Response Generation: Claude API with streaming support and conversation history
  • TTS (Text-to-Speech): Multi-provider support (Google Cloud, ElevenLabs, Amazon Polly) with failover
  • State Management: Session persistence, conversation history, user context
  • Infrastructure: Caching, rate limiting, monitoring, logging

What follows is each piece in the order I hit trouble with it, starting with speech recognition.


✦

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
✦How I split a 1500ms voice-to-voice latency budget into STT 600ms / Claude Haiku 400ms / TTS 400ms, and compressed real-world p50 to 910ms with Deepgram Streaming
✦Reduced per-session cost from $0.024 to $0.011 across 4 specific decisions, with the Sonnet routing rule that finally worked after Sonnet-judges-itself failed
✦Why Cloudflare Workers cannot host the inference layer, and the Durable Objects + Cloud Run split I run in production with signed JWT session tokens
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-11-09
Does an Undated claude-sonnet-4-5 Escape the November 30 Retirement?
The retirement table lists only the dated Sonnet 4.5 ID. Here is how I read the docs to decide whether the undated alias stops too, and the one grep that catches both.
⬡ API & SDK2026-11-07
Your Key Is Valid but You Get a 400 or 401 — Check the Workspace Header and Browser Calls Before Reissuing
When a Claude API key is valid but requests still fail with 400 or 401, two causes are worth ruling out before you create a new key: a missing workspace ID header and a direct call from the browser. A triage table and a small script you can run are included.
⬡ API & SDK2026-11-05
Three Changes I Made Before Moving to Message Threads, So My Own Copy of the Conversation Stays Mine
What changes when a loop that resends the full history every turn moves to message threads, which entered beta on November 2. How create and continue differ, how to triage a 404 or 400, and where I would not migrate, all based on the official docs.