콘텐츠로 건너뛰기

음성 AI 레이트 리미팅: 동시성, 대기열, 429 에러

게시일
최종 업데이트

듣기이 글 오디오로 듣기

대부분의 팀은 다른 API를 다루듯 음성용 AI 속도 제한을 적용합니다. 분당 요청 수를 제한하고, 서버가 거부하면 재시도한 뒤 넘어갑니다. 하지만 ElevenLabs 워크로드에서는 첫 번째 트래픽 급증부터 이 방식이 무너집니다. 실제로 부딪히는 한도는 요청 수가 아니라 동시성 때문입니다.

이 가이드에서는 동시성이 실제 제약 조건인 이유를 설명하고, 한도 내에서 운영할 수 있는 클라이언트 측 패턴을 살펴봅니다. 제한된 동시성 풀과 유연한 429 처리부터 멀티 테넌트 공정성, 토큰 버킷과 리키 버킷까지 구현 가능한 실용적인 시스템을 소개합니다. 각 패턴에는 필요에 맞게 조정할 수 있는 작동하는 TypeScript 구현을 함께 제공합니다.

음성 에이전트를 구축하고 내레이션 파이프라인이나 모델 기반의 다른 프로덕션 시스템을 확장하려는 경우, 이 플레이북이 도움이 됩니다.

요약

  • 음성용 AI 속도 제한은 분당 요청 수 계산이 아니라 동시성 제어입니다.
  • 속도 제한 한도에 도달해도 트래픽이 즉시 거부되지는 않습니다. 대신 요청은 약 50ms의 지연을 추가하는 우선순위 큐에 들어갑니다.
  • 큐잉 이후에도 용량을 초과하면 HTTP 429 오류가 발생합니다.
  • WebSocket은 활성 생성 시간만 한도에 반영되므로 실질적인 용량을 크게 늘립니다.
  • 멀티 테넌트 시스템에는 테넌트별 버킷, 가중 공정 큐잉, 예약된 헤드룸, 격리를 위한 키 간 샤딩 등 추가적인 공정성 계층이 필요합니다.
  • current-concurrent-requests와 maximum-concurrent-requests라는 두 응답 헤더로 AI 속도 제한 현황을 파악할 수 있습니다.

한도가 분당 요청 수가 아닌 동시성인 이유

동시성은 같은 순간에 처리 중인 요청 수입니다. 분당 요청 수는 일정 시간 구간의 처리량입니다. 이 차이를 이해하는 것이 중요한 이유는 한도 내에 머무르게 해 주는 제어 수단이 달라지기 때문입니다.

ElevenLabs 모델 중 하나를 사용할 때 서버 워크로드는 동시 사용자 수에 따라 증가합니다. 오디오 생성은 생성이 지속되는 동안 슬롯을 점유하며, 그 시간은 입력 길이, 모델, 부하에 따라 달라집니다.

분당 요청 수 제한만으로는 지금 몇 개의 슬롯이 점유되어 있는지 알 수 없습니다. 서버가 측정하는 것은 바로 이 수치뿐입니다.

플랜 및 모델 계열별 한도

동시성 예산은 하나의 숫자가 아닙니다. 동시성 한도는 플랜과 모델 계열에 따라 다릅니다. 예를 들어 음성 텍스트 변환텍스트 음성 변환보다 높은 한도가 적용됩니다. 전사 요청은 보통 지속 시간이 더 짧아 시스템에서 더 많은 요청을 동시에 처리할 수 있기 때문입니다.

Multilingual v2
Free
2
Starter
3
Creator
5
Pro
10
Scale
15
Business
15
Enterprise
Elevated
Flash
Free
4
Starter
6
Creator
10
Pro
20
Scale
30
Business
30
Enterprise
Elevated
STT
Free
8
Starter
12
Creator
20
Pro
40
Scale
60
Business
60
Enterprise
Elevated
Realtime STT
Free
6
Starter
9
Creator
15
Pro
30
Scale
45
Business
45
Enterprise
Elevated
Queue weight
Free
3
Starter
4
Creator
5
Pro
5
Scale
5
Business
5
Enterprise
6

