Skip to content
Writing
NewSecurityArchitectureAI agentsRate LimitingDeliverability

Preventing Infinite Email Loops in Autonomous AI Agents: Circuit Breakers and Token Buckets

When two autonomous email agents start talking to each other, they can trigger an infinite email loop in minutes. Here is how to engineer circuit breakers, token buckets, and idempotency safeguards.

The anatomy of an autonomous email storm: 3 catastrophic triggers

As autonomous AI agents take over customer support, SDR outreach, and automated operations, the risk of recursive email loops has become one of the most critical threats to developer infrastructure.

An infinite email loop occurs when an agent-generated email triggers an automated response, which the agent (or another autonomous bot) interprets as fresh user input, generating yet another reply.

In production environments, email storms typically stem from three distinct architectural failure modes:

  • Auto-Responder Ping-Pong: The AI agent emails a user who has enabled an Out-of-Office (OOO) or vacation auto-responder. The incoming OOO email arrives with subject "Re: Your Request", which the agent treats as a new customer inquiry, generating an immediate apology or follow-up, triggering another OOO response in an unbroken feedback loop.
  • Bot-to-Bot Conversational Traps: An outbound SDR agent reaches out to a sales inquiry address that is monitored by a rival vendor customer service AI agent. The two LLMs begin negotiating, apologizing, or querying each other indefinitely.
  • Blind Retry Storms on Transient Errors: If an agent tool call times out or throws an unhandled exception, poorly configured retry loops (e.g. while (!success)) re-dispatch identical messages every 200ms until memory exhausts.

Real-world blast radius: Cost, reputation, and blacklisting

The consequences of an uncontrolled agent loop extend far beyond minor spam inconvenience:

Impact VectorUnprotected Agent LoopSadaSend Protected Architecture
Outbound VolumeThousands of duplicate emails in minutesHard capped at per-key hourly velocity limit
LLM Inference Cost$200 – $1,200 in recursive token generationHalted on 3rd duplicate attempt
IP ReputationImmediate Spamhaus / Barracuda blocklistingDomain reputation protected by edge refusal
Customer Inbox ImpactRecipient inbox flooded with duplicate notificationsMax 1 message delivered per conversation thread
Gateway RecoveryRequires manual server kill and DB patchAutomatic 429 backoff with circuit breaker trip

Defense Layer 1: Cryptographic Idempotency Keys

The first line of defense against agent retry loops is end-to-end cryptographic idempotency. Every outbound email request generated by an agent must include a deterministic Idempotency-Key header.

Generate the idempotency key by hashing the agent session ID, recipient address, and discussion topic:

TYPESCRIPT
import { createHash } from 'node:crypto';

export function generateEmailIdempotencyKey(agentId: string, recipient: string, threadId: string): string {
  // Deterministic hash prevents duplicate sends even if the agent retries
  return createHash('sha256')
    .update(`${agentId}:${recipient}:${threadId}`)
    .digest('hex');
}

// Usage in agent dispatch:
const idempotencyKey = generateEmailIdempotencyKey('support_bot_v3', 'alex@customer.com', 'ticket_882');
const res = await fetch('https://api.sadasend.com/emails', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.SADASEND_API_KEY}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': idempotencyKey,
  },
  body: JSON.stringify({ to: 'alex@customer.com', subject: 'Ticket #882 Resolved', text: 'All set!' }),
});

Defense Layer 2: Distributed Sliding Window Token Buckets

Never rely solely on client-side memory counters, which disappear when serverless workers scale down. Implement a distributed sliding window rate limiter in Redis to track dispatches per (agent, recipient) pair across all cluster nodes:

TYPESCRIPT
import Redis from 'ioredis';
const redis = new Redis(process.env.REDIS_URL!);

export async function enforceLoopGuard(agentId: string, recipient: string, maxPerHour = 3): Promise<boolean> {
  const now = Date.now();
  const windowStart = now - 3600 * 1000; // 1 hour ago
  const key = `loopguard:${agentId}:${recipient}`;

  // Use Redis multi transaction for atomic sliding window
  const pipeline = redis.pipeline();
  pipeline.zremrangebyscore(key, '-inf', windowStart); // Evict older timestamps
  pipeline.zadd(key, now, `${now}-${Math.random()}`);   // Record current send
  pipeline.zcard(key);                                 // Count sends in last hour
  pipeline.expire(key, 3600);

  const results = await pipeline.exec();
  const currentCount = results?.[2]?.[1] as number;

  if (currentCount > maxPerHour) {
    console.warn(`[CIRCUIT_BREAKER_TRIPPED] Agent ${agentId} hit limit for recipient ${recipient}`);
    return false; // Trip circuit breaker
  }
  return true;
}

Defense Layer 3: Loop-Breaking MIME Headers (RFC 3834 & RFC 2076)

To prevent autoresponders and external mail daemons from replying to your agent, every automated email must carry standard automated header flags:

  • Auto-Submitted: auto-generated (RFC 3834): Explicitly tells compliant email systems (like Outlook and Gmail) that an automatic response MUST NOT be generated.
  • X-Auto-Response-Suppress: All: Microsoft Exchange proprietary header instructing mail servers not to send OOO, auto-reply, or NDR notices back to the sender.
  • Thread Hop Counting: Increment an X-Thread-Hop-Count integer header in each reply. If the hop count exceeds 3 without human intervention, terminate the thread automatically.
JSON
{
  "headers": {
    "Auto-Submitted": "auto-generated",
    "Precedence": "bulk",
    "X-Auto-Response-Suppress": "All",
    "X-Agent-Framework": "LangGraph/SadaSend",
    "X-Thread-Hop-Count": "1"
  }
}

Defense Layer 4: Server-Enforced Gateway Circuit Breakers in SadaSend

Application-level code guards can fail if an engineer forgets to import a Redis check or if a developer pushes buggy agent code. For this reason, SadaSend enforces hardware-level circuit breakers at the API gateway layer:

1. Hourly Velocity Limits: Configure your agent API key with a hard ceiling (e.g. 50 emails/hour). If an agent enters an uncontrolled loop, the gateway cuts execution at the 50th request, returning HTTP 429 Too Many Requests.

2. Recipient Domain Allowlists: Bind the agent key strictly to authorized staging domains (e.g. @yourcompany.com). Even if the agent loops, it is physically prohibited from contacting external customer inboxes.

3. Instant Dashboard Kill Switch: In the event of an anomalous surge, human operators can revoke or pause an agent API key with a single click, instantly dropping in-flight requests in under 2ms.

Free plan

Building AI agents that send email?

Scoped API keys, per-key recipient allowlists, approval mode and a hosted MCP server with ten tools — on the free plan, without a card.