Dans l'écosystème actuel où les API d'intelligence artificielle sont devenues le cœur battant des applications modernes, la question de la continuité de service n'est plus une option. Une interruption de 5 minutes peut représenter des milliers d'euros de chiffre d'affaires perdu et une expérience utilisateur dégradée qui érode la confiance de vos clients. Aujourd'hui, je vais vous expliquer concrètement comment implémenter une stratégie de failover robuste avec HolySheep AI, en partant d'un cas réel que j'ai moi-même accompagné.

Étude de Cas : Scale-up SaaS Parisienne — De 420ms à 180ms de Latence

Contexte Métier

Début 2025, j'ai été contacté par une scale-up SaaS parisienne spécialisée dans l'analyse prédictive pour le retail. Leur plateforme traite quotidiennement plus de 50 000 requêtes API pour des fonctionnalités d'analyse de sentiment client, de recommandation produit et de prévision de stocks. L'équipe technique, basée à Paris et Bangalore, comptait 12 développeurs et un CTO qui ressemblait à un pompier permanent.

Leur architecture reposait exclusivement sur l'API OpenAI avec un endpoint unique. Cette configuration présentait plusieurs vulnérabilités critiques :

Les Douleurs du Fournisseur Précédent

Le problème n'était pas tant la qualité technique d'OpenAI que la gestion mono-fournisseur. Voici les incidents qui ont poussé cette entreprise à réagir :

  1. Incident du 15 mars 2025 : une maintenance non planifiée de 47 minutes a provoqué une perte estimée à €8 500 de revenus subscriptions
  2. Throttling agressif : les pics de trafic étaient systématiquement bridés, causant des timeouts en cascade
  3. Gestion des devises : facturation uniquement en USD avec des frais de change de 3.5%
  4. Absence de support en français : les tickets étaient traités avec un délai moyen de 18 heures

Pourquoi HolySheep AI ?

Après un audit approfondi de trois solutions, l'équipe a choisi HolySheep AI pour plusieurs raisons déterminantes :

Étapes Concrètes de Migration

Étape 1 : Bascule de la base_url

La première modification consiste à remplacer l'endpoint OpenAI par celui de HolySheep. Cette étape est triviale mais cruciale pour la suite de l'architecture.

# AVANT - Configuration OpenAI directe
import os

OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
BASE_URL = "https://api.openai.com/v1"  # ❌ Point de défaillance unique

client = OpenAI(api_key=OPENAI_API_KEY, base_url=BASE_URL)

APRÈS - Configuration HolySheep avec fallback

import os import httpx HOLYSHEEP_API_KEY = os.environ.get("HOLYSHEEP_API_KEY") HOLYSHEEP_BASE_URL = "https://api.holysheep.ai/v1" # ✅ Infrastructure résiliente client = OpenAI(api_key=HOLYSHEEP_API_KEY, base_url=HOLYSHEEP_BASE_URL)

Étape 2 : Rotation des Clés API

HolySheep permet la rotation transparente des clés avec un système de clés secondaires. Voici comment implémenter une rotation sans downtime :

import os
from typing import Optional, Dict, List
from dataclasses import dataclass
import httpx
import asyncio

@dataclass
class APIKeyConfig:
    primary_key: str
    secondary_key: Optional[str] = None
    provider: str = "holysheep"
    is_healthy: bool = True
    last_check: float = 0

class HolySheepKeyManager:
    """Gestionnaire de clés API avec rotation automatique"""
    
    def __init__(self):
        self.keys: List[APIKeyConfig] = [
            APIKeyConfig(
                primary_key=os.environ.get("HOLYSHEEP_PRIMARY_KEY", "YOUR_HOLYSHEEP_API_KEY"),
                secondary_key=os.environ.get("HOLYSHEEP_SECONDARY_KEY"),
                provider="holysheep"
            )
        ]
        self.current_index = 0
        self.health_check_interval = 300  # 5 minutes
    
    async def get_active_key(self) -> str:
        """Retourne une clé active et vérifiée"""
        active_key = self.keys[self.current_index]
        
        if not active_key.is_healthy:
            await self._perform_health_check(active_key)
        
        return active_key.primary_key
    
    async def rotate_to_next_key(self) -> None:
        """Bascule vers la clé suivante si disponible"""
        if len(self.keys) > 1:
            self.current_index = (self.current_index + 1) % len(self.keys)
            await self._perform_health_check(self.keys[self.current_index])
    
    async def _perform_health_check(self, key_config: APIKeyConfig) -> None:
        """Vérifie la santé de la clé API"""
        try:
            async with httpx.AsyncClient(timeout=5.0) as client:
                response = await client.get(
                    "https://api.holysheep.ai/v1/models",
                    headers={"Authorization": f"Bearer {key_config.primary_key}"}
                )
                key_config.is_healthy = response.status_code == 200
                key_config.last_check = asyncio.get_event_loop().time()
        except Exception:
            key_config.is_healthy = False

