---
term: 'Jobs em Segundo Plano & Agendadores de Tarefas'
seoTitle: 'Jobs em Segundo Plano e Agendadores: Filas, Workers, Retries'
headline: 'O que são Jobs em Segundo Plano & Agendadores de Tarefas?'
slug: jobs-em-segundo-plano
category: backend-compute
shortDefinition: 'Um job em segundo plano é uma tarefa que roda fora do ciclo de requisição — enfileirada pelo app, executada por workers, com retry em caso de falha.'
relatedTerms:
  - scheduled-cloud-code-cron-jobs
  - cloud-code-serverless-functions
  - pub-sub-pattern
  - webhooks
contrastsWith:
  - scheduled-cloud-code-cron-jobs
aboutTerms:
  - 'Fila de Jobs'
  - 'Worker'
  - 'Fila Dead-Letter'
  - 'Cron'
faq:
  - question: 'O que é um job em segundo plano?'
    answer: 'É uma tarefa que sua aplicação roda fora do ciclo de requisição e resposta: o servidor enfileira o trabalho, responde ao usuário imediatamente, e um worker separado o executa de forma assíncrona — com retries se falhar. Tudo que é lento, repetível ou desnecessário para a resposta pertence ali.'
  - question: 'Por que não fazer o trabalho direto no handler da requisição?'
    answer: 'Porque trabalho lento bloqueia a resposta, prende capacidade do servidor e esbarra em timeouts de gateway — e se o trabalho der erro no meio da requisição, o usuário recebe uma falha mesmo com parte dele já feita. O exemplo canônico: enviar o e-mail de boas-vindas durante o cadastro, onde um servidor de e-mail lento transforma a criação da conta em um spinner.'
  - question: 'Como funciona uma fila de jobs?'
    answer: 'É uma lista durável entre produtores e workers: o app empurra um job — um tipo mais um payload pequeno —, a fila o persiste, e os workers puxam, executam e confirmam com um ack. Jobs sem ack voltam para a fila, e é daí que vem a confiabilidade.'
  - question: 'Qual a diferença entre fila de jobs e fila de mensagens?'
    answer: 'O propósito. Uma fila de mensagens move dados entre serviços — a entrega é o objetivo, e uma mensagem pode se espalhar para muitos consumidores. Uma fila de jobs executa trabalho — ela adiciona retries, agendamento, prioridades e status por cima, e cada job vai para exatamente um worker.'
  - question: 'Qual a diferença entre cron jobs e jobs em segundo plano?'
    answer: 'O gatilho. O cron é guiado por tempo — "toda noite às 2h"; jobs em segundo plano são guiados por eventos — "quando um usuário sobe um arquivo". Os padrões se compõem: um design comum tem o cron enfileirando o lote noturno enquanto os workers o executam com semântica completa de retry.'
  - question: 'Como funcionam os retries de jobs?'
    answer: 'Jobs que falharam rodam de novo automaticamente com backoff exponencial — um segundo, depois dois, quatro, oito — mais um jitter aleatório para que mil falhas não tentem de novo no mesmo instante, com um teto máximo de tentativas. O backoff atravessa falhas transitórias; o teto impede as permanentes de tentarem para sempre.'
  - question: 'Por que jobs em segundo plano precisam ser idempotentes?'
    answer: 'Porque filas prometem execução ao-menos-uma-vez: um worker pode travar depois de fazer o trabalho mas antes de confirmar o ack, e o job roda de novo. Rodar duas vezes não pode cobrar duas vezes — chaves de idempotência, constraints únicas e upserts transformam duplicatas em no-ops.'
  - question: 'O que é uma fila dead-letter?'
    answer: 'É para onde os jobs vão depois de esgotar seus retries — retidos para inspeção, alerta e reexecução manual, em vez de tentarem para sempre ou sumirem em silêncio. Jobs malformados que nunca vão ter sucesso deveriam pular os retries e ir direto para lá.'