한도는 모델 계열별로 적용됩니다. 에이전트에 Flash를, 내레이션에 Multilingual v2를 사용한다면 두 개의 별도 예산을 동시에 사용하게 됩니다. 현재 플랜별 수치와 동시성 관련 내용은 모델 페이지에서 확인할 수 있습니다.

동시성 한도에 도달하면 어떻게 되나요?

동시성 한도에 도달해도 트래픽은 즉시 거부되지 않습니다. 시스템은 우선순위 큐를 통해 자연스럽게 성능을 저하시키며, 속도 제한의 전체 용량을 계속 초과할 때만 완전 거부로 전환합니다.

한도 미만에서는 요청이 즉시 실행됩니다. 한도에 도달하면 이후 요청은 플랜의 우선순위 수준에 따라 정렬된 큐에 들어갑니다. 큐는 일반적으로 약 50ms의 지연만 추가하므로, 짧은 초과는 대부분 사용자에게 거의 보이지 않습니다.

큐잉 후에도 시스템 용량을 초과하면 HTTP 429를 받게 됩니다. 이는 즉시 재시도하지 말고 속도를 늦추라는 신호입니다. 표의 우선순위 수준은 대기 중인 요청이 다른 트래픽과 비교해 어떤 순서로 처리되는지를 결정하며, 상위 플랜일수록 큐를 더 빨리 통과합니다.

HTTP와 WebSocket: 각각 한도에 반영되는 방식

선택하는 전송 방식은 속도 제한과 예산에 직접 영향을 줍니다. 동일한 대화 요청도 HTTP로 실행하는지 WebSocket으로 실행하는지에 따라 동시성 예산을 크게 다르게 소비할 수 있습니다.

HTTP에서는 각 요청이 전체 지속 시간 동안 동시성 한도에 개별적으로 반영됩니다. WebSocket에서는 모델이 오디오를 활발히 생성하는 시간만 반영됩니다. 열려 있지만 유휴 상태인 WebSocket은 대부분 계산되지 않습니다.

음성 에이전트 대화에는 아무도 말하지 않고 모델도 아무것도 생성하지 않는 긴 구간이 있습니다. HTTP에서는 매 턴마다 요청이 지속되는 동안 슬롯을 점유합니다. WebSocket에서는 활성 생성 중인 밀리초 단위의 시간에만 슬롯이 소모되므로, 하나의 동시성 슬롯을 여러 대화가 시간 분할해 사용할 수 있습니다.

실시간 TTS WebSocket 가이드에서 프로토콜 세부 정보를 확인하세요. 인터랙티브 트래픽에는 WebSocket이 적합한 기본 선택입니다.

동시성 약 5개로 방송 약 100개를 지원할 수 있는 이유

재생 시간을 고려하기 전까지 동시성의 계산 방식은 직관적이지 않습니다. 생성은 재생보다 훨씬 빠르며, 슬롯은 오디오가 생성되는 동안에만 실제로 점유됩니다. 이 차이 덕분에 작은 예산으로도 많은 청취자에게 서비스를 제공할 수 있습니다.

생성에 몇 분의 1초가 걸리는 요청은 몇 초 분량의 오디오를 만들어 냅니다. 청취자는 그 오디오를 재생하는 데 시간을 쓰며, 재생 중에는 슬롯이 해제되어 다른 청취자가 사용할 수 있습니다.

경험칙상 동시성 한도 5개로 약 100개의 동시 오디오 방송을 지원할 수 있습니다. 정확한 수치는 음성, 말하는 속도, 발화 사이의 침묵 시간에 따라 달라집니다.

현재 상황을 알려 주는 헤더

한도 대비 현재 위치를 추정할 필요가 없습니다. 모든 응답에는 단순한 추정 대신 남은 여유 용량을 측정하는 데 사용할 수 있는 두 가지 수치가 포함됩니다.