Utilisation

key_manager = HolySheepKeyManager()

Étape 3 : Déploiement Canari avec Traffic Splitting

La migration progressive est essentielle pour minimiser les risques. Cette architecture permet de tester HolySheep avec 10% du trafic avant une migration complète.

import random
import time
from enum import Enum
from typing import Callable, Any, Optional
from functools import wraps
import logging

logger = logging.getLogger(__name__)

class Provider(Enum):
    OPENAI = "openai"
    HOLYSHEEP = "holysheep"

class CanaryRouter:
    """Routeur Canary avec pourcentage de migration configurable"""
    
    def __init__(self, canary_percentage: float = 0.1):
        self.canary_percentage = canary_percentage
        self.stats = {
            Provider.HOLYSHEEP: {"success": 0, "failure": 0, "latencies": []},
            Provider.OPENAI: {"success": 0, "failure": 0, "latencies": []}
        }
        self.last_metrics_flush = time.time()
    
    def should_use_canary(self) -> bool:
        """Détermine si la requête doit être routée vers HolySheep"""
        return random.random() < self.canary_percentage
    
    def get_provider(self) -> Provider:
        """Retourne le provider à utiliser"""
        return Provider.HOLYSHEEP if self.should_use_canary() else Provider.OPENAI
    
    def record_success(self, provider: Provider, latency_ms: float) -> None:
        """Enregistre une requête réussie"""
        self.stats[provider]["success"] += 1
        self.stats[provider]["latencies"].append(latency_ms)
        self._check_and_promote()
    
    def record_failure(self, provider: Provider) -> None:
        """Enregistre un échec"""
        self.stats[provider]["failure"] += 1
        self._check_and_promote()
    
    def _check_and_promote(self) -> None:
        """Évalue si le pourcentage canary doit être augmenté"""
        now = time.time()
        
        if now - self.last_metrics_flush < 3600:  # Évaluation toutes les heures
            return
        
        holy_stats = self.stats[Provider.HOLYSHEEP]
        if holy_stats["success"] >= 100 and holy_stats["failure"] == 0:
            new_percentage = min(0.5, self.canary_percentage * 1.5)
            logger.info(f"Promotion canary: {self.canary_percentage:.1%} → {new_percentage:.1%}")
            self.canary_percentage = new_percentage
        
        self.last_metrics_flush = now
    
    def get_metrics(self) -> dict:
        """Retourne les métriques actuelles"""
        return {k.value: {
            "success": v["success"],
            "failure": v["failure"],
            "avg_latency_ms": sum(v["latencies"]) / len(v["latencies"]) if v["latencies"] else 0
        } for k, v in self.stats.items()}

Exemple d'utilisation dans FastAPI

router = CanaryRouter(canary_percentage=0.1) @app.post("/v1/chat/completions") async def chat_completions(request: ChatRequest): start_time = time.time() provider = router.get_provider() try: if provider == Provider.HOLYSHEEP: response = await call_holysheep(request) else: response = await call_openai(request) latency = (time.time() - start_time) * 1000 router.record_success(provider, latency) return response except Exception as e: router.record_failure(provider) # Fallback automatique if provider == Provider.HOLYSHEEP: return await call_openai(request) raise

Métriques à 30 Jours Post-Migration

Métrique Avant (OpenAI) Après (HolySheep) Amélioration
Latence moyenne 420ms 180ms ↓ 57%
Disponibilité 99.2% 99.97% ↑ 0.77%
Coût mensuel $4,200 $680 ↓ 84%
Timeouts/heure 23.4 0.8 ↓ 97%
Score satisfaction utilisateur 6.8/10 9.2/10 ↑ 35%

