Guías

Cómo ejecutar tareas en segundo plano en una app web: colas, planificadores y cron

Para ejecutar tareas en segundo plano en una app web, primero divide el trabajo en dos tipos. Las tareas disparadas por un evento (enviar un correo de bienvenida, procesar una subida) se pueden guardar en una cola de tareas, a menudo una tabla de tu base de datos, y atenderlas con un worker que reintenta. Las tareas programadas (un informe nocturno, recordatorios cada 15 minutos) necesitan algo que se dispare según un horario: la función cron de un alojamiento, o un planificador externo que llama a un endpoint protegido de tu app. Haz siempre que las tareas sean seguras de ejecutar dos veces, registra los fallos y nunca confíes en un temporizador dentro de un servidor que pueda dormirse o reiniciarse.

Esta guía explica las opciones, cuándo encaja cada una y cómo configurarlas con un creador de apps con IA, incluso en alojamientos que escalan a cero.

Qué cuenta como tarea en segundo plano

Cualquier cosa lenta, poco fiable o que no es necesaria para la respuesta inmediata del usuario:

  • Enviar correos, notificaciones y recibos
  • Redimensionar imágenes, transcodificar vídeo, generar PDF
  • Llamar a APIs de terceros lentas, incluidos modelos de IA para tareas largas
  • Importar o sincronizar datos desde otro sistema
  • Limpiezas nocturnas, informes y recordatorios

Hacerlo dentro de la petición vuelve lentas y frágiles las páginas: si el proveedor de correo se cae, el registro del usuario falla. Pasarlo al segundo plano hace que el usuario reciba una respuesta instantánea y que la tarea pueda reintentarse.

Las opciones

OpciónCómo funcionaVentajasInconvenientes
Lanzar y olvidar en el mismo procesoResponde y luego sigue el trabajo en el servidorSin configuraciónSe pierde si el servidor se detiene; sin reintentos
Temporizador en el proceso (setInterval, setTimeout)Un temporizador en el servidor en marchaTrivialNo se ejecuta mientras duerme; se duplica con varias copias
Cola en base de datosTareas guardadas como filas; un worker las reclama y las ejecutaUsa la base de datos que ya tienes; duradera; fácil de inspeccionarTú construyes los reintentos y el bloqueo; hace falta algo que ejecute el worker
Cola dedicada (basada en Redis o gestionada)Un servicio de colas más workersFunciones maduras de reintentos y programaciónOtro servicio que ejecutar y pagar
Servicio alojado de tareas o flujosUn tercero llama a tus endpoints con reintentos y horariosProgramación y reintentos gestionados por tiDependencia del proveedor; otra cuenta y otra clave
Planificador externo que llama a un endpointUn temporizador en otro sitio envía una petición HTTP según horarioFunciona en cualquier alojamiento, incluidos los que escalan a ceroIntervalos mínimos y retrasos; protege el endpoint
Cron integrado del alojamientoLa plataforma ejecuta un comando según horarioSencillo donde existeNo todos los alojamientos lo ofrecen

No hay una única respuesta correcta. Una app pequeña suele necesitar solo una cola en base de datos más un planificador externo.

Por qué los alojamientos que escalan a cero cambian el panorama

Muchos alojamientos actuales duermen tu app cuando nadie la usa y la despiertan con la siguiente petición. Eso ahorra dinero, pero un servidor dormido no ejecuta código: los temporizadores no se disparan y los workers no sondean. En estos alojamientos, el trabajo programado tiene que empezar con una petición entrante, y la forma más sencilla de generar esa petición es un planificador externo. Cada llamada despierta la app (y a menudo su base de datos), así que llamar cada minuto cuesta más que cada 15 minutos. Elige el horario más lento que cubra la necesidad.

Patrón 1: una cola de tareas en base de datos

