본문 바로가기

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

게시일

듣기이 기사 오디오로 듣기

대부분의 팀은 음성 AI 레이트 리미팅을 다른 API와 마찬가지로 처리합니다. 분당 요청 수를 제한하고, 서버에서 거부하면 재시도하며, 그 이상은 신경 쓰지 않습니다. 하지만 ElevenLabs에서 워크로드를 처리할 때는 첫 트래픽 폭주에서 바로 이 방식이 무너집니다. 실제로 제한에 걸리는 것은 요청 수가 아니라 동시성입니다.

이 가이드에서는 왜 동시성이 진짜 제약인지 설명하고, 클라이언트에서 동시성 내로 유지하는 다양한 패턴을 소개합니다. 제한된 동시성 풀, 429 에러를 부드럽게 처리하는 방법, 멀티 테넌트 공정성, 토큰 버킷과 리키 버킷 등 실제로 적용할 수 있는 시스템을 안내합니다. 각 패턴마다 바로 활용할 수 있는 TypeScript 예제도 함께 제공합니다.

만약 음성 에이전트나 내레이션 파이프라인, 또는 ElevenLabs 모델을 활용한 다른 프로덕션 시스템을 구축하고 확장하고 싶다면, 이 가이드가 도움이 됩니다.

요약

  • 음성 AI 레이트 리미팅의 핵심은 동시성 제어이며, 분당 요청 수 제한이 아닙니다.
  • 레이트 리미팅 한도에 도달해도 트래픽이 바로 거부되지 않습니다. 대신 요청이 우선순위 대기열에 들어가 약 50ms 정도 지연이 추가됩니다.
  • 대기열 이후에도 용량을 초과하면 HTTP 429 에러가 발생합니다.
  • WebSocket을 사용하면 실제 용량이 크게 늘어납니다. 활성 생성 시간만 한도에 포함되기 때문입니다.
  • 멀티 테넌트 시스템에는 추가적인 공정성 계층이 필요합니다. 테넌트별 버킷, 가중치 기반 공정 대기열, 예비 용량 확보, 키별 샤딩 등으로 격리할 수 있습니다.
  • 두 가지 응답 헤더(current-concurrent-requests, maximum-concurrent-requests)로 현재 AI 레이트 리미팅 상태를 확인할 수 있습니다.

왜 제한이 분당 요청 수가 아니라 동시성인가요?

동시성은 한 순간에 동시에 처리 중인 요청의 수를 의미합니다. 분당 요청 수는 일정 시간 동안의 처리량입니다. 이 차이를 이해하는 것이 중요한데, 어떤 방식으로 제한을 관리해야 하는지가 달라지기 때문입니다.

ElevenLabs 모델을 사용할 때 서버의 워크로드는 동시 사용자 수에 따라 달라집니다. 오디오 생성은 생성이 끝날 때까지 슬롯을 점유하며, 이 시간은 입력 길이, 모델, 부하에 따라 달라집니다.

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

플랜별, 모델 패밀리별 제한

동시성 예산은 단일 숫자가 아닙니다. 동시성 제한은 플랜과 모델 패밀리마다 다릅니다. 예를 들어, 음성 인식(Speech to Text)텍스트 음성 변환(Text to Speech)보다 더 높은 한도를 가집니다. 전사는 보통 요청이 짧게 끝나기 때문에 시스템이 더 많은 요청을 동시에 처리할 수 있습니다.

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
Priority
Free
3
Starter
4
Creator
5
Pro
5
Scale
5
Business
5
Enterprise
6

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

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

동시성 한도에 도달해도 트래픽이 바로 거부되지 않습니다. 시스템은 우선순위 대기열을 통해 점진적으로 처리하며, 전체 용량을 초과할 때만 완전히 거부됩니다.

한도 내에서는 요청이 바로 처리됩니다. 한도에 도달하면 이후 요청은 플랜의 우선순위에 따라 대기열에 들어갑니다. 대기열은 보통 약 50ms의 지연만 추가하므로, 짧은 초과는 사용자에게 거의 보이지 않습니다.

대기열 이후에도 시스템이 용량을 초과하면 HTTP 429가 반환됩니다. 이 신호가 오면 즉시 재시도하지 말고 속도를 늦춰야 합니다. 테이블의 우선순위 레벨에 따라 대기열에서 요청이 처리되는 순서가 결정되며, 상위 플랜일수록 대기열을 더 빨리 통과합니다.

HTTP vs. WebSocket: 각각의 동시성 계산 방식

어떤 전송 방식을 선택하느냐에 따라 레이트 리미팅과 예산 사용량이 달라집니다. 동일한 대화라도 HTTP와 WebSocket 중 어떤 방식을 쓰느냐에 따라 동시성 예산 소모가 크게 달라질 수 있습니다.