다음 두 헤더를 확인하세요:

  • current-concurrent-requests: 현재 처리 중인 요청 수
  • maximum-concurrent-requests: 해당 모델 계열의 한도

이 헤더들을 함께 사용하면 실시간으로 현재 사용량과 이용 가능한 용량을 파악할 수 있습니다. AI 속도 제한에 도달하기 전까지 추측에 의존할 필요가 없습니다.

AI 속도 제한을 위한 클라이언트 측 전략

거의 모든 AI 속도 제한 시나리오를 다루는 4가지 기본 요소가 있습니다:

  • 토큰 버킷: 토큰이 있으면 요청을 진행시킵니다. 시간이 지나며 용량이 보충되므로 속도 제한에 걸리지 않고 짧은 버스트를 처리할 수 있습니다.
  • 리키 버킷: 들어오는 트래픽을 고정된 출력 속도로 평준화하여 갑작스러운 급증이 다운스트림 시스템을 압도하지 않도록 합니다.
  • 제한된 동시성 풀: 동시에 활성화할 수 있는 총 요청 수를 제한하므로 동시 요청 한도를 절대 초과하지 않습니다.
  • 전체 지터를 적용한 지수 백오프: 실패한 요청 사이의 대기 시간을 점진적으로 늘려 모든 클라이언트가 한꺼번에 재시도하는 일을 방지합니다.

아래 섹션에서는 동시성 한도에 가장 직접적으로 대응하는 요소부터 시작해 하나씩 구축하는 방법을 보여 줍니다.

아래의 모든 코드 스니펫은 한 번만 초기화한 단일 클라이언트를 가정합니다:

import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";

const elevenlabs = new ElevenLabsClient({ apiKey: process.env.ELEVENLABS_API_KEY });

제한된 동시성: 한도에 대응하는 기본 요소

서버는 동시성을 측정하므로, 가장 직접적인 클라이언트 제어 방법은 한 번에 처리 중인 요청 수를 제한하는 워커 풀입니다. 우선순위 큐와 지터를 위한 여유를 남기도록 플랜 한도보다 약간 낮게 제한을 설정하세요.

async function pool<T, R>(
  items: T[],
  maxInFlight: number,
  worker: (item: T) => Promise<R>,
): Promise<R[]> {
  const results: R[] = new Array(items.length);
  let next = 0;

  async function run(): Promise<void> {
    while (next < items.length) {
      const i = next++;
      results[i] = await worker(items[i]); // never more than maxInFlight of these run at once
    }
  }

  await Promise.all(
    Array.from({ length: Math.min(maxInFlight, items.length) }, run),
  );
  return results;
}

async function synthesize(text: string): Promise<Buffer> {
  const stream = await elevenlabs.textToSpeech.stream("JBFqnCBsd6RMkjVDRZzb", {
    text,
    modelId: "eleven_flash_v2_5",
    outputFormat: "mp3_44100_128",
  });
  const chunks: Buffer[] = [];
  for await (const chunk of stream) chunks.push(Buffer.from(chunk));
  return Buffer.concat(chunks);
}

// Plan Flash limit is, say, 10. Stay under it.
const texts = Array.from({ length: 50 }, (_, i) => `Sentence number ${i}.`);
const audio = await pool(texts, 8, synthesize); // never more than 8 in flight

토큰 버킷: 버스트 허용, 평균 제한

토큰 버킷은 최대 capacity개의 토큰을 보유하고 초당 refillRate개의 토큰으로 보충됩니다. 각 요청은 토큰 하나를 소비하므로, 장기 평균 속도는 제한하면서 버킷 크기만큼의 짧은 버스트는 허용합니다.

작업 큐가 갑자기 도착했을 때 모든 요청을 한꺼번에 실행해 동시성이 급증하지 않도록 평준화하는 데 적합한 도구입니다.

class TokenBucket {
  private tokens: number;
  private updated = performance.now();