Para tareas disparadas por un evento:

  1. Crea una tabla jobs: tipo, carga útil (JSON), estado (pending, running, done, failed), intentos, run_after, last_error, marcas de tiempo.
  2. Cuando ocurre algo, inserta una fila de tarea en la misma transacción que el cambio que lo causó, para que ambas cosas tengan éxito o fallen juntas.
  3. Un worker recoge las tareas vencidas, las marca como running, hace el trabajo y las marca como done.
  4. Si falla, aumenta attempts, fija run_after más tarde (por ejemplo, 1, 5 y luego 30 minutos) y guarda el error. Tras un máximo, márcala como failed y avisa a alguien.

Si puede haber más de un worker a la vez, las tareas deben reclamarse de forma segura. En Postgres, SELECT ... FOR UPDATE SKIP LOCKED permite que cada worker reclame filas distintas sin chocar.

¿Qué ejecuta el worker? En un servidor siempre encendido, un bucle en un proceso separado. En un alojamiento que escala a cero, el endpoint programado del Patrón 2 puede procesar un lote de tareas vencidas en cada llamada.

Patrón 2: un planificador externo que llama a tu app

Para tareas programadas:

  1. Añade un endpoint como POST /api/cron/send-reminders.
  2. Protégelo: exige un token secreto en una cabecera, guardado como secreto en ambos lados, y rechaza cualquier otra cosa.
  3. Hazlo idempotente: ejecutarlo dos veces en el mismo minuto no debe enviar dos recordatorios. Registra lo que se envió.
  4. Mantén cada llamada corta: procesa un lote (por ejemplo, 100 elementos) y deja que la siguiente llamada recoja el resto.
  5. Apunta un planificador hacia él.

Opciones de planificador:

  • Flujos programados de GitHub Actions. Gratis dentro de los límites de uso de GitHub. Según la documentación de GitHub a septiembre de 2026, el intervalo mínimo es una vez cada 5 minutos, las ejecuciones pueden retrasarse en horas de mucha carga (sobre todo al inicio de cada hora), los horarios usan UTC por defecto, y los flujos programados de un repositorio público se desactivan tras 60 días sin actividad en el repositorio.
  • Servicios de cron alojados. Existen muchos servicios cuyo único trabajo es llamar a una URL según un horario. Revisa la fiabilidad, el intervalo mínimo y las alertas antes de depender de uno.
  • El planificador de tu proveedor de nube. Si ya usas un gran proveedor de nube, tendrá un planificador gestionado que puede llamar a un endpoint HTTPS.
  • Un servicio alojado de tareas o flujos. Combinan programación, colas y reintentos, y llaman a tus endpoints en cada paso. Compara precios y límites en la web de cada proveedor.

Patrón 3: que lo haga el proveedor

A veces, la mejor tarea en segundo plano es ninguna:

  • Pagos. Stripe reintenta los pagos fallidos de suscripciones y envía webhooks; tú reaccionas en lugar de sondear. Consulta qué es un webhook.
  • Correo. Los proveedores encolan y reintentan la entrega una vez que les entregas el mensaje.
  • Trabajo masivo con IA. OpenAI y Anthropic ofrecen APIs por lotes para peticiones no urgentes que envías y recoges más tarde.

Indicaciones para tu creador de apps con IA

Para una cola:

Añade una cola de tareas en segundo plano usando una tabla jobs en nuestra base de datos (tipo, payload JSON, estado, intentos, run_after, last_error). Cuando un usuario se registra, inserta una tarea send_welcome_email en la misma transacción en lugar de enviar el correo en línea. Añade una función processJobs(limit) que reclame las tareas vencidas con SELECT ... FOR UPDATE SKIP LOCKED, las ejecute y reintente los fallos tras 1, 5 y 30 minutos, marcándolas como failed tras 4 intentos.

Para un disparador programado:

Añade POST /api/cron/tick protegido por un token bearer del secreto CRON_SECRET; rechaza cualquier petición sin él. Cada llamada ejecuta processJobs(100) y envía los recordatorios de reserva previstos en las próximas 24 horas que aún no se hayan enviado, registrando los recordatorios enviados para que nada se envíe dos veces. Devuelve un resumen en JSON de lo que se ejecutó. Después escribe un flujo de GitHub Actions que llame a este endpoint cada 15 minutos, leyendo la URL y el token de los secretos del repositorio.

