---
title: "¿Con cuántos usuarios virtuales deberías empezar en k6?"
description: "Estima VUs iniciales desde objetivos de concurrencia y tasas de llegada, evita generadores saturados y alinea las opciones de k6 con la pregunta de tu escenario."
publishDate: "2026-05-12"
draft: false
keyword: "cuantos usuarios virtuales k6"
intent: "MOFU"
cta: "Usa Performate para modelar rampas de VU, comparar corridas y afinar tu carga inicial más rápido."
tags: ["k6", "usuarios-virtuales", "pruebas-de-carga"]
translationOf: how-many-virtual-users-k6
---

Alguien en Slack dijo «empieza con 500 VUs» porque en otro producto funcionó. Tu API es de circuito abierto, el pool de staging es compartido y el script aún tiene un bug de auth en la iteración dos. La prueba satura el generador, molesta a los vecinos y no responde nada sobre el margen de capacidad en producción.

No existe un número universal de VUs iniciales. El valor correcto depende de si modelas cargas **cerradas** (sesiones concurrentes fijas) o **abiertas** (peticiones que llegan independientes del número de sesiones). En esta guía verás cómo traducir analytics a una primera configuración k6, cuándo los VUs importan menos que la tasa de llegada y cómo leer el resumen cuando tu «VU obvio» está mal.

Si aún eliges el *tipo* de prueba, lee primero [stress vs carga vs spike](/es/blog/stress-vs-carga-vs-spike-testing). Combina decisiones de pacing con [think time y concurrencia](/es/blog/k6-think-time-concurrencia) para que el conteo de VUs refleje pausas humanas, no loops de bot.

## Por qué el mismo número de VUs significa cosas distintas en k6

Los usuarios virtuales de k6 son **ejecutores concurrentes del script**, no humanos literales. El ejecutor cambia qué controlan los VUs:

- **Modelos cerrados** (`constant-vus`, `ramping-vus`): el conteo de VUs ≈ sesiones concurrentes que repiten pasos; quitar `sleep` sube el throughput con los mismos VUs.
- **Modelos abiertos** (`constant-arrival-rate`, `ramping-arrival-rate`): la req/s objetivo es primaria; k6 suma VUs hasta mantener la tasa ([arrival-rate executors](https://k6.io/docs/using-k6/scenarios/arrival-rate-vu-and-iteration-tracking/)).
- **Límites del generador**: si la duración de iteración sube de forma no lineal, quizá necesitas más `maxVUs` o una tasa menor—no «más usuarios» por intuición.

Piensa en los VUs como músicos y la tasa de llegada como tempo—misma plantilla, ritmo distinto, sonido distinto.

### Cuando muchos VUs mienten sobre capacidad

Saltar a VUs altos sin smoke deja que los bugs del script dominen a escala ([guía para principiantes](/es/blog/guia-pruebas-de-carga-principiantes)). En staging compartido, modelos cerrados oversized también disparan fallos de **vecino ruidoso** ajenos a tu servicio. Cambia **una** dimensión por experimento: VUs, duración o tasa de llegada—no las tres ([regresión de línea base](/es/blog/linea-base-regresion-rendimiento-api)).

## Implementación práctica con k6: smoke, rampa cerrada y tasa abierta

Empieza chico, demuestra fidelidad, luego escala la dimensión que coincide con tu pregunta.

**Script de ejemplo (ilustrativo—no listo para producción).** URLs y números ficticios; adapta a tu entorno.

**Qué demuestra este ejemplo:**

- **Etapa smoke** a 3 VUs validando auth y secuencia antes de etapas de carga.
- **Rampa cerrada** (`ramping-vus`) al modelar sesiones tipo navegador.
- **Tasa abierta** (`constant-arrival-rate`) cuando la pregunta es RPS sostenido con think time incluido.
- **Conciencia de iteraciones descartadas** vía umbrales en `http_req_failed` e inspección de métricas de iteración.

```javascript
import http from 'k6/http';
import { check, sleep } from 'k6';

const BASE = __ENV.API_BASE || 'https://staging.example.com';

export const options = {
  scenarios: {
    smoke_closed: {
      executor: 'constant-vus',
      vus: Number(__ENV.SMOKE_VUS || 3),
      duration: '2m',
      tags: { phase: 'smoke' },
      exec: 'apiFlow',
    },
    peak_closed: {
      executor: 'ramping-vus',
      startVUs: 0,
      stages: [
        { duration: '2m', target: Number(__ENV.START_VUS || 25) },
        { duration: '5m', target: Number(__ENV.PEAK_VUS || 50) },
        { duration: '2m', target: 0 },
      ],
      startTime: '2m',
      tags: { phase: 'closed_peak' },
      exec: 'apiFlow',
    },
    sustained_open: {
      executor: 'constant-arrival-rate',
      rate: Number(__ENV.TARGET_RPS || 40),
      timeUnit: '1s',
      duration: '8m',
      preAllocatedVUs: 20,
      maxVUs: Number(__ENV.MAX_VUS || 120),
      startTime: '11m',
      tags: { phase: 'open_rate' },
      exec: 'apiFlow',
    },
  },
  thresholds: {
    http_req_failed: ['rate<0.01'],
    'http_req_duration{phase:smoke}': ['p(95)<500'],
    'http_req_duration{phase:closed_peak}': ['p(95)<800'],
    'http_req_duration{phase:open_rate}': ['p(95)<700'],
  },
};

export function apiFlow() {
  const res = http.get(`${BASE}/orders?page=1`, {
    headers: { Authorization: `Bearer ${__ENV.TOKEN}` },
    tags: { route: 'orders' },
  });
  check(res, { 'orders 2xx': (r) => r.status >= 200 && r.status < 300 });
  sleep(Number(__ENV.THINK_SEC || 2));
}
```

**Patrones que funcionan**

- **Derivar VUs cerrados** de sesiones concurrentes pico en analytics (no uniques diarios)—aplicar 25–50 % en staging compartido primero.
- **Derivar tasas abiertas** de RPS/iteraciones de negocio; afinar `maxVUs` hasta que iteraciones descartadas queden en cero ([ramping arrival rate](/es/blog/k6-ejecutores-ramping-arrival-rate)).
- **Smoke corto a 1–5 VUs** antes de cualquier rampa; arreglar checks y tokens temprano.
- **Comparar corridas** con datasets y entornos congelados para que cambios de VU sean interpretables.

**Antipatrones a evitar**

- Copiar conteos de VU de posts u otros equipos sin el mismo modelo de ejecutor.
- Subir VUs y tasa de llegada en la misma corrida al triagear regresiones.
- Ignorar `dropped_iterations` en resúmenes arrival-rate—la latencia describe entonces una prueba por debajo del objetivo.

**Pro tip (comando de ejemplo):**

```bash
k6 run vu-sizing.js -e SMOKE_VUS=3 -e PEAK_VUS=40 --summary-trend-stats="p(95),p(99)"
```

**Qué demuestra este comando:** tendencias de percentiles por tag `phase` entre smoke, rampa cerrada y etapa open-rate en un solo artefacto.

## Marco de decisión: VUs cerrados vs tasa de llegada abierta

| Situación | Punto de partida recomendado |
|:---|:---|
| Loops de sesión web/móvil con think time | Smoke 1–5 VU → rampa al 25–50 % de sesiones concurrentes pico |
| API medida en RPS en gateway | `constant-arrival-rate` al 25–50 % del RPS objetivo; subir `maxVUs` si caen iteraciones |
| Staging compartido con vecinos ruidosos | Fracción menor (25 %); duración más corta; ventanas fuera de pico |
| Smoke en CI tras merges | 1–3 VUs o tasa baja 2–3 min; `http_req_failed` estricto |
| Stress buscando punto de quiebre | Una dimensión arriba por corrida tras baseline estable ([stress vs carga](/es/blog/stress-vs-carga-vs-spike-testing)) |

**Usa VUs cerrados** cuando la concurrencia en sí es el riesgo (sesiones, carritos, websockets).

**Usa tasa de llegada abierta** cuando el contrato es throughput y las sesiones son fungibles.

**Sube `maxVUs` antes que peak VUs** en modelos abiertos si aumenta el think time pero el RPS objetivo se mantiene.

## Qué leer en el resumen de k6

Mira duración de iteración, iteraciones descartadas (modos arrival-rate) y `http_req_failed` junto con percentiles ([metrics](https://k6.io/docs/using-k6/metrics/)). Si la duración media sube de forma no lineal con aumentos modestos de VU, probablemente golpeaste límites de app o generador. Cruza narrativas con stakeholders usando [cómo leer reportes](/es/blog/como-leer-reportes-pruebas-de-carga) cuando la carga inicial se estabilice.

## Checklist pre-corrida

- [ ] Documentar si el escenario es cerrado (sesiones concurrentes) u abierto (RPS objetivo) y por qué.
- [ ] Registrar fuente de analytics para concurrencia pico o RPS (dashboard, rango de fechas).
- [ ] Correr smoke a ≤5 VUs o tasa mínima hasta que pasen checks de auth y payloads.
- [ ] Definir `maxVUs` en escenarios arrival-rate lo bastante alto para evitar sub-disparo silencioso.
- [ ] Cambiar solo una variable de tamaño por experimento hasta que los resultados se estabilicen.

## Cómo Performate ayuda a encontrar la carga mínima que responde la pregunta

Performate envuelve k6 con flujos de escritorio para clonar escenarios, ajustar rampas o objetivos de llegada y comparar corridas sin reescribir scripts.

**Ejemplo: dimensionar VUs de smoke a pico en un workspace**

1. **Importar** la colección Postman u OpenAPI del camino crítico. *Problema resuelto:* requests alineados con lo que QA ya valida.
2. **Correr smoke a 3 VUs** en el editor; arreglar refresh de token y secuencia antes de escalar. *Problema resuelto:* bugs de script baratos.
3. **Cambiar ejecutor** a `ramping-vus` con stages copiados de analytics (p. ej. 25 → 50 VUs). *Problema resuelto:* tuning de modelo cerrado sin editar options a mano.
4. **Duplicar escenario** como `constant-arrival-rate` al RPS objetivo; subir `maxVUs` hasta cero iteraciones descartadas. *Problema resuelto:* dimensionado open-model visible en la misma UI de reporte.
5. **Comparar corridas** lado a lado con gráficos exportados para revisión de ingeniería.
6. **Exportar k6** para CI cuando el tamaño se estabilice ([ejemplos de umbrales k6](/es/blog/ejemplos-umbrales-k6)).

## Cierre

Los VUs iniciales son una **hipótesis**, no una medalla. Derívalos del modelo de ejecutor y del analytics, haz smoke antes de rampar y escala una dimensión a la vez hasta que el resumen cuente una historia coherente.

Corre smoke esta tarde, luego una rampa cerrada y una etapa open-rate—anota si las colas se mueven por la app o porque se descartaron iteraciones.

[Try Performate free](https://performate.app) | [Book a demo](/demo) | [k6 scenarios documentation](https://k6.io/docs/using-k6/scenarios/)