codeLanguages: [javascript, dart, swift, kotlin]
externalAuthorities:
  - name: 'Sidekiq Best Practices'
    url: 'https://github.com/sidekiq/sidekiq/wiki/Best-Practices'
  - name: 'Celery — Distributed Task Queue'
    url: 'https://docs.celeryq.dev/en/stable/getting-started/introduction.html'
  - name: 'crontab(5) — Linux manual page'
    url: 'https://man7.org/linux/man-pages/man5/crontab.5.html'
  - name: 'Scaling Slack''s Job Queue — Slack Engineering'
    url: 'https://slack.engineering/scaling-slacks-job-queue/'
  - name: 'Job scheduler — Wikipedia'
    url: 'https://en.wikipedia.org/wiki/Job_scheduler'
cta:
  title: 'Jobs sem fila para operar'
  text: 'Defina um Cloud Job no Back4app e rode sob demanda ou em um agendamento pelo dashboard — status, logs e recorrência incluídos, sem broker, frota de workers ou infraestrutura de fila para operar.'
  linkText: 'Comece grátis'
  linkUrl: 'https://www.back4app.com/signup'
author: 'Back4app Engineering'
publishedDate: '2026-08-21'
translationKey: background-jobs-task-schedulers
---

**Um job em segundo plano é uma tarefa que roda fora do ciclo de requisição — enfileirada pelo app, executada por workers, com retry em caso de falha.** A linha divisória é o tempo: uma resposta deve parecer instantânea (poucas centenas de milissegundos) e *precisa* vencer o timeout do gateway (tipicamente ~30 segundos), enquanto trabalho de verdade — e-mails via SMTP, processamento de imagens, geração de relatórios, APIs de terceiros — leva de segundos a minutos e merece retries. Tudo do lado errado dessa linha é enfileirado, confirmado e feito em outro lugar; em escala, isso é infraestrutura central, não encanamento — uma grande empresa de mensagens processa mais de um bilhão de jobs por dia com exatamente essa maquinaria.

## Principais pontos

| Pergunta | Resposta |
| --- | --- |
| A arquitetura | Produtor enfileira → fila persiste → worker executa e dá ack |
| A linha divisória | Orçamento de resposta ~300 ms; o que é lento ou repetível vira job |
| Os três agendamentos | Imediato · atrasado ("em 24 h") · recorrente (cron) |
| O contrato de confiabilidade | Ao-menos-uma-vez + jobs idempotentes + backoff com jitter + dead letters |
| A falha silenciosa | Nada dá erro quando um job agendado não roda — monitore a ausência |

## O anti-padrão que ensina tudo

```js
// ✗ O cadastro que se faz refém de um servidor de e-mail
app.post('/signup', async (req, res) => {
  const user = await createUser(req.body);
  await sendWelcomeEmail(user);        // SMTP lento? O usuário encara um spinner.
  res.json(user);                      // SMTP fora do ar? O cadastro dá 500 — mas
});                                    // a conta EXISTE. O pior dos mundos.

// ✔ Enfileire e responda
app.post('/signup', async (req, res) => {
  const user = await createUser(req.body);
  await jobs.enqueue('welcomeEmail', { userId: user.id }); // milissegundos
  res.json(user);                      // o e-mail envia, tenta de novo e chega
});                                    // no seu próprio ritmo — invisivelmente
```

O mesmo princípio visto dos dois lados de um backend real — um job sobre os dados, e um cliente que enfileira em vez de esperar:

**JavaScript:**

```javascript
// JavaScript — Cloud Code (cloud/main.js)
// A background job: heavy work outside the request cycle
Parse.Cloud.job('sendWeeklyDigest', async (request) => {
  const query = new Parse.Query(Parse.User).equalTo('digestOptIn', true);
  await query.eachBatch(async (users) => {
    for (const user of users) await sendDigest(user); // per-record, resumable
  }, { useMasterKey: true });
  request.message('Digest run complete'); // status visible in the dashboard
});
// Run on demand or on a schedule from the dashboard — no queue to operate
```