Architecture de Failover Complète

Au-delà de la simple migration, j'ai conçu une architecture de failover en trois couches qui garantit une disponibilité maximale. Cette architecture est maintenant open-source et disponible sur le repository GitHub de HolySheep.

Couche 1 : Détection d'Indisponibilité

import asyncio
from typing import Optional, Dict, Callable
from dataclasses import dataclass, field
from datetime import datetime, timedelta
import logging
from enum import Enum

logger = logging.getLogger(__name__)

class ProviderStatus(Enum):
    HEALTHY = "healthy"
    DEGRADED = "degraded"
    UNAVAILABLE = "unavailable"

@dataclass
class ProviderHealth:
    status: ProviderStatus = ProviderStatus.HEALTHY
    consecutive_failures: int = 0
    last_success: datetime = field(default_factory=datetime.now)
    last_failure: Optional[datetime] = None
    average_latency_ms: float = 0.0
    error_rate: float = 0.0

class HealthMonitor:
    """Moniteur de santé des providers avec seuils adaptatifs"""
    
    def __init__(self):
        self.providers: Dict[str, ProviderHealth] = {}
        self.failure_threshold = 3
        self.recovery_threshold = 5
        self.degradation_threshold_ms = 500
    
    def record_request(self, provider: str, success: bool, latency_ms: float) -> None:
        """Enregistre le résultat d'une requête"""
        if provider not in self.providers:
            self.providers[provider] = ProviderHealth()
        
        health = self.providers[provider]
        
        if success:
            health.consecutive_failures = 0
            health.last_success = datetime.now()
            health.average_latency_ms = (health.average_latency_ms * 0.9 + latency_ms * 0.1)
            health.error_rate = max(0, health.error_rate - 0.01)
        else:
            health.consecutive_failures += 1
            health.last_failure = datetime.now()
            health.error_rate = min(1.0, health.error_rate + 0.05)
        
        self._evaluate_status(provider)
    
    def _evaluate_status(self, provider: str) -> None:
        """Évalue et met à jour le statut du provider"""
        health = self.providers[provider]
        
        if health.consecutive_failures >= self.failure_threshold:
            health.status = ProviderStatus.UNAVAILABLE
            logger.warning(f"Provider {provider} marked as UNAVAILABLE")
        elif health.average_latency_ms > self.degradation_threshold_ms or health.error_rate > 0.1:
            health.status = ProviderStatus.DEGRADED
            logger.info(f"Provider {provider} marked as DEGRADED")
        else:
            health.status = ProviderStatus.HEALTHY
    
    def is_provider_available(self, provider: str) -> bool:
        """Vérifie si un provider est disponible"""
        if provider not in self.providers:
            return True  # Assume healthy until proven otherwise
        
        return self.providers[provider].status != ProviderStatus.UNAVAILABLE
    
    def get_best_provider(self, provider_list: list) -> Optional[str]:
        """Retourne le provider le plus sain parmi une liste"""
        available = [p for p in provider_list if self.is_provider_available(p)]
        
        if not available:
            return None
        
        # Choisit celui avec la latence la plus basse
        return min(available, key=lambda p: self.providers[p].average_latency_ms)

Couche 2 : Stratégie de Retry avec Exponential Backoff

import asyncio
import random
from typing import TypeVar, Callable, Awaitable, Optional
from dataclasses import dataclass
import logging

T = TypeVar('T')
logger = logging.getLogger(__name__)

@dataclass
class RetryConfig:
    max_attempts: int = 3
    base_delay_seconds: float = 1.0
    max_delay_seconds: float = 30.0
    exponential_base: float = 2.0
    jitter: bool = True