  constructor(private capacity: number, private refillPerSec: number) {
    this.tokens = capacity;
  }

  private refill(): void {
    const now = performance.now();
    const elapsed = (now - this.updated) / 1000;
    this.tokens = Math.min(this.capacity, this.tokens + elapsed * this.refillPerSec);
    this.updated = now;
  }

  tryAcquire(cost = 1): boolean {
    this.refill();
    if (this.tokens >= cost) {
      this.tokens -= cost;
      return true;
    }
    return false;
  }

  timeUntil(cost = 1): number {
    this.refill();
    return this.tokens >= cost ? 0 : ((cost - this.tokens) / this.refillPerSec) * 1000;
  }
}

리키 버킷: 일정한 처리 속도 강제

경우에 따라 버스트를 전혀 허용하고 싶지 않을 수 있습니다. 리키 버킷은 입력이 얼마나 급격하게 들어오든 상관없이 고정된 일정한 속도로 작업을 받아들입니다. 간헐적인 급증보다 매끄럽고 예측 가능한 부하를 선호하는 다운스트림 시스템에 더 적합합니다.

예를 들어 다른 서비스와 공유하는 작은 동시성 예산보다 의도적으로 훨씬 낮은 수준을 유지할 때 유용합니다.

class LeakyBucket {
  private next = performance.now();
  constructor(private intervalMs: number) {} // admit at most one item per intervalMs

  async acquire(): Promise<void> {
    const now = performance.now();
    const wait = Math.max(0, this.next - now);
    this.next = Math.max(now, this.next) + this.intervalMs;
    if (wait > 0) await new Promise((r) => setTimeout(r, wait));
  }
}

전체 지터를 적용한 지수 백오프

재시도 가능한 상태로 요청이 실패했을 때 즉시 재시도하면 상황이 악화됩니다. 백오프는 재시도 간격을 벌려 주고, 전체 지터는 전체 구간에서 각 지연 시간을 무작위화합니다. 이를 통해 많은 클라이언트가 같은 타이밍에 재시도해 실패를 일으킨 동일한 급증을 재현하는 일을 막습니다.

아래 스니펫은 실패한 상태와 Retry-After 값을 담는 작은 클래스인 RetryableError를 참조합니다. 이 클래스는 아래의 유연한 429 처리 섹션에서 정의합니다.

async function withBackoff<T>(
  call: () => Promise<T>,
  opts: { maxAttempts?: number; baseMs?: number; capMs?: number } = {},
): Promise<T> {
  const { maxAttempts = 5, baseMs = 500, capMs = 20_000 } = opts;
  let attempt = 0;
  for (;;) {
    try {
      return await call();
    } catch (e) {
      if (!(e instanceof RetryableError) || ++attempt >= maxAttempts) throw e;
      // honor Retry-After if present; otherwise capped exponential growth with full jitter
      const delay =
        e.retryAfterMs ?? Math.random() * Math.min(capMs, baseMs * 2 ** attempt);
      await new Promise((r) => setTimeout(r, delay));
    }
  }
}

유연한 429 처리: 한도에 도달했을 때 할 일

429는 우선순위 큐를 거친 뒤에도 용량을 초과했다는 뜻입니다. 따라서 더 강하게 재시도하는 대신 속도를 늦춰야 합니다. 이를 잘 처리하는 방법은 다음 4가지 전략으로 정리할 수 있습니다:

  • 감지
  • Retry-After 준수
  • 백프레셔 노출
  • 서킷 브레이커로 재시도 폭주 방지

각 항목을 자세히 살펴보겠습니다.

첫 번째는 감지입니다. HTTP 429와 일시적인 500, 502, 503, 504는 재시도 가능한 것으로 처리하고, 400, 401, 403, 422는 재시도 불가능한 것으로 처리하세요. 잘못된 형식이거나 인증되지 않은 요청은 재시도해도 성공하지 않으며 슬롯만 낭비합니다.