**Flutter:**

```dart
// Flutter / Dart — Back4app Flutter SDK
// The client's rule: never wait on heavy work — enqueue and move on
final export = ParseObject('ExportRequest')
  ..set('user', currentUser)
  ..set('status', 'queued'); // an afterSave trigger starts the work
await export.save(); // returns in milliseconds

// Watch the job's progress like any other data:
final sub = await LiveQuery().client.subscribe(
    QueryBuilder<ParseObject>(ParseObject('ExportRequest'))
      ..whereEqualTo('objectId', export.objectId));
sub.on(LiveQueryEvent.update, (job) {
  if (job.get<String>('status') == 'done') openReport(job.get('fileUrl'));
});
```

**Swift:**

```swift
// iOS / Swift — Back4app Swift SDK
// The client's rule: never wait on heavy work — enqueue and move on
var export = ExportRequest()
export.status = "queued" // an afterSave trigger starts the work
let saved = try await export.save() // returns in milliseconds

// Watch the job's progress like any other data:
let sub = try await ExportRequest.query("objectId" == saved.id).subscribe()
sub.handleEvent { _, event in
    if case .updated(let job) = event, job.status == "done" {
        openReport(job.fileUrl)
    }
}
```

**Kotlin:**

```kotlin
// Android / Kotlin — Back4app Android SDK
// The client's rule: never wait on heavy work — enqueue and move on
val export = ParseObject("ExportRequest")
export.put("user", ParseUser.getCurrentUser())
export.put("status", "queued") // an afterSave trigger starts the work
export.save() // returns in milliseconds

// Watch the job's progress like any other data:
val q = ParseQuery.getQuery<ParseObject>("ExportRequest")
q.whereEqualTo("objectId", export.objectId)
val sub = ParseLiveQueryClient.Factory.getClient().subscribe(q)
sub.handleEvent(SubscriptionHandling.Event.UPDATE) { _, job ->
    if (job.getString("status") == "done") openReport(job.getString("fileUrl"))
}
```

## Produtor, fila, worker

```mermaid
flowchart LR
  accTitle: Arquitetura de produtor, fila e worker com retries e dead letters
  accDescr: A aplicação enfileira jobs em uma fila durável e responde aos usuários imediatamente. Workers puxam os jobs, os executam e confirmam com ack em caso de sucesso. Jobs que falharam são reenfileirados com backoff exponencial, e jobs que esgotam seus retries vão para uma fila dead-letter para inspeção e reexecução.
  A["App (produtor)<br/>enfileira + responde rápido"] --> Q[("Fila<br/>durável, ordenada (mais ou menos)")]
  S["Agendador<br/>cron: reenfileira no horário"] --> Q
  Q --> W["Workers<br/>puxam · executam · dão ack"]
  W -->|"sucesso"| OK["Concluído"]
  W -.->|"falha"| B["Backoff + jitter<br/>atraso, depois reenfileira"] -.-> Q
  B -.->|"tentativas esgotadas"| DL["Fila dead-letter<br/>inspecionar · alertar · reexecutar"]
```

Três papéis, um contrato. O **produtor** — em geral um handler de requisição — cria um job: um nome de tipo e um payload pequeno. A **fila** o persiste; durabilidade é o ponto, já que trabalho que existe apenas na memória de um processo agonizante morre com ele. Os **workers** puxam, executam e *confirmam com ack*; um job só desaparece depois do ack, e é assim que o job de um worker que travou sobrevive para rodar de novo. O vocabulário que vem junto: enqueue/dequeue, acks, visibility timeouts, e a distinção que vale policiar — uma fila de *mensagens* move dados entre serviços (e pode espalhar para [muitos assinantes](/glossary/pub-sub-pattern/)); uma fila de *jobs* executa trabalho, exatamente uma vez por job por worker, com retries e status embutidos.

## Os três agendamentos — e um primer de cron

