---
title: "Think time y concurrencia: escenarios k6 que se sienten humanos (sin matemática de fantasía)"
description: "Think time y concurrencia en k6: pacing realista, distribuciones de sleep e interacción con escenarios arrival-rate—alineado con analytics de producto."
publishDate: "2026-08-24"
draft: false
keyword: "k6 think time concurrencia"
intent: "MOFU"
cta: "Usa Performate para convertir este playbook en escenarios k6 ejecutables, umbrales y reportes compartibles sin perder días en código pegamento."
tags: ["k6", "pruebas-de-carga", "rendimiento-api", "think", "tiempo"]
translationOf: k6-think-time-concurrency
---

Tu script ejecuta búsqueda → detalle → checkout en 200 ms sin pausa. Analytics de producto dice que el usuario mediano tarda 8 segundos entre pasos. La prueba reporta 500 req/s sostenidos; producción nunca supera 40—y el capacity plan compra infraestructura para un fantasía de bots.

El think time (`sleep`) en k6 no es decoración: define **cuánta presión concurrente** ejerce cada VU y si tu modelo closed vs open tiene sentido. En esta guía verás por qué sleeps uniformes de 1 s suelen mentir, cómo alinear distribuciones a telemetría de sesión, y qué cambia cuando combinas think time con ejecutores arrival-rate.

## Por qué el pacing cambia la concurrencia—no solo el RPS

A nivel funcional, omitir `sleep` «acelera» la prueba. Bajo modelos closed, produce efectos distintos:

- **VUs como bots** — cada usuario virtual dispara requests al ritmo máximo; la concurrencia efectiva en backends y pools de DB no refleja sesiones humanas.
- **RPS inflado en closed model** — más VUs × menos sleep = más req/s que analytics de producto jamás verá.
- **Interacción con arrival rate** — en ejecutores open, el think time **no** reduce la tasa objetivo; k6 lanza más VUs para mantener iteraciones/s ([ejecutores](/es/blog/k6-ejecutores-ramping-arrival-rate)).
- **Colas engañosas** — sin pausa, las colas de middleware se llenan distinto; los percentiles no son comparables a prod.

Piensa en medir tráfico peatonal contando pasos por minuto mientras todos corren en lugar de caminar.

### Cuando copiar sleeps de otro producto falla

Los artículos genéricos sugieren `sleep(1)` o `sleep(Math.random() * 3)`. Valida contra trazas de sesión reales—o contra [cuántos usuarios virtuales](/es/blog/cuantos-usuarios-virtuales-k6) necesitas dado tu mix de closed/open. Combina pacing con [tipos de escenario](/es/blog/tipos-escenarios-k6-explicados) cuando el riesgo es flujo multipaso, no un endpoint aislado.

## Implementación práctica con k6: distribuciones de sleep en flujo multipaso

Modela un journey de e-commerce con pausas log-normales entre pasos—más realistas que uniforme—y compara RPS resultante con analytics.

**Script de ejemplo (ilustrativo—no es una prueba lista para producción).** El snippet usa URLs y timings ficticios. Adapta base URL, auth y distribuciones a tu telemetría.

**Qué demuestra este ejemplo:**

- **Think time por paso:** sleeps distintos tras búsqueda, detalle y checkout reflejan lectura vs decisión de compra.
- **Distribución sesgada:** `humanPause()` usa log-normal (media ~3 s) en lugar de uniforme 0–1 s.
- **Closed model explícito:** `ramping-vus` con 30→80 VUs modela sesiones concurrentes, no req/s fijos.
- **Checks por paso:** validación funcional en cada transición antes de dormir—evita inflar sleeps sobre requests fallidos.

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

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

// Pausa log-normal aproximada — calibra media/mu contra analytics
function humanPause(meanSeconds = 3) {
  const u = Math.random();
  const v = Math.random();
  const z = Math.sqrt(-2 * Math.log(u)) * Math.cos(2 * Math.PI * v);
  const seconds = Math.max(0.5, meanSeconds * Math.exp(0.5 * z));
  sleep(seconds);
}

export const options = {
  scenarios: {
    browse_buy: {
      executor: 'ramping-vus',
      startVUs: 0,
      stages: [
        { duration: '2m', target: 30 },
        { duration: '5m', target: 80 },
        { duration: '2m', target: 80 },
        { duration: '2m', target: 0 },
      ],
      exec: 'journey',
      tags: { flow: 'checkout' },
    },
  },
  thresholds: {
    'http_req_duration{step:search}': ['p(95)<300'],
    'http_req_duration{step:checkout}': ['p(95)<800', 'p(99)<1500'],
    http_req_failed: ['rate<0.01'],
  },
};