두 번째는 Retry-After 준수입니다. 응답에 이 헤더가 있으면 자체 지연 시간을 계산하지 말고 정확히 따르세요. 서버는 언제 용량이 확보될 것으로 예상하는지 알려 주며, 지수 공식보다 더 정확히 알고 있습니다. 헤더가 없을 때만 지터를 적용한 백오프로 대체하세요.

class RetryableError extends Error {
  constructor(public status: number, public retryAfterMs?: number) {
    super(`retryable ${status}`);
  }
}

function classify(resp: Response): void {
  if ([429, 500, 502, 503, 504].includes(resp.status)) {
    const ra = resp.headers.get("retry-after");
    throw new RetryableError(resp.status, ra ? Number(ra) * 1000 : undefined);
  }
  if (!resp.ok) throw new Error(`non-retryable ${resp.status}`);
}

세 번째는 백프레셔 노출입니다. 재시도가 보이지 않게 쌓이도록 두지 마세요. 큐 깊이나 측정한 헤드룸으로 보아 새 요청을 곧 처리할 수 없다면, 처리할 수 없는 작업을 받아들이는 대신 호출자에게 명확한 신호를 보내고 엣지에서 거부하세요.

네 번째는 서킷 브레이커로 재시도 폭주를 방지하는 것입니다. 실패가 임계값을 넘으면 실패할 것으로 예상되는 요청을 보내는 대신 서킷을 열고 쿨다운 기간 동안 빠르게 실패 처리하세요. 기간이 지난 뒤에는 몇 개의 프로브 요청을 보내고, 성공하면 서킷을 닫으세요.

class CircuitBreaker {
  private failures = 0;
  private openedAt: number | null = null;
  constructor(private threshold = 5, private cooldownMs = 10_000) {}

  allow(): boolean {
    if (this.openedAt === null) return true;
    if (performance.now() - this.openedAt >= this.cooldownMs) {
      this.openedAt = null; // half-open: allow a probe
      this.failures = 0;
      return true;
    }
    return false;
  }

  record(ok: boolean): void {
    if (ok) {
      this.failures = 0;
      this.openedAt = null;
    } else if (++this.failures >= this.threshold) {
      this.openedAt = performance.now();
    }
  }
}

AI 속도 제한을 위한 멀티 테넌트 할당량 패턴

지금까지는 단일 예산을 사용하는 단일 애플리케이션을 가정했습니다. ElevenLabs 기반 SaaS를 구축하면 문제의 양상이 달라집니다. 동시성 예산은 모든 고객이 공유하며, 한 테넌트가 배치 작업을 실행한다고 해서 다른 모든 테넌트의 실시간 트래픽이 굶주려서는 안 됩니다. 테넌트와 단일 업스트림 한도 사이에 공정성 계층이 필요합니다.

기본은 테넌트별 토큰 버킷입니다. 각 테넌트에 권한에 맞는 크기의 버킷을 제공하고, 테넌트 버킷과 전역 리미터가 모두 허용할 때만 요청을 받아들이세요.

class MultiTenantAdmission {
  private tenantBuckets = new Map<string, TokenBucket>();
  constructor(private globalMaxInFlight: number) {}

  private bucket(tenant: string): TokenBucket {
    let b = this.tenantBuckets.get(tenant);
    if (!b) {
      // Each tenant: burst of 5, sustained 2 starts/sec. Tune per tier.
      b = new TokenBucket(5, 2);
      this.tenantBuckets.set(tenant, b);
    }
    return b;
  }

  async run<R>(tenant: string, work: () => Promise<R>): Promise<R> {
    const b = this.bucket(tenant);
    if (!b.tryAcquire()) {
      throw new RetryableError(429, b.timeUntil());
    }
    // ... then admit through the global limiter (e.g. the bounded pool above)
    return work();
  }
}