Errores habituales

  • Depender de setInterval. Se detiene en silencio cuando el servidor duerme o se reinicia, y se duplica cuando hay dos copias en marcha.
  • Un endpoint cron sin protección. Cualquiera que lo encuentre puede disparar tus tareas o tu factura de correo.
  • Tareas que no son idempotentes. Los reintentos y las llamadas duplicadas del planificador ocurrirán. Diseña pensando en ello.
  • Sin visibilidad de fallos. Una tarea que falla en silencio durante una semana es peor que una que falla ruidosamente. Registra los errores y avisa ante fallos repetidos.
  • Ejecuciones largas en una sola petición. Las peticiones caducan. Procesa por lotes.
  • Programar con demasiada frecuencia. Cada llamada en un alojamiento que escala a cero despierta y factura la app. Ajusta el intervalo a la necesidad real.
  • Zonas horarias. «Las 9 de la mañana» significa cosas distintas para tu planificador (a menudo UTC) y para tus usuarios. Guarda las horas en UTC y convierte por usuario.
  • Secretos en el archivo del flujo. Guarda los tokens en el almacén de secretos del planificador. Consulta cómo mantener seguras las claves de API.

Lista de comprobación

  • El trabajo lento se ha sacado de las peticiones de usuario
  • Las tareas se guardan de forma duradera, no solo en memoria
  • Reintentos con retrasos crecientes y un máximo
  • Cada tarea es segura de ejecutar dos veces
  • El endpoint programado está protegido con un token secreto
  • Cada ejecución procesa un lote acotado
  • Las tareas fallidas son visibles, con alertas
  • El intervalo de programación se eligió teniendo en cuenta el coste de alojamiento
  • Las horas se guardan en UTC

Tareas en segundo plano en Mythex

La documentación de Mythex no describe tareas programadas ni cron, y las apps publicadas y sus bases de datos duermen cuando están inactivas y se despiertan con la siguiente petición (consulta Límites de alojamiento). Por eso no confíes en temporizadores dentro de tu app. El enfoque que funciona es el de arriba: pide al agente una tabla de tareas y un endpoint protegido por token, y luego apunta un planificador externo a la URL publicada. Guarda el token como secreto del proyecto y recuerda que cada despertar consume créditos mientras la app y la base de datos están activas, así que elige un intervalo razonable. Si tu app necesita un backend de API para esto, la receta backend de API REST es un buen punto de partida, y cómo crear una API REST explica cómo diseñar los endpoints. Si los workers o bots siempre activos son el núcleo de tu producto, quizá te convenga más un alojamiento pensado para procesos persistentes.

Preguntas

¿Qué es una tarea en segundo plano?

Una tarea en segundo plano es trabajo que hace tu app fuera de la petición por la que espera el usuario, como enviar correos, redimensionar imágenes, generar informes o sincronizar datos. El usuario recibe una respuesta rápida, la tarea se ejecuta por separado y puede reintentarse si falla.

¿Cómo ejecuto una tarea programada si mi alojamiento no tiene cron?

Añade un endpoint protegido que haga el trabajo y haz que un planificador externo lo llame según un horario. Las opciones incluyen un flujo programado de GitHub Actions, un servicio de cron alojado o el planificador de tu proveedor de nube. Protege el endpoint con un token secreto.

¿Puedo usar setInterval o setTimeout para tareas programadas?

Solo para tareas pequeñas y poco importantes en un servidor que esté siempre en marcha. Si el servidor se reinicia, escala a cero o ejecuta varias copias, los temporizadores se pierden o se ejecutan más de una vez. Guarda el trabajo programado en una base de datos o usa un planificador.

¿Mythex admite tareas cron?

La documentación de Mythex no describe tareas programadas ni cron, y las apps publicadas duermen cuando están inactivas. El enfoque fiable es que un planificador externo llame a un endpoint protegido de tu app, lo que despierta la app y ejecuta el trabajo.

Mythex · Pricing · Crea lo que quieras con IA · Plantillas de sitios web y apps · Mythex comparado · Glosario de creación de apps con IA · Herramientas gratuitas para crear apps con IA · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)