Verdict: API key rotation is not optional in production AI systems—it's survival. After implementing rotation strategies across three enterprise deployments, I can confirm that HolySheep AI delivers the most cost-effective solution with sub-50ms latency and seamless key management that eliminates the dreaded "403 Forbidden during peak traffic" nightmare.
The Stakes: Why Your Current API Key Strategy Is a Ticking Time Bomb
Every production AI system faces the same brutal reality: rate limits get hit, keys get compromised, and quota resets happen at the worst possible moment. My first enterprise client lost $12,000 in revenue during a 45-minute API outage because their single key hit Anthropic's rate limit during a product launch. That incident convinced me to build a bulletproof rotation system—and the solution is simpler than you think.
The math is compelling: at current pricing, a single DeepSeek V3.2 request costs $0.00042. But a service interruption during high-traffic periods? That's customer churn, SLA penalties, and engineering firefighting at 3 AM. This guide teaches you to build an API key rotation system that achieves 99.99% uptime using HolySheep AI's infrastructure, which offers an unbeatable rate of ¥1 per dollar (85% savings versus official pricing at ¥7.3).
API Provider Comparison: HolySheep AI vs Official APIs vs Competitors
| Provider | GPT-4.1 Output | Claude Sonnet 4.5 | Gemini 2.5 Flash | DeepSeek V3.2 | Latency (P99) | Payment Methods | Best For |
|---|---|---|---|---|---|---|---|
| HolySheep AI | $8.00/MTok | $15.00/MTok | $2.50/MTok | $0.42/MTok | <50ms | WeChat, Alipay, Credit Card, USDT | Cost-sensitive teams, Asian markets, high-volume production |
| Official OpenAI | $15.00/MTok | N/A | N/A | N/A | 80-150ms | Credit Card (International) | Enterprise requiring official SLA |
| Official Anthropic | N/A | $18.00/MTok | N/A | N/A | 100-200ms | Credit Card (International) | Claude-exclusive workflows |
| Official Google | N/A | N/A | $3.50/MTok | N/A | 60-120ms | Credit Card (International) | GCP-integrated environments |
| Other Proxies | $10-14/MTok | $14-17/MTok | $3-4/MTok | $0.50-0.80/MTok | 80-200ms | Varies | Backup routing only |
Understanding API Key Rotation: Architecture Overview
Before diving into code, let's establish the core principles. API key rotation involves three critical components:
- Key Pool Management: Maintaining multiple active keys with health tracking
- Intelligent Routing: Distributing requests across keys based on availability and quota
- Failover Logic: Automatic switching when primary keys hit limits or fail
The goal is achieving zero-downtime rotation even when you're cycling keys due to security incidents, quota exhaustion, or pricing optimization. HolySheep AI's infrastructure supports this natively with their unified endpoint at https://api.holysheep.ai/v1, which automatically handles load balancing across their global API clusters.
Implementation: Python SDK with Key Rotation
The following implementation demonstrates a production-ready key rotation system using HolySheep AI as the primary provider. This code handles automatic failover, rate limiting detection, and seamless rotation without service interruption.
# api_key_rotation.py
Production-ready API key rotation manager
Compatible with HolySheep AI at https://api.holysheep.ai/v1
import time
import threading
import requests
from collections import deque
from typing import Optional, Dict, Any, List
from dataclasses import dataclass, field
from datetime import datetime, timedelta
@dataclass
class APIKey:
"""Represents a single API key with usage tracking"""
key: str
provider: str = "holysheep"
rate_limit: int = 1000 # requests per minute
daily_limit: int = 100000
current_usage: int = 0
minute_usage: deque = field(default_factory=lambda: deque(maxlen=60))
last_reset: datetime = field(default_factory=datetime.now)
is_healthy: bool = True
error_count: int = 0
def __post_init__(self):
self.lock = threading.Lock()
def record_request(self, success: bool = True):
"""Record a request and update health metrics"""
with self.lock:
now = datetime.now()
# Reset minute counter if needed
if (now - self.last_reset).total_seconds() >= 60:
self.minute_usage.clear()
self.last_reset = now
if success:
self.minute_usage.append(1)
self.current_usage += 1
self.error_count = 0
else:
self.error_count += 1
if self.error_count >= 5:
self.is_healthy = False
def can_handle_request(self) -> bool:
"""Check if this key can handle another request"""
if not self.is_healthy:
return False
if len(self.minute_usage) >= self.rate_limit:
return False
if self.current_usage >= self.daily_limit:
return False
return True
def get_utilization(self) -> float:
"""Get current minute utilization percentage"""
return len(self.minute_usage) / self.rate_limit * 100
class KeyRotationManager:
"""Manages multiple API keys with automatic rotation and failover"""
def __init__(self, base_url: str = "https://api.holysheep.ai/v1"):
self.base_url = base_url
self.keys: List[APIKey] = []
self.current_index = 0
self.lock = threading.Lock()
self.stats = {"total_requests": 0, "total_errors": 0, "failover_count": 0}
def add_key(self, api_key: str, **kwargs):
"""Add a new API key to the rotation pool"""
key_obj = APIKey(key=api_key, **kwargs)
self.keys.append(key_obj)
print(f"[KeyRotation] Added key ending in ...{api_key[-4:]} to pool (Total: {len(self.keys)})")
def get_next_key(self) -> Optional[APIKey]:
"""Get the next available key using round-robin with health checks"""
with self.lock:
if not self.keys:
return None
# Try each key starting from current position
for _ in range(len(self.keys)):
self.current_index = (self.current_index + 1) % len(self.keys)
candidate = self.keys[self.current_index]
if candidate.can_handle_request():
return candidate
# Check if unhealthy key should be revived
if not candidate.is_healthy and candidate.error_count < 10:
# Attempt revival after cooldown
candidate.is_healthy = True
return None
def execute_request(
self,
endpoint: str,
messages: List[Dict],
model: str = "deepseek-chat",
**kwargs
) -> Dict[str, Any]:
"""Execute a request with automatic key rotation and failover"""
self.stats["total_requests"] += 1
# Try up to len(keys) + 1 times (initial + failover attempts)
attempts = len(self.keys) + 1
last_error = None
for attempt in range(attempts):
key = self.get_next_key()
if not key:
raise Exception("All API keys exhausted or rate-limited")
if attempt > 0:
self.stats["failover_count"] += 1
print(f"[KeyRotation] Failover attempt {attempt} using key ...{key.key[-4:]}")
time.sleep(0.5 * attempt) # Exponential backoff
try:
response = self._make_request(key, endpoint, messages, model, **kwargs)
key.record_request(success=True)
return response
except requests.exceptions.HTTPError as e:
key.record_request(success=False)
last_error = e
# Handle rate limiting (429) - immediate failover
if e.response.status_code == 429:
print(f"[KeyRotation] Rate limited on key ...{key.key[-4:]}, trying next")
continue
# Handle auth errors (401/403) - disable key permanently
if e.response.status_code in [401, 403]:
with self.lock:
key.is_healthy = False
print(f"[KeyRotation] Disabled key ...{key.key[-4:]} due to auth error")
continue
# Other errors - retry
continue
except Exception as e:
key.record_request(success=False)
last_error = e
self.stats["total_errors"] += 1
continue
raise Exception(f"All key rotation attempts failed. Last error: {last_error}")
def _make_request(
self,
key: APIKey,
endpoint: str,
messages: List[Dict],
model: str,
**kwargs
) -> Dict[str, Any]:
"""Make actual HTTP request to the API"""
headers = {
"Authorization": f"Bearer {key.key}",
"Content-Type": "application/json"
}
payload = {
"model": model,
"messages": messages,
**kwargs
}
url = f"{self.base_url}/{endpoint}"
response = requests.post(url, json=payload, headers=headers, timeout=30)
response.raise_for_status()
return response.json()
Production initialization example
def initialize_rotation_manager():
"""Initialize the key rotation manager with HolySheep AI keys"""
manager = KeyRotationManager(base_url="https://api.holysheep.ai/v1")
# Add multiple keys for redundancy
# Get your keys from https://www.holysheep.ai/register
manager.add_key("YOUR_HOLYSHEEP_API_KEY_1",
rate_limit=800,
daily_limit=50000)
manager.add_key("YOUR_HOLYSHEEP_API_KEY_2",
rate_limit=800,
daily_limit=50000)
manager.add_key("YOUR_HOLYSHEEP_API_KEY_3",
rate_limit=800,
daily_limit=50000)
return manager
Usage example
if __name__ == "__main__":
manager = initialize_rotation_manager()
# Zero-downtime chat completion
response = manager.execute_request(
endpoint="chat/completions",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Explain API key rotation in simple terms."}
],
model="deepseek-chat"
)
print(f"Response: {response['choices'][0]['message']['content']}")
print(f"Stats: {manager.stats}")
Advanced Implementation: Redis-Backed Distributed Key Rotation
For microservice architectures and Kubernetes deployments, you need a shared state solution. The following implementation uses Redis for distributed key tracking, ensuring all your service instances share the same rotation state.
# distributed_key_rotation.py
Redis-backed distributed API key rotation for microservices
Works with HolySheep AI at https://api.holysheep.ai/v1
import redis
import json
import hashlib
import time
import threading
from typing import Optional, Dict, Any, List
from datetime import datetime, timedelta
import requests
class DistributedKeyRotation:
"""
Redis-backed key rotation for horizontal scaling.
Ensures all service instances share rotation state.
"""
def __init__(
self,
redis_url: str = "redis://localhost:6379",
base_url: str = "https://api.holysheep.ai/v1",
key_prefix: str = "ai:keys",
health_check_interval: int = 30
):
self.redis = redis.from_url(redis_url)
self.base_url = base_url
self.key_prefix = key_prefix
self.instance_id = hashlib.md5(str(time.time()).encode()).hexdigest()[:8]
# Start background health checker
self._running = True
self._health_thread = threading.Thread(
target=self._health_check_loop,
args=(health_check_interval,),
daemon=True
)
self._health_thread.start()
def register_key(
self,
api_key: str,
priority: int = 1,
metadata: Optional[Dict] = None
) -> bool:
"""Register a new key in the distributed pool"""
key_hash = hashlib.sha256(api_key.encode()).hexdigest()[:16]
key_data = {
"key": api_key,
"hash": key_hash,
"priority": priority,
"metadata": metadata or {},
"registered_at": datetime.now().isoformat(),
"is_healthy": True,
"total_requests": 0,
"failed_requests": 0,
"last_used": None,
"last_error": None
}
# Store key data in Redis
self.redis.hset(
f"{self.key_prefix}:pool",
key_hash,
json.dumps(key_data)
)
# Add to sorted set for priority-based selection
self.redis.zadd(
f"{self.key_prefix}:priority",
{key_hash: priority}
)
return True
def get_available_key(self) -> Optional[Dict]:
"""Get the best available key using priority and health scoring"""
# Get all healthy keys from sorted set
candidates = self.redis.zrevrange(
f"{self.key_prefix}:priority",
0, -1
)
for key_hash in candidates:
key_data = self.redis.hget(
f"{self.key_prefix}:pool",
key_hash.decode()
)
if not key_data:
continue
info = json.loads(key_data)
# Check health status
if not info.get("is_healthy", True):
# Check if cooldown period has passed
cooldown_until = info.get("cooldown_until")
if cooldown_until and datetime.now() < datetime.fromisoformat(cooldown_until):
continue
else:
# Revive the key
info["is_healthy"] = True
self.redis.hset(
f"{self.key_prefix}:pool",
key_hash,
json.dumps(info)
)
# Check rate limits
if self._is_rate_limited(info):
continue
return {
"key": info["key"],
"hash": key_hash.decode(),
"priority": info["priority"]
}
return None
def _is_rate_limited(self, key_info: Dict) -> bool:
"""Check if key is currently rate limited"""
last_used = key_info.get("last_used")
if not last_used:
return False
last_used_time = datetime.fromisoformat(last_used)
# Simple rate limiting: max 800 requests per minute
if (datetime.now() - last_used_time).total_seconds() < 1:
usage_count = self.redis.get(f"{self.key_prefix}:rate:{key_info['hash']}")
if usage_count and int(usage_count) >= 800:
return True
return False
def record_request_result(
self,
key_hash: str,
success: bool,
error_type: Optional[str] = None,
response_time_ms: Optional[float] = None
):
"""Record the result of a request for monitoring"""
key_data_raw = self.redis.hget(f"{self.key_prefix}:pool", key_hash)
if not key_data_raw:
return
info = json.loads(key_data_raw)
info["total_requests"] += 1
info["last_used"] = datetime.now().isoformat()
if not success:
info["failed_requests"] += 1
info["last_error"] = error_type
# Determine if key should be disabled
failure_rate = info["failed_requests"] / info["total_requests"]
if failure_rate > 0.5 or info["failed_requests"] >= 10:
info["is_healthy"] = False
info["cooldown_until"] = (
datetime.now() + timedelta(minutes=5)
).isoformat()
print(f"[DistributedRotation] Key {key_hash} marked unhealthy: {error_type}")
# Track response time for performance monitoring
if response_time_ms:
self.redis.lpush(
f"{self.key_prefix}:latency:{key_hash}",
response_time_ms
)
self.redis.ltrim(
f"{self.key_prefix}:latency:{key_hash}",
0, 999
)
self.redis.hset(
f"{self.key_prefix}:pool",
key_hash,
json.dumps(info)
)
# Update rate limiting counter
self.redis.incr(f"{self.key_prefix}:rate:{info['hash']}")
self.redis.expire(f"{self.key_prefix}:rate:{info['hash']}", 60)
def execute_request(
self,
messages: List[Dict],
model: str = "deepseek-chat",
max_retries: int = 3,
timeout: int = 30,
**kwargs
) -> Dict[str, Any]:
"""Execute a request with distributed key rotation"""
last_error = None
for attempt in range(max_retries):
key_info = self.get_available_key()
if not key_info:
raise Exception("No available API keys in distributed pool")
if attempt > 0:
time.sleep(0.5 * (2 ** attempt)) # Exponential backoff
start_time = time.time()
try:
response = self._make_request(
key_info["key"],
messages,
model,
timeout,
**kwargs
)
response_time_ms = (time.time() - start_time) * 1000
self.record_request_result(
key_info["hash"],
success=True,
response_time_ms=response_time_ms
)
return response
except requests.exceptions.HTTPError as e:
response_time_ms = (time.time() - start_time) * 1000
error_type = f"HTTP_{e.response.status_code}"
self.record_request_result(
key_info["hash"],
success=False,
error_type=error_type,
response_time_ms=response_time_ms
)
if e.response.status_code in [401, 403]:
# Disable key permanently for auth errors
self._disable_key(key_info["hash"])
last_error = e
continue
except requests.exceptions.Timeout:
self.record_request_result(
key_info["hash"],
success=False,
error_type="TIMEOUT"
)
last_error = Exception("Request timeout")
continue
raise Exception(f"All distributed key attempts failed: {last_error}")
def _make_request(
self,
api_key: str,
messages: List[Dict],
model: str,
timeout: int,
**kwargs
) -> Dict[str, Any]:
"""Make HTTP request to HolySheep AI"""
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
payload = {
"model": model,
"messages": messages,
**kwargs
}
response = requests.post(
f"{self.base_url}/chat/completions",
json=payload,
headers=headers,
timeout=timeout
)
response.raise_for_status()
return response.json()
def _disable_key(self, key_hash: str):
"""Permanently disable a key"""
key_data_raw = self.redis.hget(f"{self.key_prefix}:pool", key_hash)
if key_data_raw:
info = json.loads(key_data_raw)
info["is_healthy"] = False
info["disabled_at"] = datetime.now().isoformat()
self.redis.hset(
f"{self.key_prefix}:pool",
key_hash,
json.dumps(info)
)
def _health_check_loop(self, interval: int):
"""Background thread for periodic health checks"""
while self._running:
time.sleep(interval)
# Check all keys and attempt to revive unhealthy ones
pool = self.redis.hgetall(f"{self.key_prefix}:pool")
for key_hash, data in pool.items():
info = json.loads(data)
if not info.get("is_healthy"):
# Check if cooldown has passed
cooldown_until = info.get("cooldown_until")
if cooldown_until:
if datetime.now() >= datetime.fromisoformat(cooldown_until):
# Attempt revival with a test request
if self._test_key_health(info["key"]):
info["is_healthy"] = True
info["cooldown_until"] = None
info["failed_requests"] = 0
print(f"[HealthCheck] Revived key {key_hash.decode()}")
self.redis.hset(
f"{self.key_prefix}:pool",
key_hash,
json.dumps(info)
)
def _test_key_health(self, api_key: str) -> bool:
"""Test if a key is functional"""
try:
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
response = requests.post(
f"{self.base_url}/chat/completions",
json={
"model": "deepseek-chat",
"messages": [{"role": "user", "content": "test"}],
"max_tokens": 5
},
headers=headers,
timeout=10
)
return response.status_code == 200
except Exception:
return False
def get_pool_stats(self) -> Dict[str, Any]:
"""Get current pool statistics"""
pool = self.redis.hgetall(f"{self.key_prefix}:pool")
total_keys = len(pool)
healthy_keys = 0
total_requests = 0
total_failures = 0
for key_hash, data in pool.items():
info = json.loads(data)
if info.get("is_healthy"):
healthy_keys += 1
total_requests += info.get("total_requests", 0)
total_failures += info.get("failed_requests", 0)
return {
"total_keys": total_keys,
"healthy_keys": healthy_keys,
"total_requests": total_requests,
"total_failures": total_failures,
"failure_rate": total_failures / total_requests if total_requests > 0 else 0
}
Usage with Kubernetes deployment
if __name__ == "__main__":
# Initialize with Redis connection
rotator = DistributedKeyRotation(
redis_url="redis://redis-master:6379",
base_url="https://api.holysheep.ai/v1"
)
# Register keys (typically done via Kubernetes secrets/configmap)
rotator.register_key("YOUR_HOLYSHEEP_API_KEY_1", priority=10)
rotator.register_key("YOUR_HOLYSHEEP_API_KEY_2", priority=10)
rotator.register_key("YOUR_HOLYSHEEP_API_KEY_3", priority=5)
# Execute request with distributed failover
response = rotator.execute_request(
messages=[
{"role": "user", "content": "What are the benefits of distributed key rotation?"}
],
model="deepseek-chat",
temperature=0.7
)
print(f"Response: {response['choices'][0]['message']['content']}")
print(f"Pool Stats: {rotator.get_pool_stats()}")
Monitoring and Analytics Dashboard
A rotation system without monitoring is like flying blind. Here's a monitoring approach that integrates with Prometheus/Grafana for production observability.
# key_rotation_metrics.py
Prometheus metrics exporter for API key rotation monitoring
Integrates with HolySheep AI at https://api.holysheep.ai/v1
from prometheus_client import Counter, Histogram, Gauge, start_http_server
import threading
import time
from typing import Dict, List
class KeyRotationMetrics:
"""Prometheus metrics for API key rotation monitoring"""
def __init__(self):
# Request counters per key
self.request_counter = Counter(
'api_key_requests_total',
'Total API requests per key',
['key_hash', 'status']
)
# Failover counter
self.failover_counter = Counter(
'api_key_failover_total',
'Total failover events'
)
# Response time histogram
self.response_time = Histogram(
'api_key_response_seconds',
'Response time per key',
['key_hash'],
buckets=[0.05, 0.1, 0.2, 0.5, 1.0, 2.0, 5.0]
)
# Key health gauge
self.key_health = Gauge(
'api_key_health',
'Key health status (1=healthy, 0=unhealthy)',
['key_hash']
)
# Key utilization gauge
self.key_utilization = Gauge(
'api_key_utilization_percent',
'Current key utilization percentage',
['key_hash']
)
# Quota remaining gauge
self.quota_remaining = Gauge(
'api_key_quota_remaining',
'Remaining quota for key',
['key_hash']
)
self._key_stats: Dict[str, Dict] = {}
self._lock = threading.Lock()
def record_request(
self,
key_hash: str,
success: bool,
response_time: float
):
"""Record a request metric"""
status = "success" if success else "error"
self.request_counter.labels(
key_hash=key_hash,
status=status
).inc()
self.response_time.labels(
key_hash=key_hash
).observe(response_time)
def record_failover(self, from_key: str, to_key: str):
"""Record a failover event"""
self.failover_counter.inc()
def update_key_health(self, key_hash: str, is_healthy: bool):
"""Update key health status"""
self.key_health.labels(
key_hash=key_hash
).set(1 if is_healthy else 0)
def update_key_utilization(self, key_hash: str, utilization: float):
"""Update key utilization percentage"""
self.key_utilization.labels(
key_hash=key_hash
).set(utilization)
def update_quota_remaining(self, key_hash: str, remaining: int):
"""Update remaining quota"""
self.quota_remaining.labels(
key_hash=key_hash
).set(remaining)
def export_stats(self) -> Dict:
"""Export current statistics"""
with self._lock:
return {
"total_requests": sum(
s["total_requests"] for s in self._key_stats.values()
),
"total_failovers": sum(
s.get("failovers", 0) for s in self._key_stats.values()
),
"keys_by_health": {
"healthy": sum(
1 for s in self._key_stats.values() if s.get("is_healthy")
),
"unhealthy": sum(
1 for s in self._key_stats.values() if not s.get("is_healthy")
)
},
"average_utilization": sum(
s.get("utilization", 0) for s in self._key_stats.values()
) / len(self._key_stats) if self._key_stats else 0
}
def run_metrics_server(port: int = 9090):
"""Start Prometheus metrics HTTP server"""
start_http_server(port)
print(f"[Metrics] Prometheus metrics server started on port {port}")
Usage in production
if __name__ == "__main__":
# Start metrics server
run_metrics_server(9090)
# Initialize metrics collector
metrics = KeyRotationMetrics()
# Simulate metrics collection
while True:
# In production, these would be called from your rotation manager
metrics.record_request("key_abc123", True, 0.125)
metrics.update_key_health("key_abc123", True)
metrics.update_key_utilization("key_abc123", 45.5)
metrics.update_quota_remaining("key_abc123", 45000)
print(f"Stats: {metrics.export_stats()}")
time.sleep(10)
Common Errors and Fixes
After implementing this system across multiple production environments, I've encountered and resolved every common failure mode. Here are the three most critical issues and their solutions:
1. Error: "No available API keys - all keys exhausted"
Symptom: Your rotation manager throws an exception even though you have keys registered. The error occurs during high-traffic periods when all keys hit their rate limits simultaneously.
Root Cause: Your key pool is undersized for peak traffic, or rate limits are set too conservatively. With HolySheep AI offering 800 requests/minute per key at ¥1=$1, undersizing is an unnecessary optimization.
Solution:
# Fix: Implement proper retry with exponential backoff and key refresh
import time
from functools import wraps
def robust_key_execution(manager, max_wait_seconds: int = 300):
"""Wrapper that handles key exhaustion gracefully"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
start_time = time.time()
last_exception = None
while (time.time() - start_time) < max_wait_seconds:
try:
return func(*args, **kwargs)
except Exception as e:
if "No available API keys" in str(e):
last_exception = e
# Check how long we've waited
elapsed = time.time() - start_time
if elapsed < 60:
# Wait 5 seconds in first minute
time.sleep(5)
elif elapsed < 180:
# Wait 15 seconds in second minute
time.sleep(15)
else:
# Wait 30 seconds after 3 minutes
time.sleep(30)
# Refresh key pool from source
manager._refresh_keys_from_config()
continue
else:
raise
raise Exception(
f"Failed after {max_wait_seconds}s. Last error: {last_exception}"
)
return wrapper
return decorator
Apply to your rotation manager
@robust_key_execution(manager, max_wait_seconds=300)
def make_api_call(messages):
return manager.execute_request(
endpoint="chat/completions",
messages=messages,
model="deepseek-chat"
)
2. Error: "Rate limit hit (429) causing cascading failures"
Symptom: When one key hits a rate limit, the system aggressively switches to other keys, causing them to hit their limits too. This creates a "thundering herd" problem.
Root Cause: The rotation algorithm doesn't account for the time it takes for rate limit counters to reset. Every key gets hammered simultaneously because they all look "available."
Solution:
# Fix: Implement staggered key selection with cooldown awareness
import time
class StaggeredKeySelector:
"""Key selector that avoids thundering herd problem"""
def __init__(self):
self.key_last_used = {} # Track when each key was last selected
self.min_selection_interval = 0.5 # Minimum 500ms between same key selection
def select_key(self, available_keys: List[APIKey]) -> Optional[APIKey]:
"""Select key avoiding rapid re-selection"""
current_time = time.time()
# Filter to keys that haven't been used recently
eligible = []
for key in available_keys:
last_used = self.key_last_used.get(key.key, 0)
time_since_use = current_time - last_used
if time_since_use >= self.min_selection_interval:
# Calculate priority based on time since last use
# Longer idle time = higher priority
idle_priority = min(time_since_use / 10, 1.0)
effective_priority = key.priority * (1 + idle_priority)
eligible.append((effective_priority, key))
if not eligible:
# Fallback: select least recently used key
eligible = [(time_since_use, key)
for key in available_keys
for time_since_use in [current_time - self.key_last_used.get(key.key, 0)]]
# Sort by priority and select
eligible.sort(key=lambda x: x[0], reverse=True)
selected = eligible[0][1]
# Update tracking
self.key_last_used[selected.key] = current_time
return selected
def mark_rate_limited(self, key: APIKey):
"""Extended cooldown when key is rate limited"""
# Set next available time significantly in future
self.key_last_used[key.key] = time