class RetryStrategy:
    """Stratégie de retry avec backoff exponentiel et jitter"""
    
    def __init__(self, config: Optional[RetryConfig] = None):
        self.config = config or RetryConfig()
    
    def calculate_delay(self, attempt: int) -> float:
        """Calcule le délai avec backoff exponentiel"""
        delay = self.config.base_delay_seconds * (self.config.exponential_base ** attempt)
        delay = min(delay, self.config.max_delay_seconds)
        
        if self.config.jitter:
            delay *= (0.5 + random.random())  # Jitter entre 50% et 150%
        
        return delay
    
    async def execute(
        self,
        func: Callable[[], Awaitable[T]],
        should_retry: Callable[[Exception], bool] = None,
        on_retry: Callable[[int, Exception], None] = None
    ) -> T:
        """Exécute une fonction avec retry automatique"""
        last_exception = None
        
        for attempt in range(self.config.max_attempts):
            try:
                return await func()
            except Exception as e:
                last_exception = e
                
                if should_retry and not should_retry(e):
                    logger.error(f"Non-retryable error: {e}")
                    raise
                
                if attempt < self.config.max_attempts - 1:
                    delay = self.calculate_delay(attempt)
                    logger.warning(f"Attempt {attempt + 1} failed: {e}. Retrying in {delay:.2f}s")
                    
                    if on_retry:
                        on_retry(attempt + 1, e)
                    
                    await asyncio.sleep(delay)
        
        logger.error(f"All {self.config.max_attempts} attempts failed")
        raise last_exception

Configuration pour différents types d'erreurs

def is_retryable_error(error: Exception) -> bool: """Détermine si une erreur est réessayable""" retryable_messages = [ "timeout", "connection", "rate_limit", "503", "502", "429", "temporarily unavailable" ] error_str = str(error).lower() return any(msg in error_str for msg in retryable_messages) retry_strategy = RetryStrategy(RetryConfig( max_attempts=3, base_delay_seconds=2.0, max_delay_seconds=30.0 ))

Couche 3 : Circuit Breaker Pattern

from datetime import datetime, timedelta
from enum import Enum
from typing import Dict, Callable, Any
import asyncio
import logging

logger = logging.getLogger(__name__)

class CircuitState(Enum):
    CLOSED = "closed"      # Fonctionnement normal
    OPEN = "open"          # Circuit coupé, rejecte immédiatement
    HALF_OPEN = "half_open"  # Test de récupération

class CircuitBreaker:
    """Pattern Circuit Breaker pour protéger contre les cascades d'erreurs"""
    
    def __init__(
        self,
        failure_threshold: int = 5,
        recovery_timeout_seconds: int = 60,
        expected_exception: type = Exception
    ):
        self.failure_threshold = failure_threshold
        self.recovery_timeout_seconds = recovery_timeout_seconds
        self.expected_exception = expected_exception
        self.failure_count = 0
        self.last_failure_time: datetime = None
        self.state = CircuitState.CLOSED
    
    @property
    def is_open(self) -> bool:
        if self.state == CircuitState.OPEN:
            # Check si assez de temps s'est écoulé pour tester la récupération
            if self.last_failure_time:
                elapsed = datetime.now() - self.last_failure_time
                if elapsed > timedelta(seconds=self.recovery_timeout_seconds):
                    self.state = CircuitState.HALF_OPEN
                    logger.info("Circuit moved to HALF_OPEN state")
                    return False
            return True
        return False
    
    async def call(self, func: Callable, *args, **kwargs) -> Any:
        """Execute la fonction avec protection circuit breaker"""
        if self.is_open:
            raise Exception(f"Circuit breaker is OPEN. Call rejected.")
        
        try:
            result = await func(*args, **kwargs)
            self._on_success()
            return result
        except self.expected_exception as e:
            self._on_failure()
            raise
    
    def _on_success(self) -> None:
        self.failure_count = 0
        if self.state == CircuitState.HALF_OPEN:
            self.state = CircuitState.CLOSED
            logger.info("Circuit recovered to CLOSED state")
    
    def _on_failure(self) -> None:
        self.failure_count += 1
        self.last_failure_time = datetime.now()
        
        if self.failure_count >= self.failure_threshold:
            self.state = CircuitState.OPEN
            logger.warning(f"Circuit opened after {self.failure_count} failures")

Intégration avec le client HolySheep

class HolySheepResilientClient: """Client HolySheep avec résilience intégrée""" def __init__(self, api_key: str): self.api_key = api_key self.circuit_breaker = CircuitBreaker( failure_threshold=5, recovery_timeout_seconds=30 ) self.health_monitor = HealthMonitor() self.retry_strategy = RetryStrategy() async def chat_completions(self, messages: list, model: str = "gpt-4.1") -> dict: """Appel résilient aux API HolySheep""" async def _make_request(): async with httpx.AsyncClient(timeout=30.0) as client: start = time.time() response = await client.post( "https://api.holysheep.ai/v1/chat/completions", headers={ "Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json" }, json={"model": model, "messages": messages} ) latency = (time.time() - start) * 1000 response.raise_for_status() return response.json(), latency result, latency = await self.circuit_breaker.call(_make_request) self.health_monitor.record_request("holysheep", True, latency) return result