HTTP에서는 각 요청이 전체 처리 시간 동안 동시성 한도를 차지합니다. WebSocket에서는 모델이 실제로 오디오를 생성하는 시간만 한도에 포함됩니다. 열려 있지만 대기 중인 WebSocket은 거의 한도에 포함되지 않습니다.

음성 에이전트의 경우, 대화 중 아무도 말하지 않고 모델이 아무것도 생성하지 않는 시간이 길게 이어집니다. HTTP에서는 매 턴마다 요청 시간만큼 슬롯을 점유하지만, WebSocket에서는 실제 생성되는 순간에만 슬롯이 사용되어 하나의 동시성 슬롯을 여러 대화가 나눠 쓸 수 있습니다.

자세한 프로토콜 내용은 실시간 TTS WebSocket 가이드에서 확인하세요. 인터랙티브 트래픽에는 WebSocket이 기본값으로 적합합니다.

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

동시성의 원리는 재생 시간을 고려해야 직관적으로 이해할 수 있습니다. 오디오 생성은 재생보다 훨씬 빠르며, 슬롯은 오디오 생성 중에만 점유됩니다. 이 차이 덕분에 적은 예산으로도 많은 청취자를 지원할 수 있습니다.

생성에 1초도 안 걸리는 요청이 몇 초짜리 오디오를 만들어내고, 청취자가 재생하는 동안 슬롯은 해제되어 다른 청취자가 사용할 수 있습니다.

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

현재 상태를 알려주는 헤더

한도 대비 현재 위치를 추측할 필요가 없습니다. 모든 응답에는 두 개의 숫자가 포함되어 있어, 단순 추정이 아니라 실제 여유 용량을 측정할 수 있습니다.

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

  • 현재 동시 요청 수: 현재 동시에 처리 중인 요청 수
  • 최대 동시 요청 수: 해당 모델 패밀리의 한도

이 두 헤더를 통해 실시간으로 현재 사용량과 남은 용량을 확인할 수 있습니다. AI 레이트 리미트에 걸리기 전에 추측할 필요가 없습니다.

AI 레이트 리미팅을 위한 클라이언트 전략

거의 모든 AI 레이트 리미팅 상황을 커버하는 네 가지 기본 도구가 있습니다:

  • 토큰 버킷: 토큰이 있으면 요청을 허용합니다. 시간이 지나면서 용량이 다시 채워져, 짧은 폭주 상황에서도 한도에 걸리지 않고 처리할 수 있습니다.
  • 리키 버킷: 들어오는 트래픽을 고정된 출력 속도로 평탄화하여, 갑작스러운 트래픽 폭주가 다운스트림 시스템을 압도하지 않도록 합니다.
  • 제한된 동시성 풀: 동시에 활성화될 수 있는 요청 수를 제한하여, 동시성 한도를 절대 초과하지 않게 만듭니다.
  • 지터가 적용된 지수 백오프: 실패한 요청 사이의 대기 시간을 점점 늘려, 모든 클라이언트가 동시에 재시도하는 상황을 방지합니다.

아래 섹션에서는 동시성 한도와 가장 직접적으로 연결된 도구부터 하나씩 구현하는 방법을 보여줍니다.

아래 모든 예제는 한 번 초기화된 단일 클라이언트를 가정합니다:

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

토큰 버킷: 폭주는 허용, 평균은 제한

토큰 버킷은 최대 용량만큼 토큰을 보유하며, 초당 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));
  }
}

지터가 적용된 지수 백오프

재시도 가능한 상태로 요청이 실패하면, 즉시 재시도하는 것은 상황을 악화시킵니다. 백오프는 재시도 간격을 늘리고, 지터는 각 지연을 무작위로 분산시켜 여러 클라이언트가 동시에 재시도해 또다시 폭주가 발생하는 것을 막아줍니다.

아래 예제에서는 RetryableError라는 작은 클래스를 참조합니다. 이 클래스는 실패 상태와 Retry-After 값을 담고 있습니다. 자세한 정의는 아래 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는 우선순위 대기열 이후에도 용량을 초과했다는 의미이므로, 더 강하게 재시도하기보다는 속도를 늦추는 것이 정답입니다. 처리 방법은 네 가지로 나눌 수 있습니다:

  • 감지
  • 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);
  }
}

추적해야 할 네 가지 신호:

  • 사용률(현재/최대)
  • 전체 요청 대비 429 비율
  • 재시도 깊이(논리적 요청당 시도 횟수)
  • Time-to-first-audio(앱에서 측정, 모델 추론 시간 아님). TTFA에 포함되는 항목은 지연 시간 이해하기를 참고하세요.

