Agent Skills
Discover and share powerful Agent Skills for AI assistants
deepgram-rate-limits - Agent Skill - Agent Skills
Home/ Skills / deepgram-rate-limits Implement Deepgram rate limiting and backoff strategies.
Use when handling API quotas, implementing request throttling,
or dealing with rate limit errors.
Trigger with phrases like "deepgram rate limit", "deepgram throttling",
"429 error deepgram", "deepgram quota", "deepgram backoff".
Use the skills CLI to install this skill with one command. Auto-detects all installed AI assistants.
Method 1 - skills CLI
npx skills i jeremylongshore/claude-code-plugins-plus-skills/plugins/saas-packs/deepgram-pack/skills/deepgram-rate-limits CopyMethod 2 - openskills (supports sync & update)
npx openskills install jeremylongshore/claude-code-plugins-plus-skills CopyAuto-detects Claude Code, Cursor, Codex CLI, Gemini CLI, and more. One install, works everywhere.
Installation Path
Download and extract to one of the following locations:
Claude Code Cursor OpenCode Gemini CLI Codex CLI
~/.claude/skills/deepgram-rate-limits/ Back No setup needed. Let our cloud agents run this skill for you.
Select Model
Claude Haiku 4.5 $0.10 Claude Sonnet 4.5 $0.20 Claude Opus 4.5 $0.50 Claude Sonnet 4.5 $0.20 /task
Best for coding tasks
Try NowNo setup required
Deepgram Rate Limits
Overview
Implement proper rate limiting and backoff strategies for Deepgram API integration.
Deepgram Rate Limits
Plan Concurrent Requests Requests/Minute Audio Hours/Month Pay As You Go 100 1000 Unlimited Growth 200 2000 Included hours Enterprise Custom Custom Custom
Instructions
Step 1: Implement Request Queue
Create a queue to manage concurrent request limits.
Step 2: Add Exponential Backoff
Handle rate limit responses with intelligent retry.
Step 3: Monitor Usage
Track request counts and audio duration.
Step 4: Implement Circuit Breaker
Prevent cascade failures during rate limiting.
Output
Rate-limited request queue
Exponential backoff handler
Usage monitoring dashboard
Circuit breaker implementation
Examples
TypeScript Rate Limiter
// lib/rate-limiter.ts
interface
Exponential Backoff with Jitter
// lib/backoff.ts
interface BackoffConfig {
baseDelay : number ;
maxDelay : number ;
factor : number ;
Circuit Breaker Pattern
// lib/circuit-breaker.ts
enum CircuitState {
CLOSED = 'CLOSED' ,
OPEN = 'OPEN' ,
HALF_OPEN =
Usage Monitor
// lib/usage-monitor.ts
interface UsageStats {
requestCount : number ;
audioSeconds : number ;
errorCount : number ;
rateLimitHits : number
Python Rate Limiter
# lib/rate_limiter.py
import asyncio
import time
from collections import deque
from typing import Callable, TypeVar
T = TypeVar( 'T' )
class RateLimiter :
Resources
Next Steps
Proceed to deepgram-security-basics for security best practices.
RateLimiterConfig
{
maxConcurrent : number ;
maxPerMinute : number ;
retryAttempts : number ;
baseDelay : number ;
}
export class DeepgramRateLimiter {
private queue : Array <{
fn : () => Promise < unknown >;
resolve : ( value : unknown ) => void ;
reject : ( error : Error ) => void ;
}> = [];
private activeRequests = 0 ;
private requestsThisMinute = 0 ;
private minuteStart = Date. now ();
private config : RateLimiterConfig ;
constructor ( config : Partial < RateLimiterConfig > = {}) {
this .config = {
maxConcurrent: config.maxConcurrent ?? 50 ,
maxPerMinute: config.maxPerMinute ?? 500 ,
retryAttempts: config.retryAttempts ?? 3 ,
baseDelay: config.baseDelay ?? 1000 ,
};
}
async execute < T >( fn : () => Promise < T >) : Promise < T > {
return new Promise (( resolve , reject ) => {
this .queue. push ({
fn,
resolve: resolve as ( value : unknown ) => void ,
reject,
});
this . processQueue ();
});
}
private async processQueue () {
// Reset minute counter if needed
const now = Date. now ();
if (now - this .minuteStart >= 60000 ) {
this .requestsThisMinute = 0 ;
this .minuteStart = now;
}
// Check limits
if ( this .activeRequests >= this .config.maxConcurrent) return ;
if ( this .requestsThisMinute >= this .config.maxPerMinute) return ;
if ( this .queue. length === 0 ) return ;
const { fn , resolve , reject } = this .queue. shift () ! ;
this .activeRequests ++ ;
this .requestsThisMinute ++ ;
try {
const result = await this . executeWithRetry (fn);
resolve (result);
} catch (error) {
reject (error instanceof Error ? error : new Error ( String (error)));
} finally {
this .activeRequests -- ;
this . processQueue ();
}
}
private async executeWithRetry < T >(
fn : () => Promise < T >,
attempt = 0
) : Promise < T > {
try {
return await fn ();
} catch (error) {
const isRateLimited = error instanceof Error &&
(error.message. includes ( '429' ) || error.message. includes ( 'rate limit' ));
if (isRateLimited && attempt < this .config.retryAttempts) {
const delay = this .config.baseDelay * Math. pow ( 2 , attempt);
const jitter = Math. random () * 1000 ;
await new Promise ( r => setTimeout (r, delay + jitter));
return this . executeWithRetry (fn, attempt + 1 );
}
throw error;
}
}
getStats () {
return {
activeRequests: this .activeRequests,
queuedRequests: this .queue. length ,
requestsThisMinute: this .requestsThisMinute,
};
}
}
jitter : boolean ;
}
export class ExponentialBackoff {
private attempt = 0 ;
private config : BackoffConfig ;
constructor ( config : Partial < BackoffConfig > = {}) {
this .config = {
baseDelay: config.baseDelay ?? 1000 ,
maxDelay: config.maxDelay ?? 60000 ,
factor: config.factor ?? 2 ,
jitter: config.jitter ?? true ,
};
}
getDelay () : number {
const exponential = this .config.baseDelay *
Math. pow ( this .config.factor, this .attempt);
const capped = Math. min (exponential, this .config.maxDelay);
if ( this .config.jitter) {
// Full jitter: random value between 0 and calculated delay
return Math. random () * capped;
}
return capped;
}
increment () : void {
this .attempt ++ ;
}
reset () : void {
this .attempt = 0 ;
}
async wait () : Promise < void > {
const delay = this . getDelay ();
await new Promise ( resolve => setTimeout (resolve, delay));
this . increment ();
}
}
// Usage
const backoff = new ExponentialBackoff ();
async function transcribeWithBackoff ( url : string ) {
const maxAttempts = 5 ;
for ( let i = 0 ; i < maxAttempts; i ++ ) {
try {
return await transcribe (url);
} catch (error) {
if (i === maxAttempts - 1 ) throw error;
if (error instanceof Error && error.message. includes ( '429' )) {
console. log ( `Rate limited, waiting ${ backoff . getDelay () }ms...` );
await backoff. wait ();
} else {
throw error;
}
}
}
}
'HALF_OPEN'
,
}
interface CircuitBreakerConfig {
failureThreshold : number ;
resetTimeout : number ;
halfOpenRequests : number ;
}
export class CircuitBreaker {
private state = CircuitState. CLOSED ;
private failures = 0 ;
private lastFailure = 0 ;
private halfOpenSuccesses = 0 ;
private config : CircuitBreakerConfig ;
constructor ( config : Partial < CircuitBreakerConfig > = {}) {
this .config = {
failureThreshold: config.failureThreshold ?? 5 ,
resetTimeout: config.resetTimeout ?? 30000 ,
halfOpenRequests: config.halfOpenRequests ?? 3 ,
};
}
async execute < T >( fn : () => Promise < T >) : Promise < T > {
if ( this .state === CircuitState. OPEN ) {
if (Date. now () - this .lastFailure > this .config.resetTimeout) {
this .state = CircuitState. HALF_OPEN ;
this .halfOpenSuccesses = 0 ;
} else {
throw new Error ( 'Circuit breaker is OPEN' );
}
}
try {
const result = await fn ();
if ( this .state === CircuitState. HALF_OPEN ) {
this .halfOpenSuccesses ++ ;
if ( this .halfOpenSuccesses >= this .config.halfOpenRequests) {
this .state = CircuitState. CLOSED ;
this .failures = 0 ;
}
}
return result;
} catch (error) {
this . recordFailure ();
throw error;
}
}
private recordFailure () {
this .failures ++ ;
this .lastFailure = Date. now ();
if ( this .failures >= this .config.failureThreshold) {
this .state = CircuitState. OPEN ;
console. log ( 'Circuit breaker OPENED' );
}
}
getState () : CircuitState {
return this .state;
}
}
;
startTime : Date ;
}
export class DeepgramUsageMonitor {
private stats : UsageStats = {
requestCount: 0 ,
audioSeconds: 0 ,
errorCount: 0 ,
rateLimitHits: 0 ,
startTime: new Date (),
};
recordRequest ( audioSeconds : number = 0 ) {
this .stats.requestCount ++ ;
this .stats.audioSeconds += audioSeconds;
}
recordError ( isRateLimit : boolean = false ) {
this .stats.errorCount ++ ;
if (isRateLimit) {
this .stats.rateLimitHits ++ ;
}
}
getStats () : UsageStats & { audioDuration : string ; uptimeHours : number } {
const uptimeMs = Date. now () - this .stats.startTime. getTime ();
return {
... this .stats,
audioDuration: this . formatDuration ( this .stats.audioSeconds),
uptimeHours: uptimeMs / 3600000 ,
};
}
private formatDuration ( seconds : number ) : string {
const hours = Math. floor (seconds / 3600 );
const minutes = Math. floor ((seconds % 3600 ) / 60 );
return `${ hours }h ${ minutes }m` ;
}
shouldAlert () : boolean {
// Alert if rate limit hit rate exceeds 10%
const hitRate = this .stats.rateLimitHits / this .stats.requestCount;
return hitRate > 0.1 && this .stats.requestCount > 10 ;
}
}
def __init__ (
self,
max_concurrent: int = 50 ,
max_per_minute: int = 500
):
self .max_concurrent = max_concurrent
self .max_per_minute = max_per_minute
self .semaphore = asyncio.Semaphore(max_concurrent)
self .request_times: deque = deque()
async def execute (self, fn: Callable[[], T]) -> T:
await self ._wait_for_rate_limit()
async with self .semaphore:
self .request_times.append(time.time())
return await fn()
async def _wait_for_rate_limit (self):
now = time.time()
# Remove requests older than 1 minute
while self .request_times and now - self .request_times[ 0 ] > 60 :
self .request_times.popleft()
# Wait if at limit
if len ( self .request_times) >= self .max_per_minute:
wait_time = 60 - (now - self .request_times[ 0 ])
if wait_time > 0 :
await asyncio.sleep(wait_time)