💻 Développement

dev-scalability-planner

Planification de la scalabilité d'une application ou infrastructure.

⚡ Installation & lancement en 1 commande

Copiez-collez dans votre terminal : le skill s'installe dans ~/.claude/skills et Claude Code se lance directement dessus.

macOS / Linux
curl -fsSL https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.sh | sh -s -- dev-scalability-planner --launch
Windows (PowerShell)
iex "& { $(iwr -useb https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.ps1) } dev-scalability-planner -Launch"

🚀 Déjà installé ?

claude "/dev-scalability-planner"

Ou tapez /dev-scalability-planner dans une session Claude Code, ou décrivez simplement votre besoin — le skill se déclenche automatiquement via le skill-router.

🔑 Déclencheurs automatiques

Le skill s'active automatiquement quand votre demande contient :

scalabilitéscalingmontée en chargemillions d'utilisateurshaute disponibilitéscalehorizontal scaling

📦 Installation manuelle

git clone https://github.com/khalilbenaz/claude-skills-collection.git cp -r claude-skills-collection/skills/dev-scalability-planner ~/.claude/skills/

Payload du plugin : skills/dev-scalability-planner · source éditable : dev-skills/scalability-planner

📖 Manuel

Scalability Planner

Workflow

1. Établir le baseline et les objectifs

Collecter les métriques actuelles avant toute décision :

# Baseline rapide avec wrk
wrk -t4 -c100 -d30s https://api.example.com/health

# Métriques PostgreSQL actives
SELECT count(*), state FROM pg_stat_activity GROUP BY state;

# Saturation CPU/mémoire courante
top -bn1 | head -20

Critères à documenter : RPS moyen/pic, latence p50/p95/p99, utilisateurs concurrents, croissance mensuelle observée, SLA uptime cible.

Seuils décisionnels :

Charge cibleApproche recommandée
< 500 RPSScale vertical + connection pooling
500–5 000 RPSScale horizontal + cache L2
> 5 000 RPSSharding DB + CDN + async obligatoires

2. Identifier les bottlenecks réels

Ne jamais supposer : mesurer d'abord.

# Load test ciblé avec k6
k6 run --vus 200 --duration 60s script.js

# Profiling Go sous charge
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30

# Slow queries PostgreSQL
SELECT query, calls, mean_exec_time FROM pg_stat_statements
ORDER BY mean_exec_time DESC LIMIT 10;

Ordre typique de saturation : DB connections → CPU compute → IOPS stockage → bande passante réseau.

3. Choisir la stratégie de scaling

Critère principal : le service est-il stateless ?

# Kubernetes HPA basé sur CPU + custom metric
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
spec:
  minReplicas: 2
  maxReplicas: 20
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 60
  - type: Pods
    pods:
      metric:
        name: http_requests_per_second
      target:
        type: AverageValue
        averageValue: "1000"

Vertical scaling : pertinent pour les DB (instance type upgrade) mais atteint vite ses limites. Prévoir l'horizontal dès la conception.

4. Scaler la couche base de données

# PgBouncer — connection pooling (postgresql.ini)
[databases]
mydb = host=127.0.0.1 port=5432 dbname=mydb

[pgbouncer]
pool_mode = transaction
max_client_conn = 1000
default_pool_size = 25
-- Partitionnement PostgreSQL par date (haute volumétrie)
CREATE TABLE events (
  id BIGSERIAL,
  created_at TIMESTAMPTZ NOT NULL,
  payload JSONB
) PARTITION BY RANGE (created_at);

CREATE TABLE events_2026_q1 PARTITION OF events
  FOR VALUES FROM ('2026-01-01') TO ('2026-04-01');

Décision read replica vs sharding :

5. Caching multi-niveaux

# Nginx — micro-cache API (évite thundering herd)
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api_cache:10m inactive=1m;

location /api/ {
    proxy_cache api_cache;
    proxy_cache_valid 200 5s;
    proxy_cache_lock on;           # une seule requête upstream pendant le miss
    add_header X-Cache-Status $upstream_cache_status;
}
# Redis — cache-aside avec TTL
import redis, json, hashlib

r = redis.Redis(host='localhost', decode_responses=True)

def get_user(user_id: int):
    key = f"user:{user_id}"
    cached = r.get(key)
    if cached:
        return json.loads(cached)
    user = db.query(User).get(user_id)
    r.setex(key, 300, json.dumps(user.to_dict()))  # TTL 5 min
    return user

Ordre de mise en place : CDN (assets, pages statiques) → reverse proxy cache → cache applicatif → query cache DB.

6. Traitement asynchrone

Découpler les opérations > 200 ms ou non bloquantes pour l'utilisateur.

# Celery — tâche asynchrone Python
from celery import Celery

app = Celery('tasks', broker='redis://localhost:6379/0')

@app.task(bind=True, max_retries=3, default_retry_delay=60)
def send_email(self, user_id, template):
    try:
        _do_send(user_id, template)
    except Exception as exc:
        raise self.retry(exc=exc)

Patterns : queue par priorité (email low, paiement high), DLQ pour les échecs, idempotency key sur chaque message.

7. Multi-région et haute disponibilité

Active-passive : failover DNS, RPO ≈ minutes — simple, pour DR. Active-active : routing latency-based, RPO ≈ 0 — complexe, cohérence éventuelle.

# Terraform — Route53 latency-based routing
resource "aws_route53_record" "api" {
  for_each       = { eu-west-1 = "...", us-east-1 = "..." }
  zone_id        = var.zone_id
  name           = "api.example.com"
  type           = "A"
  set_identifier = each.key
  latency_routing_policy { region = each.key }
  alias { name = aws_lb.api[each.key].dns_name ... }
}

Toujours implémenter : health checks actifs, circuit breaker (Resilience4j, Polly), retry avec jitter.

8. Valider en load test

// k6 — scénario réaliste avec ramp-up
import http from 'k6/http';
import { sleep, check } from 'k6';

export const options = {
  stages: [
    { duration: '2m', target: 100 },   // ramp-up
    { duration: '5m', target: 500 },   // charge cible
    { duration: '2m', target: 1000 },  // pic
    { duration: '1m', target: 0 },     // ramp-down
  ],
  thresholds: {
    http_req_duration: ['p95<500'],
    http_req_failed: ['rate<0.01'],
  },
};

export default function () {
  const res = http.get('https://api.example.com/users');
  check(res, { 'status 200': (r) => r.status === 200 });
  sleep(1);
}

Mesurer le breaking point (pas juste la charge nominale), valider que l'auto-scaling déclenche et stabilise avant 60 s, documenter le plan de capacité.


Anti-patterns et pièges

Bonnes pratiques 2026