버킷은 어느 한 테넌트가 과도하게 사용하지 못하도록 하지만, 테넌트가 전역 리미터를 두고 경쟁할 때 누가 우선인지 결정하지는 못합니다. 이를 위해 가중 공정 큐잉을 사용하세요.

한 테넌트의 버스트가 슬롯을 독점하게 되는 선착순 방식을 사용하지 마세요. 테넌트별 큐를 유지하고 각 테넌트의 가중치에 비례해 디스패치하면 유료 테넌트는 무료 테넌트보다 경합 중인 용량을 더 많이 확보할 수 있습니다.

공정성에 더해 헤드룸을 예약하세요. 일반 트래픽이 동시성 한도의 100%를 소비하도록 두지 마세요. 지연 시간에 민감한 인터랙티브 요청과 우선순위 큐를 위한 버퍼로 15~20% 정도를 남겨 두세요.

단일 예산 내 공정성만으로 부족해지면 워크스페이스나 키 전반으로 샤딩하세요. 아무리 공정하게 나누더라도 결국 하나의 동시성 예산이 병목이 됩니다.

그 시점에는 워크로드를 각자의 예산을 가진 별도 워크스페이스 또는 API 키로 분리하세요. 예를 들어 하나의 키는 실시간 에이전트 트래픽용으로, 다른 하나는 백그라운드 내레이션용으로 사용하면 내레이션 백로그가 에이전트 용량에 영향을 주지 못합니다.

워크스페이스에서는 범위 제한, 크레딧 할당량, 키별 제어도 적용할 수 있으며, 자세한 내용은 인증 문서에서 확인할 수 있습니다.

동시성 사용률 모니터링

측정 없이는 어떤 것도 조정할 수 없습니다. 측정하지 않는 헤드룸은 관리할 수 없습니다. 모든 응답에서 모델 계열 태그와 함께 current-concurrent-requests 및 maximum-concurrent-requests를 기록하고, 사용률을 게이지로 내보내세요.

function recordHeadroom(resp: Response, metrics: Metrics): void {
  const cur = Number(resp.headers.get("current-concurrent-requests"));
  const max = Number(resp.headers.get("maximum-concurrent-requests"));
  if (Number.isFinite(cur) && Number.isFinite(max)) {
    metrics.gauge("el.concurrency.current", cur);
    metrics.gauge("el.concurrency.max", max);
    if (max > 0) metrics.gauge("el.concurrency.utilization", cur / max);
  }
}

추적할 4가지 신호:

  • 사용률(현재 / 최대).
  • 전체 요청 대비 429 비율.
  • 재시도 깊이, 즉 논리적 요청당 시도 횟수.
  • 모델 추론 수치가 아닌 애플리케이션에서 측정한 첫 오디오까지의 시간(Time-to-first-audio). TTFA에 포함되는 항목은 지연 시간 이해 가이드를 참고하세요.

건강한 시스템은 사용률을 포화 상태보다 충분히 낮게 유지하고, 429는 가끔 발생하는 버스트에서만 보입니다. 이러한 신호를 모니터링하면 장애 문제가 되기 훨씬 전에 속도 제한 압박을 파악할 수 있습니다.

클라이언트 측 속도 제한을 넘어 확장해야 할 때

클라이언트 측 패턴은 많은 일을 처리할 수 있지만, 결국 안정 상태의 수요가 이를 넘어설 수 있습니다. 그때는 비용과 노력 모두에 도움이 되는 변경을 적용할 시점입니다.

다음 각 단계는 추가 용량을 확보하는 데 도움이 됩니다.

인터랙티브 트래픽은 먼저 HTTP에서 WebSocket으로 전환하세요. 에이전트나 실시간 사용 사례가 HTTP에서 실행 중이라면 WebSocket으로 옮겨 활성 생성 시간만 반영되도록 계산 방식을 바꿀 수 있습니다. 대화형 워크로드에서는 유휴 대화 시간이 더 이상 슬롯을 소비하지 않으므로, 플랜을 바꾸지 않고도 실질적인 용량이 크게 늘어나는 경우가 많습니다.