건강한 시스템은 사용률이 포화에 훨씬 못 미치고, 429는 가끔씩만 발생합니다. 이 신호들을 모니터링하면 장애가 발생하기 훨씬 전에 레이트 리미팅 압력을 파악할 수 있습니다.

클라이언트 측 레이트 리미팅을 넘어 확장해야 할 때

클라이언트 패턴만으로도 많은 부분을 해결할 수 있지만, 결국에는 지속적인 수요가 이를 초과하게 됩니다. 그때는 비용과 효율 모두를 개선할 수 있는 변화를 시도해야 합니다.

다음 단계들을 순서대로 적용하면 추가 용량을 확보할 수 있습니다.

먼저, 인터랙티브 트래픽은 HTTP 대신 WebSocket으로 전환하세요. 에이전트나 실시간 사용 사례가 HTTP로 동작한다면, WebSocket으로 바꾸면 활성 생성 시간만 한도에 포함되어 용량이 크게 늘어납니다. 대화형 워크로드에서는 대기 시간이 한도에 포함되지 않으므로 효과가 큽니다.

트래픽이 순간적으로 몰리지만 평균 부하는 예산에 맞는 경우, 토큰 버킷이나 리키 버킷에 제한된 풀을 조합하면 피크를 평균으로 평탄화할 수 있습니다.

그 다음에는 적합한 모델을 선택하세요. 더 빠른 생성 속도는 슬롯 점유 시간을 줄여, 동일한 동시성 한도로 더 많은 방송을 지원할 수 있습니다. Eleven Flash v2.5는 최저 지연 옵션이며, 즉시 음성 복제(Instant Voice Clone)나 기본 음성을 사용하면 프로페셔널 음성 복제의 추가 오버헤드도 피할 수 있습니다.

이후에도 예산을 초과한다면 플랜을 업그레이드하세요. 클라이언트가 잘 동작하는데도 지속적으로 예산을 넘긴다면, 상위 플랜으로 동시성 한도와 대기열 우선순위를 모두 높일 수 있습니다. API 가격 페이지에서 각 플랜을 비교해보세요.

공개된 한도 이상이 필요하다면, 엔터프라이즈 플랜에서 더 높은 맞춤 동시성 한도와 최고 대기열 우선순위를 제공합니다. IP 화이트리스트(엔터프라이즈 프리뷰), 무기록 모드 등 추가 제어 기능도 제공됩니다. 한도 상향이 필요하면 담당자에게 문의하세요.

AI 레이트 리미팅에서 꼭 기억해야 할 점

가장 흔한 실수는 음성 AI 레이트 리미팅을 요청 수로만 생각하는 것입니다. 여기서 중요한 것은 동시성 제어입니다. 성공 여부를 결정하는 것은 같은 순간에 오디오를 생성 중인 요청 수와 각 요청이 슬롯을 점유하는 시간입니다.

이 점을 중심으로 클라이언트를 설계하세요.

동시 요청은 제한된 풀로, 요청 허용은 토큰/리키 버킷으로, 재시도는 제한된 지수 백오프와 지터로, Retry-After는 반드시 준수하고, 재시도 폭주 전에 서킷 브레이커로 차단하세요.

멀티 테넌트 시스템에서는 테넌트별 버킷, 가중치 공정성, 예비 용량, 샤딩을 추가하세요. current-concurrent-requests와 maximum-concurrent-requests 헤더를 모니터링하고, 실패가 아니라 사용률 추세에 알림을 설정하세요.

진짜로 더 많은 용량이 필요하다면, 순서대로 적용하세요: 먼저 WebSocket과 클라이언트 개선, 그 다음 모델 선택, 플랜 업그레이드, 마지막으로 엔터프라이즈 한도입니다.

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

프로덕션급 AI 레이트 리미팅은 올바른 전송 방식, 적합한 모델, 그리고 현재 상태를 정확히 알려주는 헤더에서 시작합니다.

ElevenAPI는 Eleven Flash v2.5와 같은 저지연 모델, 실시간 WebSocket 스트리밍, 음성 인식(Speech to Text)텍스트 음성 변환(TTS) API, 그리고 응답마다 동시성 헤더를 제공해, 한도 내에서 확장 가능한 음성 에이전트를 만들 수 있습니다.

이 글에서 소개한 AI 레이트 리미팅 전략과 함께 사용하면, 부하가 걸려도 예측 가능한 성능을 유지하며 반응성 높은 음성 경험을 제공할 수 있습니다.

지금 ElevenAPI에서 전체 모델 라인업을 직접 확인하거나, 계정 만들기로 오늘 바로 ElevenLabs와 함께 시작하세요.

AI 레이트 리미팅 FAQ

유사한 기사

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