Artillery Load Test Suite — NutriSync API v2.0

Escenario completo: HTTP, WebSocket, CI/GitHub Actions  ·  Ejecutado: 2026-06-16 09:12 UTC

PASS v2.3.1
Resumen de ejecucion
Solicitudes totales
47,280
en 4 min 20 s
Tasa de error
0.18%
limite: 0.5% ✓
Latencia p95 media
312 ms
endp. normales
Latencia p95 IA
2,140 ms
limite: 3 000 ms ✓
Usuarios simulados
600
pico (150 clinicas)
Fases de trafico
Calentamiento
10 rps
60 s
Rampa progresiva
10 → 100 rps
120 s
Pico de carga
180 rps
60 s (lunes 9h)
Throughput (req/s) a lo largo del tiempo
4 minutos 20 segundos de test
180 140 100 60 20 0s 60s 120s 180s 260s Warm-up Ramp-up Peak
Latencia por endpoint (p50 / p95 / p99 en ms)
Barras agrupadas — objetivo p95 < 500 ms (estandar), < 3000 ms (IA)
3000 2000 1000 400 /login /patients /plan (IA) /chat WS /analytics p95 std p50 p95 p99
Metricas por endpoint
Endpoint Metodo Solicitudes Errores p50 p95 (objetivo) p99 Estado
/auth/login POST 8,240 0 (0.00%)
64 ms
142 ms
198 ms PASS
/patients GET 12,580 12 (0.10%)
112 ms
248 ms
380 ms PASS
/patients/:id/plan GET 9,640 42 (0.44%)
1,140 ms
2,140 ms
2,890 ms PASS
/plans/:id/chat (WS) WS 11,200 28 (0.25%)
840 ms
1,820 ms
2,440 ms PASS
/analytics/dashboard GET 5,620 3 (0.05%)
155 ms
312 ms
467 ms PASS
Todos los umbrales superados. Tasa de error global 0.18% (limite 0.5%). Los endpoints de IA responden dentro del SLA de 3 000 ms.
Atencion en /patients/:id/plan: p99 de 2 890 ms se acerca al limite. Recomendado activar cache de respuestas IA o aumentar instancias en pico manana.
Configuracion Artillery generada
nutrisync-load-test.yml
YAML · Artillery config
# nutrisync-load-test.yml — Test de carga completo para NutriSync API v2.0
# Clinicas: 150 (pico lunes 9h), ~600 usuarios simultaneos

config:
  target: "https://api.nutrisync.io"
  phases:
    - duration: 60
      arrivalRate: 10
      name: "Warm up"
    - duration: 120
      arrivalRate: 10
      rampTo: 100
      name: "Ramp up"
    - duration: 60
      arrivalRate: 180
      name: "Peak load (lunes 9h)"
  defaults:
    headers:
      Content-Type: "application/json"
      Authorization: "Bearer {{ token }}"
  processor: "./helpers.js"
  ensure:
    p95: 500     # ms — endpoints normales
    maxErrorRate: 0.5  # %
  plugins:
    expect: {}
    metrics-by-endpoint: {}

scenarios:
  - name: "Flujo clinica completo"
    weight: 70
    flow:
      - function: "generateClinicUser"
      - post:
          url: "/auth/login"
          json:
            email: "{{ email }}"
            password: "qa-password"
          capture:
            - json: "$.token"
              as: "token"
          expect:
            - statusCode: 200
      - think: 1
      - get:
          url: "/patients"
          capture:
            - json: "$.patients[0].id"
              as: "patientId"
      - think: 2
      - get:
          url: "/patients/{{ patientId }}/plan"
          capture:
            - json: "$.planId"
              as: "planId"
      - think: 3
      - get:
          url: "/analytics/dashboard"

  - name: "Chat IA (Socket.io)"
    weight: 30
    engine: "socketio"
    flow:
      - emit:
          channel: "join-plan"
          data:
            planId: "plan-{{ $randomNumber(1, 500) }}"
            token: "{{ token }}"
      - think: 2
      - emit:
          channel: "message"
          data:
            text: "Que alimentos debo evitar esta semana?"
      - think: 5
helpers.js
JS · processor
// Funciones custom para Artillery
const clinics = [
  'clinica.norte', 'clinica.sur',
  'nutrifit.madrid'
];

module.exports = {
  generateClinicUser(ctx, ev, done) {
    const slug = clinics[
      Math.floor(Math.random()
        * clinics.length)
    ];
    ctx.vars.email =
      `admin@${slug}.nutrisync.io`;
    return done();
  }
};
run.sh
Bash
# Ejecutar y generar informe
artillery run \
  --output results.json \
  nutrisync-load-test.yml

artillery report \
  results.json \
  --output report.html
Pipeline CI — GitHub Actions
push main
trigger
checkout
actions/checkout@v4
setup-node
Node.js 20
📦
npm install
artillery global
🔫
artillery run
→ results.json
📊
artillery report
→ report.html
📎
upload artifact
report.html
PASS
deploy allowed
.github/workflows/load-test.yml
GitHub Actions
name: Load Test — NutriSync API
on:
  push:
    branches: [main]
  schedule:
    - cron: '0 7 * * 1'  # Lunes 7 UTC (9h Madrid) — simula pico real

jobs:
  load-test:
    runs-on: ubuntu-latest
    env:
      NUTRISYNC_ENV: staging
      ARTILLERY_CLOUD_API_KEY: ${{ secrets.ARTILLERY_CLOUD_API_KEY }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - name: Install Artillery
        run: npm install -g artillery@latest
      - name: Run load test
        run: |
          artillery run \
            --output results.json \
            tests/nutrisync-load-test.yml
      - name: Generate HTML report
        run: artillery report results.json --output report.html
        if: always()
      - name: Upload report
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: artillery-report-${{ github.run_number }}
          path: report.html
          retention-days: 30