timeout-minutes en GitHub Actions: no dejes el default de 6 horas
Resumen
El job de Actions sin timeout-minutes usa 360 minutos en runners hosted. Un test colgado quema minutos y presupuesto. Pon 10–20 en CI de PR y un techo mayor solo en jobs que lo justifiquen. Workflow syntax: jobs.<id>.timeout-minutes.

Qué resuelve
Esta pieza se queda en la decisión práctica: qué instalar, qué riesgo agrega y cómo aplicarlo sin romper operación.
GitHub-hosted: el máximo de un job es 360 minutos (6 h) y ese es el default si no pones timeout-minutes. Un pnpm test que se cuelga en un wait infinito cobra 6 horas. El agente que copia un workflow sin timeout está quemando la org.
También existe timeout por step. El del job corta todo el job.
No sustituye AbortSignal en tools (eso es runtime de la app). Aquí es CI. El curso instalar un agente no cubre minutos de Actions. gh pr no paga la factura.
Números de partida
jobs:
test:
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- run: pnpm test
timeout-minutes: 10
| Job | timeout-minutes |
|---|---|
| lint / typecheck | 5–10 |
| unit tests | 10–20 |
| e2e | 30–45 |
| build + deploy | 15–30 |
| nightly largo | lo que mida, nunca 360 por olvido |
Self-hosted puede tener otros techos; igual pon número.

Qué no hace el agente
- Dejar el default.
timeout-minutes: 360“por si acaso”.- Subir el timeout en vez de matar el hang (el hang es el bug).
- Un timeout de 2 min en un e2e que siempre tarda 8: rojo eterno, no es “estricto”, es inútil.
Si CI pasa de 12 a 40 min, no subas a 60 a ciegas: mira qué step. Cache, concurrency, o test que espera red.
Receta AGENTS.md
Every new job: timeout-minutes set (15 default for test).
Do not use 360.
If a job times out, fix the hang; don't only raise the cap.

FAQ
¿Matrix? Cada shard es un job; cada uno tiene el timeout.
¿Reusable? El callee puede definir el suyo. El caller no lo pisa mágicamente.
¿Billing? Los minutos cancelados (concurrency) no siempre se cobran igual que un timeout; el timeout sí corre hasta el corte.
¿Services / compose? El hang suele ser wait-for-db. Timeout corto + healthcheck, no 6 h.
Un job que “a veces tarda 14 min” con timeout 15 es frágil: 15 no es margen, es el techo. Mide p95 y pon 2×, no 360. El default de GitHub es un seguro contra olvido, no un SLA.
Verificado 2026-09-03 contra GitHub workflow syntax jobs.<job_id>.timeout-minutes (default/max 360 hosted).
Lecturas relacionadas
Sigue explorando Coding Agents y otras piezas para builders.

git status para coding agents: porcelain, XY, no el long

Reusable workflows: workflow_call, no copies el YAML entre repos

schedule (cron) en GitHub Actions: UTC, no cada minuto