export function journey() {
  const headers = {
    Authorization: `Bearer ${__ENV.TOKEN}`,
    'Content-Type': 'application/json',
  };

  const search = http.get(`${BASE}/v1/search?q=headphones`, {
    headers,
    tags: { step: 'search', flow: 'checkout' },
  });
  check(search, { 'search ok': (r) => r.status === 200 });
  humanPause(4);

  const detail = http.get(`${BASE}/v1/products/SKU-42`, {
    headers,
    tags: { step: 'detail', flow: 'checkout' },
  });
  check(detail, { 'detail ok': (r) => r.status === 200 });
  humanPause(6);

  const checkout = http.post(
    `${BASE}/v1/checkout`,
    JSON.stringify({ sku: 'SKU-42', qty: 1 }),
    { headers, tags: { step: 'checkout', flow: 'checkout' } }
  );
  check(checkout, { 'checkout ok': (r) => r.status >= 200 && r.status < 300 });
  humanPause(2);
}
```

**Patrones que funcionan**

- **Calibra contra analytics** — exporta histogramas de tiempo entre eventos de producto; ajusta media de `humanPause`.
- **Sleep solo tras éxito** — no pauses sobre 4xx/5xx si el flujo real aborta; modela abandono con `if (!check(...)) return`.
- **Arrival rate para APIs abiertas** — si prod mide req/s independiente de pacing, usa [ramping arrival rate](/es/blog/k6-ejecutores-ramping-arrival-rate) y think time mínimo.
- **Tags por paso** — umbrales segmentados (`step:checkout`) detectan cuellos en el paso lento del journey.

**Anti-patrones a evitar**

- Copiar sleeps de tutoriales ajenos sin validar contra tus trazas.
- `sleep(0)` en closed model y extrapolar «usuarios concurrentes» a stakeholders.
- Mezclar closed model con objetivo de req/s de marketing—son preguntas distintas.

**Tip pro (comando de ejemplo):**

```bash
k6 run journey.js --summary-trend-stats="avg,min,max" --tag flow=checkout
```

**Qué demuestra este comando:** el summary expone tendencias por tag de paso—útil para comparar si el pacing produce RPS alineado a analytics (~40 vs ~500).

## Marco de decisión: cuánto sleep y qué executor

| Situación | Acción recomendada |
|:---|:---|
| App con login, carrito, wizard—«usuarios activos» | `ramping-vus` + think time calibrado a sesiones |
| API pública, métrica principal = req/s | `ramping-arrival-rate`; think time mínimo o cero |
| Flujo con paso lento (pago, KYC) | Sleep largo solo en ese paso; umbrales por `step` |
| CI smoke—salud rápida | Sleep corto fijo; no confundir con capacity test |
| Comparar builds | Mismo executor, mismos sleeps, mismos stages |

**Usa think time largo si** analytics muestra minutos entre acciones y modelas closed concurrency.

**Usa think time mínimo si** el sistema es API-first y prod reporta arrival rate desacoplado del response time.

**Usa distribución log-normal si** la mediana y la cola larga importan—uniforme subestima ráfagas de usuarios rápidos.

## Observabilidad, documentación y siguientes pasos

El pacing solo sirve si documentas de dónde salieron los números. Antes de presentar capacity:

- [ ] Registra fuente de think times (Mixpanel, Amplitude, traces APM) en el README del escenario.
- [ ] Compara RPS observado en k6 vs dashboard de prod para el mismo flujo.
- [ ] Documenta executor (closed vs open) junto a los sleeps—evita interpretaciones cruzadas.
- [ ] Revalida sleeps tras rediseños de UX que cambian tiempo entre pasos.
- [ ] Archiva git SHA y parámetros de `humanPause` por corrida de regresión.

## Cómo Performate simplifica pacing sin reescribir sleeps en cada script

Ajustar `sleep(3)` en cuatro archivos cada vez que producto cambia el funnel no escala. Abajo hay un **ejemplo concreto de flujo** para el journey browse→buy de arriba.

**Ejemplo: flujo multipaso con pacing visual y comparación de RPS**

1. **Importa los tres requests** (search, detail, checkout) desde Postman en orden de flujo. *Problema resuelto:* un journey en un workspace, no tres scripts desconectados.
2. **Define pausas entre pasos** en el editor visual—4 s, 6 s, 2 s alineados a analytics. *Problema resuelto:* tuning sin buscar líneas `sleep` en JS.
3. **Configura escenario ramping-vus** 30→80 para modelar sesiones concurrentes. *Problema resuelto:* closed model explícito para stakeholders de producto.
4. **Corre y compara RPS resultante** con el dashboard de prod en la vista de reporte. *Problema resuelto:* detectas desalineación de pacing antes del capacity review.
5. **Duplica escenario con arrival rate** para el mismo flujo si también necesitas modelo open—compara side by side. *Problema resuelto:* dos preguntas, una fuente de requests.
6. **Exporta script k6** con sleeps y executor para CI ([pruebas de carga en CI/CD](/es/blog/pruebas-de-carga-en-ci-cd)).

Ese flujo conecta directo con el `cta` de este post: escenarios que se sienten humanos sin matemática de fantasía ni días de pegamento.

## Cierre

El riesgo de concurrencia mal modelada es un **problema de pacing**, no solo de VU count. Calibra think time contra telemetría real, elige closed vs open según la pregunta, y valida que el RPS de la corrida esté en el mismo orden de magnitud que producción.

Corre el journey con pacing de analytics esta semana—y anota si los req/s observados están dentro de 2× del dashboard de prod o si estás stressando con bots.

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