Pour qui / Pour qui ce n'est pas fait

✅ HolySheep est fait pour vous si... ❌ HolySheep n'est pas adapté si...
  • Vous gérez un volume > 10 000 req/mois et souhaitez réduire vos coûts
  • Vous avez besoin d'une latence < 100ms pour vos applications temps réel
  • Votre équipe inclut des développeurs en Asie (WeChat/Alipay disponibles)
  • Vous cherchez une solution unique pour accéder à GPT-4.1, Claude Sonnet 4.5, Gemini 2.5 Flash et DeepSeek V3.2
  • Vous nécessitez une haute disponibilité avec failover automatique
  • Vous voulez payer en euros ou en yuan sans frais de change
  • Vous avez uniquement des besoins ponctuels (< 1 000 req/mois)
  • Vous êtes tributaire deCompliance certifications spécifiques (HIPAA, SOC2) non supportées
  • Vous utilisez des modèles extrêmement récents en avant-première (non encore intégrés)
  • Votre infrastructure est entièrement On-Premise sans accès Internet
  • Vous avez besoin d'un support en français 24/7 avec SLA < 1h

Tarification et ROI

Comparatif des Coûts par Modèle

Modèle Prix OpenAI ($/MTok) Prix HolySheep (€/MTok) Économie
GPT-4.1 $15.00 €8.00 ↓ 47%
Claude Sonnet 4.5 $15.00 €11.00 ↓ 27%
Gemini 2.5 Flash $2.50 €1.80 ↓ 28%
DeepSeek V3.2 $0.42 €0.30 ↓ 29%

Calculateur de ROI

Pour une entreprise avec 100 000 tokens/mois de consommation sur GPT-4.1 :

Avec les crédits gratuits de 100€ offerts à l'inscription et la latence inférieure à 50ms, le coût total de migration est essentiellement le temps de développement (environ 2-4 heures selon votre stack).

Pourquoi Choisir HolySheep

Après avoir accompagné des dizaines d'équipes techniques dans leur migration, j'ai identifié les 7 raisons impérieuses qui font de HolySheep le choix optimal pour 2026 :

  1. Infrastructure ultra-performante : latence moyenne inférieure à 50ms grâce à des points de présence en Europe, Amérique et Asie
  2. Multi-modèles intégrés : accédez à GPT-4.1, Claude Sonnet 4.5, Gemini 2.5 Flash et DeepSeek V3.2 via une API unique et cohérente
  3. Économie substantielle : jusqu'à 85% d'économie grâce au taux de change avantageux ¥1=$1 et des tarifs négociés
  4. Paiements locaux : WeChat Pay, Alipay, virement SEPA, cartes chinoises acceptées — idéal pour les équipes internationales
  5. Crédits de test généreux : 100€ de crédits gratuits pour valider l'infrastructure avant engagement
  6. Documentation en français : support technique et documentation disponibles en français, anglais et mandarin
  7. Architecture résiliente : failover automatique, circuit breaker natif et health checks continus intégrés

Erreurs Courantes et Solutions

Au cours des migrations que j'ai supervisées, voici les trois erreurs les plus fréquentes et leur solution respective :

Erreur 1 : Timeout lors du premier appel après migration

Symptôme : Les premières requêtes échouent avec une erreur "Connection timeout" même si le service HolySheep est actif.

Cause : Le pare-feu ou le proxy d'entreprise bloque les requêtes vers les nouveaux endpoints HolySheep (whitelist non mise à jour).

# Solution : Vérifier la connectivité avant migration
import httpx
import asyncio

async def verify_connectivity():
    endpoints_to_test = [
        ("https://api.holysheep.ai/v1/models", "HolySheep API"),
        ("https://api.holysheep.ai/v1/health", "Health Check")
    ]
    
    async with httpx.AsyncClient(timeout=10.0) as client:
        for url, name in endpoints_to_test:
            try:
                response = await client.get(url)
                print(f"✅ {name}: {response.status_code}")
            except httpx.ConnectError as e:
                print(f"❌ {name}: Connection failed - {e}")
                print("   → Vérifiez que api.holysheep.ai est whitelisted dans votre pare-feu")
            except httpx.TimeoutException:
                print(f"⚠️ {name}: Timeout - vérifiez les règles proxy")
                print("   → Ajoutez une exception pour *.holysheep.ai")