버스트는 급격하지만 평균 부하는 예산에 맞는다면, 토큰 버킷이나 리키 버킷에 제한된 풀을 결합해 피크를 평균 수준으로 평준화할 수 있습니다.

그다음 적합한 모델을 선택하세요. 생성 속도가 빠를수록 각 슬롯의 점유 시간이 줄어들어 고정된 동시성 한도가 지원할 수 있는 방송 수가 늘어납니다. Eleven Flash v2.5는 실시간 작업을 위한 최저 지연 시간 옵션이며, 즉시 음성 복제 또는 기본 음성과 함께 사용하면 Professional Voice Clone의 생성당 오버헤드를 피할 수 있습니다.

그 후에야 플랜 업그레이드를 고려하세요. 클라이언트 동작을 잘 최적화한 뒤에도 안정 상태 수요가 실제로 예산을 초과한다면, 상위 플랜은 모델별 동시성 한도와 큐 우선순위를 모두 높여 줍니다. API 가격 페이지에서 티어를 비교하세요.

공개된 수준을 넘어서는 한도가 필요하다면 엔터프라이즈 플랜에서 더 높은 맞춤형 동시성 한도와 가장 높은 큐 우선순위를 제공합니다. 엔터프라이즈 프리뷰의 IP 허용 목록, 데이터 미보존 모드처럼 적합한 사용 사례를 위한 추가 제어 기능도 제공됩니다. 한도 상향은 계정 관리자에게 문의하세요.

AI 속도 제한에서 기억할 핵심 정리

핵심적인 실수는 음성 AI 속도 제한을 요청 수 계산으로 다루는 것입니다. 여기서 다루는 모든 내용은 동시성 제어에 관한 것입니다. 성공 여부를 결정하는 수치는 같은 순간에 오디오를 생성하는 요청 수와 각 요청이 슬롯을 점유하는 시간입니다.

이 사실을 중심으로 클라이언트를 구축하세요.

제한된 풀로 처리 중인 요청을 제한하고, 토큰 버킷 또는 리키 버킷으로 요청 수락을 조절하며, 제한된 지수 백오프와 전체 지터로 재시도하세요. Retry-After를 준수하고, 재시도 폭주가 형성되기 전에 서킷을 차단하세요.

멀티 테넌트 시스템에는 테넌트별 버킷, 가중 공정성, 예약된 헤드룸, 격리를 위한 샤딩을 추가하세요. current-concurrent-requests와 maximum-concurrent-requests 헤더를 관찰하고 실패가 아니라 사용률 추세에 대해 알림을 설정하세요.

정말로 더 많은 용량이 필요하다면 순서대로 진행하세요. 먼저 WebSocket과 더 나은 클라이언트 동작을 적용하고, 그다음 적합한 모델을 선택한 후 플랜을 업그레이드하고, 마지막으로 엔터프라이즈 한도를 고려하세요.

ElevenAPI로 음성 애플리케이션 구축

프로덕션급 AI 속도 제한은 적절한 전송 방식, 적절한 모델, 그리고 현재 상황을 정확히 알려 주는 헤더에서 시작됩니다.

ElevenAPI는 Eleven Flash v2.5와 같은 저지연 모델, 실시간 WebSocket 스트리밍, 음성 텍스트 변환텍스트 음성 변환 API와 함께, 한도 내에서 확장 가능한 음성 에이전트를 구축할 수 있도록 응답별 동시성 헤더를 제공합니다.

이 글의 AI 속도 제한 전략과 함께 사용하면, 부하가 있는 상황에서도 예측 가능한 성능을 유지하면서 반응성 높은 음성 경험을 제공할 수 있습니다.

ElevenAPI에서 전체 모델 라인업의 실제 동작을 살펴보거나, 계정을 만들어 지금 바로 ElevenLabs로 개발을 시작하세요.

AI 속도 제한 FAQ

유사한 기사

최고 품질의 AI 오디오로 창작하세요