Todo sistema de jobs implementa os mesmos três modos de tempo: **imediato** (enfileire agora, rode assim que um worker liberar), **atrasado** (enfileire agora, elegível em um momento futuro — lembretes, expiração de trials, e o próprio mecanismo de retry) e **recorrente** (um agendador reenfileira por calendário). Agendamentos recorrentes quase sempre são escritos nos cinco campos do [cron](https://man7.org/linux/man-pages/man5/crontab.5.html):

```text
┌ minuto (0-59)  ┌ hora (0-23)  ┌ dia do mês  ┌ mês  ┌ dia da semana
0 2 * * *      → todo dia às 02:00
*/15 * * * *   → a cada 15 minutos
0 9 * * 1     → segundas-feiras às 09:00

Duas minas do agendador: transições de horário de verão (02:30 some ou
acontece duas vezes — agende em UTC) e sobreposição (uma execução que dura
mais que o intervalo precisa de um lock, ou duas cópias processam os
mesmos dados).
```

## Filas de jobs vs. filas de mensagens vs. agendadores

| | Fila de jobs | Fila de mensagens | Agendador |
| --- | --- | --- | --- |
| Unidade | Um job para executar | Uma mensagem para entregar | Um horário para disparar |
| Consumidores | Exatamente um worker | Um ou [muitos assinantes](/glossary/pub-sub-pattern/) | Os jobs que ele enfileira |
| Vem com | Retries, status, prioridades, atraso | Durabilidade, roteamento, fan-out | Calendários, recorrência |
| Nomes open-source | Sidekiq, Celery, BullMQ | RabbitMQ, Kafka, Redis | cron, Quartz |
| Compõe como | Executa o que os eventos exigem | Transporta entre sistemas | Alimenta a fila na hora certa |

A composição é a resposta para a maioria dos debates de "qual deles?": agendadores decidem *quando*, filas guardam *o quê*, workers fazem o *fazer* — e um lote noturno é o cron enfileirando jobs que os workers executam com semântica completa de retry.

## O contrato de confiabilidade

As peças costumam ser ensinadas separadas; elas são um único contrato. **A fila promete ao-menos-uma-vez** — um worker que trava depois do trabalho mas antes do ack significa que o job roda de novo; isso é inevitável, não desleixo. **Você promete idempotência** em troca: deduplique por um ID de job, proteja com constraints únicas, escreva com upserts, para que a segunda execução seja um no-op em vez de uma segunda fatura. **Retries com backoff exponencial e jitter** atravessam falhas transitórias — 1 s, 2 s, 4 s, com aleatoriedade para que mil jobs falhando juntos não tentem de novo juntos, uma cortesia que [terceiros com rate limit](/glossary/pt/rate-limiting-de-api/) vão impor se você não a estender. **A fila dead-letter pega o resto**: depois do teto de tentativas, os jobs estacionam onde humanos podem inspecioná-los, corrigi-los e reexecutá-los — e jobs permanentemente malformados deveriam pular o teatro dos retries e ir direto para lá.

## Projetando jobs bem feitos

As regras em que os frameworks de fila concordam, reunidas: **passe IDs, não objetos** — um payload de job com `userId: "u-8fk2"` rebusca estado fresco na hora de rodar, enquanto um objeto de usuário serializado já está velho no momento em que foi enfileirado; **mantenha payloads pequenos** e JSON-simples, nunca segredos; **um job por registro** — um job por usuário que falha refaz um usuário, um mega-job refaz todo mundo; **torne trabalho longo retomável** — divida em blocos, registre checkpoints de progresso e saia graciosamente em sinais de shutdown no meio de um bloco; e **assuma concorrência** — dois workers um dia vão processar jobs adjacentes tocando a mesma linha, uma questão de locking que você responde no design ou em um incidente.

## De olho na fila

Falha em segundo plano é silenciosa — nenhum usuário vê uma página de erro quando o job do resumo morre. Os quatro medidores que substituem a página de erro: **profundidade da fila** (backlog acumulando significa que os workers estão perdendo); **idade do job** medida do enfileiramento à conclusão — um job processado em 200 ms depois de esperar 40 minutos é um job de 40 minutos para o usuário; **taxas de falha e de dead-letter** com alertas sobre a fila dead-letter, porque jobs estacionados que alguém esqueceu são dados quietamente não processados; e **execuções perdidas** do trabalho agendado — a mais traiçoeira delas, já que um agendamento que nunca disparou não produziu erro, linha de log ou job algum. Alarme sobre a ausência.

## Casos de uso comuns

- **E-mail e notificações** — o adiamento canônico: enfileire no cadastro, entregue com retries.
- **Processamento de mídia** — resizes, transcodes, thumbnails: minutos de CPU que nenhuma requisição deveria esperar.
- **Relatórios e exports** — gere em segundo plano, notifique quando o arquivo estiver pronto.
- **Sincronização com terceiros** — syncs de CRM e entregas de [webhook](/glossary/pt/webhooks/), com backoff contra remotos instáveis.
- **Limpeza e manutenção** — varreduras de TTL, poda de órfãos, montagem de resumos no cron noturno.

## Qual padrão você precisa? Matriz de decisão

| O trabalho parece | Use |
| --- | --- |
| Disparado por ações de usuário, volume variável | Fila de jobs + workers |
| Calendário fixo, limitado, previsível | Job agendado (cron) |
| Lote noturno sobre muitos registros | O cron enfileira; workers executam por registro |
| Serviços contando coisas uns aos outros | [Fila de mensagens / pub-sub](/glossary/pub-sub-pattern/) |
| Trabalho lento dentro de um handler hoje | O refactor acima — enfileire e responda |
| Precisa sobreviver a crashes e repetir com segurança | Qualquer um destes — mais o contrato de confiabilidade |

## Limitações e trade-offs

- **Eventual, não instantâneo.** Trabalho enfileirado acontece *depois* — UIs precisam de estados pendentes, e o "depois" precisa de um limite que alguém escolheu de propósito.
- **O estado se move fora da banda.** Resultados chegam por campos de status, callbacks ou notificações — a simplicidade requisição-resposta foi gasta; orce o encanamento.
- **A infraestrutura é real.** Brokers, workers e agendadores são serviços com seus próprios modos de falha — ou problema de uma plataforma, que é o argumento dos jobs gerenciados.
- **Duplicatas são garantidas, eventualmente.** Ao-menos-uma-vez é o contrato; todo job não idempotente é um incidente com hora marcada.
- **Filas escondem sobrecarga com graça — graça demais.** Um backlog crescendo parece calmo até a idade dos jobs explodir; alarmes de profundidade e idade são o mecanismo de honestidade.

## Jobs em Segundo Plano no Back4app

O Back4app é uma plataforma open-source de Backend as a Service (BaaS) que combina banco de dados gerenciado, APIs REST e GraphQL geradas automaticamente, autenticação, armazenamento de arquivos e funções serverless com Cloud Code. Jobs aqui são [Cloud Code](/glossary/pt/cloud-code-funcoes-serverless/) com um agendamento: defina `Parse.Cloud.job` — as abas de código mostram um job de resumo iterando usuários com `eachBatch`, por registro e retomável — e rode sob demanda ou em recorrência estilo cron pelo dashboard, com status e logs no painel de Jobs; sem broker para provisionar, sem frota de workers para escalar, sem serviço de fila para manter vivo. A metade orientada a eventos se compõe dos mesmos primitivos: um handler de requisição grava uma linha com `status: "queued"`, um trigger `afterSave` inicia o trabalho, e os clientes acompanham o progresso por [Live Queries](/glossary/pt/live-queries-tempo-real/) em vez de fazer polling — o padrão produtor/worker expresso como dados, com o contrato de confiabilidade (IDs nos payloads, handlers idempotentes, status sobre o qual dá para alarmar) como sua disciplina de design em vez de sua infraestrutura.