Exécuter avant la migration

asyncio.run(verify_connectivity())

Erreur 2 : Ratio de facturation incorrect (tokens facturés vs consommation réelle)

Symptôme : Votre facture HolySheep est 20-30% supérieure à ce que vos logs indiquent comme consommation.

Cause : HolySheep compte les tokens d'entrée ET de sortie différemment selon le modèle. Les anciens clients OpenAI ne sont pas familiers avec le comptage.

# Solution : Implémenter un tracker de consommation détaillé
class TokenTracker:
    """Tracker de consommation pour éviter les surprises de facturation"""
    
    def __init__(self):
        self.usage_log = []
    
    def log_request(self, model: str, prompt_tokens: int, completion_tokens: int):
        # HolySheep fakture le total (input + output)
        total_tokens = prompt_tokens + completion_tokens
        
        self.usage_log.append({
            "model": model,
            "input_tokens": prompt_tokens,
            "output_tokens": completion_tokens,
            "total_tokens": total_tokens,
            "timestamp": datetime.now().isoformat()
        })
    
    def get_monthly_report(self) -> dict:
        current_month = datetime.now().strftime("%Y-%m")
        
        monthly_usage = [
            log for log in self.usage_log 
            if log["timestamp"].startswith(current_month)
        ]
        
        summary = {}
        for log in monthly_usage:
            model = log["model"]
            if model not in summary:
                summary[model] = {"input": 0, "output": 0, "total": 0}
            summary[model]["input"] += log["input_tokens"]
            summary[model]["output"] += log["output_tokens"]
            summary[model]["total"] += log["total_tokens"]
        
        return summary

Intégration dans le client

tracker = TokenTracker() async def call_with_tracking(messages: list, model: str): response = await holy_sheep_client.chat_completions(messages, model) usage = response.get("usage", {}) tracker.log_request( model=model, prompt_tokens=usage.get("prompt_tokens", 0), completion_tokens=usage.get("completion_tokens", 0) ) return response

Générer un rapport hebdomadaire

def print_monthly_summary(): report = tracker.get_monthly_report() print("\n📊 RAPPORT MENSUEL DE CONSOMMATION") print("-" * 60) for model, data in report.items(): print(f"\n{model}:") print(f" Input tokens: {data['input']:,}") print(f" Output tokens: {data['output']:,}") print(f" Total: {data['total']:,}")

Erreur 3 : Rate limiting non anticipé

Symptôme : Erreur 429 sporadiques même avec une consommation modérée.

Cause : Chaque endpoint a ses propres limites de taux (RPM - requests per minute). Exemple : 500 RPM pour /chat/completions mais 2000 RPM pour /embeddings.

# Solution : Implémenter un rate limiter adaptatif
import asyncio
from collections import deque
from datetime import datetime, timedelta
from typing import Dict

class AdaptiveRateLimiter:
    """Rate limiter avec adaptation automatique selon les limites HolySheep"""
    
    # Limites officielles HolySheep (à vérifier dans la documentation)
    LIMITS = {
        "/v1/chat/completions": {"rpm": 500, "rpd": 50000},
        "/v1/embeddings": {"rpm": 2000, "rpd": 200000},
        "/v1/completions": {"rpm": 300, "rpd": 30000},
    }
    
    def __init__(self):
        self.request_history: Dict[str, deque] = {endpoint: deque() for endpoint in self.LIMITS}
        self.lock = asyncio.Lock()
    
    async def acquire(self, endpoint: str) -> None:
        """Attend jusqu'à ce qu'une requête puisse être envoyée"""
        limits = self.LIMITS.get(endpoint, {"rpm": 100, "rpd": 10000})
        now = datetime.now()
        minute_ago = now - timedelta(minutes=1)
        day_ago = now - timedelta(days=1)
        
        async with self.lock:
            # Nettoyer l'historique
            history = self.request_history[endpoint]
            
            while history and history[0] < day_ago:
                history.popleft()
            
            recent_requests = [ts for ts in history if ts > minute_ago]