Offline Queue: princípios, estratégias e mecanismos de funcionamento

Autor: IT Sectr Publicado: 2026-06-13 Tempo de leitura: 10 min

Offline Queue é um mecanismo que salva as operações do usuário localmente quando o dispositivo está offline e as envia ao servidor após restabelecer a conexão. Sem uma fila offline, o usuário perde todas as ações realizadas sem internet, o que é inaceitável em aplicativos móveis. De acordo com Google Developers (2025), implementar arquitetura offline-first aumenta a retenção de usuários em 30% em regiões com internet instável.

Principais pontos

  • Offline Queue — uma fila FIFO de operações que o usuário realiza sem internet, para sincronização posterior.
  • Persistent storage — a fila é armazenada em um banco de dados local (SQLite, Room) para ser preservada ao reiniciar o aplicativo.
  • Exponential backoff — estratégia de repetição com intervalos crescentes em caso de falha no envio.
  • Conflict resolution — mecanismo de resolução de colisões quando alterações offline entram em conflito com dados do servidor.
  • Idempotency keys — chaves únicas de operação para evitar duplicação no servidor durante o reenvio.

O que é uma fila offline?

Offline Queue é uma coleção ordenada de operações (criar, atualizar, excluir) que o aplicativo salva localmente quando o dispositivo não tem acesso à rede. Uma vez restabelecida a conexão, a fila envia as operações ao servidor na mesma ordem em que o usuário as realizou.

Imagine um cenário: um usuário de mensageiro digita mensagens no metrô sem internet. Cada toque em “Enviar” é adicionado à Offline Queue. Quando o trem sai do túnel e a rede aparece, todas as mensagens são enviadas automaticamente. Experiência do usuário — sem interrupções: ele não percebe que esteve offline, exceto por um pequeno atraso no envio.

De acordo com Uber Engineering (2024), sua fila offline processa mais de 2 milhões de operações por dia em regiões com má qualidade de conexão. A fila usa armazenamento local Room com ordem FIFO e um mecanismo de entrega garantida exactly-once.

kotlin
data class QueuedOperation(
    val id: String,
    val type: OperationType,
    val endpoint: String,
    val payload: String,
    val timestamp: Long,
    val retryCount: Int = 0,
    val idempotencyKey: String
)

Cada operação contém todos os dados necessários para o reenvio: endpoint, corpo da requisição, timestamp e idempotencyKey. Banco de dados Room garante a persistência da fila ao reiniciar o aplicativo e em falhas do SO.

Por que uma fila de operações é necessária em um aplicativo móvel

Garantia de entrega — o principal objetivo da fila. O usuário deve ter a certeza de que sua ação (enviar mensagem, curtir, fazer um pedido) será concluída, mesmo se a rede estiver indisponível no momento. Offline Queue com mecanismo de repetição garante a entrega eventual.

UX melhorada em condições de conectividade precária — de acordo com GSMA Mobile Economy Report (2025), cerca de 40% dos usuários móveis no mundo têm conexões de internet instáveis. Offline Queue torna o aplicativo utilizável no metrô, elevadores, áreas remotas — em qualquer lugar onde a conectividade seja intermitente.

Redução da perda de dados — sem fila, todas as ações realizadas offline são perdidas. Um usuário pode preencher um formulário longo, tocar em “Enviar” e ver um erro de rede — toda a entrada é perdida. Offline Queue salva os dados e os envia na primeira oportunidade. Salvamento automático no Google Docs é um exemplo clássico de fila offline para documentos.

Sincronização assíncrona — a fila permite que o aplicativo não bloqueie a interface do usuário durante o envio. O usuário continua trabalhando enquanto o gerenciador de sincronização processa a fila em segundo plano. Isso segue os princípios da Arquitetura Reativa e melhora a capacidade de resposta da interface.

Arquitetura da fila offline: armazenamento e processamento

Três camadas da fila: armazenamento (persistência), agendador (scheduler) e executor. Armazenamento — Room com uma tabela QueuedOperation. Agendador — WorkManager (Android) ou BGTaskScheduler (iOS) que inicia a sincronização quando a rede aparece. Executor — um iterador FIFO sequencial que envia operações uma por uma.

Ordem de processamento — crítica para a consistência dos dados. Se um usuário criou um registro e depois o editou, ambas as operações devem ser enviadas na mesma ordem. Caso contrário, o servidor recebe primeiro uma atualização de um registro inexistente — erro. FIFO sequencial — ordem estrita com controle de dependências entre operações.

Estratégia de fusão — se a fila tiver um CREATE seguido imediatamente por um DELETE do mesmo objeto, ambas as operações podem ser removidas sem envio: o estado final é que o objeto não foi criado. Da mesma forma, CREATE + UPDATE podem ser mesclados em um único CREATE com os dados mais recentes. Otimização da fila reduz o número de requisições HTTP e acelera a sincronização.

De acordo com Android Developers (2025), WorkManager é a forma preferida de lidar com Offline Queue no Android: garante a execução mesmo após reiniciar o dispositivo, suporta restrições de rede e permite configurar políticas de repetição através de NetworkType.CONNECTED.

kotlin
class SyncWorker(
    private val context: Context,
    private val params: WorkerParameters
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result = runCatching {
        queueRepository.processNextBatch(batchSize = 10)
        Result.success()
    }.getOrDefault(Result.retry())
}

CoroutineWorker processa lotes de operações e retorna Result.retry() em caso de falha — o WorkManager repete automaticamente com backoff exponencial. Esta é a maneira mais simples de obter uma Offline Queue confiável no Android.

Estratégias de repetição: exponential backoff e política de repetição

Exponential Backoff — estratégia padrão de repetição com intervalos crescentes: 2 seg, 4 seg, 8 seg, 16 seg e assim por diante até um limite máximo. Isso evita a sobrecarga repetida do servidor se ele estiver temporariamente indisponível. A biblioteca Java Resilience4j (2024) fornece uma implementação pronta de Retry com backoff configurável.

Número máximo de tentativas — um parâmetro crítico. Se após 5–10 tentativas a operação falhar, mais repetições são desperdiçadoras e inúteis. Recomenda-se uma dead letter queue: após esgotar as tentativas, a operação é movida para uma tabela separada para análise manual. De acordo com Microsoft Patterns & Practices (2024), uma dead letter queue simplifica a depuração de problemas de sincronização e evita que operações defeituosas bloqueiem a fila.

Jitter — variação aleatória — adicionar um número aleatório ao intervalo de backoff. Se mil dispositivos recuperarem a rede simultaneamente após uma interrupção, todos começam a sincronizar ao mesmo tempo. O Jitter os distribui no tempo, evitando Cache Stampede no servidor. Jitter completo: delay = random(0, backoff) — recomendado pela AWS (2024) para clientes de API.

Resolução de conflitos: como resolver colisões de dados

Last Write Wins (LWW) — a estratégia mais simples: em caso de conflito, vence a operação com o timestamp mais recente. LWW requer sincronização de tempo — o timestamp deve ser gerado no servidor ou usar um Relógio Lógico (relógios de Lamport). Desvantagem: os dados de um usuário podem ser sobrescritos pelos dados de outro sem aviso.

OT (Transformação Operacional) — o algoritmo usado pelo Google Docs e Figma para edição colaborativa em tempo real, incluindo o modo offline. OT transforma as operações para que possam ser aplicadas a qualquer estado do documento, garantindo consistência sem bloqueios. CRDT (Tipos de Dados Replicados Sem Conflito) — uma alternativa ao OT que ganha popularidade em aplicativos móveis: os dados são estruturados para que os conflitos sejam matematicamente resolvíveis sem um servidor central.

Mesclagem personalizada — para aplicativos com modelos de dados simples (notas, contatos), regras de mesclagem personalizadas podem ser implementadas. Por exemplo, para uma nota: se o texto for modificado em duas versões, mesclá-las como concatenação com um separador. Conflito resolvido pelo usuário — se a mesclagem automática for impossível, mostrar ao usuário ambas as versões e deixá-lo escolher. Dropbox (2024) usa essa abordagem para conflitos de arquivos offline, criando cópias com o prefixo “Conflicted Copy”.

Chaves de idempotência — proteção contra duplicação

Chave de Idempotência — um identificador único de operação que o servidor usa para detectar requisições duplicadas. Se o cliente enviar a mesma requisição com a mesma chave, o servidor retorna o resultado da operação já concluída sem executá-la novamente. Isso é criticamente importante para Offline Queue, onde reenvios são possíveis devido a erros de rede.

O formato da chave de idempotência é um UUID ou um hash dos parâmetros da requisição. O servidor deve armazenar as chaves concluídas junto com o resultado por algum tempo (geralmente 24 horas) para detectar duplicatas. A API Stripe (2024) é o exemplo de referência: a chave é passada no cabeçalho Idempotency-Key, e requisições repetidas com a mesma chave retornam uma resposta em cache.

Geração do lado do cliente — a chave é criada no cliente antes de enviar a operação e armazenada na tabela QueuedOperation. Ao repetir, a chave não muda. Arquitetura exactly-once — a combinação de uma chave de idempotência no cliente e desduplicação no servidor é a única maneira de garantir que uma operação não seja executada duas vezes.

kotlin
fun createOperation(type: OperationType, payload: String): QueuedOperation =
    QueuedOperation(
        id = UUID.randomUUID().toString(),
        type = type,
        endpoint = type.endpoint,
        payload = payload,
        timestamp = currentTimeMillis(),
        idempotencyKey = UUID.randomUUID().toString()
    )

Cada operação recebe dois UUIDs: um — o identificador do registro na fila, o segundo — a chave de idempotência para o servidor. A desduplicação do lado do servidor por idempotencyKey garante que mesmo no reenvio, o pedido não seja duplicado.

Perguntas frequentes

Como o Offline Queue difere do cache?

O cache armazena cópias de dados para leitura rápida offline. Offline Queue armazena operações do usuário para posterior escrita no servidor. O cache funciona para leitura, a fila para escrita. Ambos os componentes podem coexistir em uma arquitetura offline-first.

Qual tamanho de fila é seguro para um dispositivo móvel?

Limite recomendado — 100–500 operações. Mais cria risco de estouro de memória e sincronização longa ao restaurar a rede. Ao exceder o limite, o aplicativo deve avisar o usuário e sugerir priorizar operações. Limite razoável — 50 operações de atualização + 10 de criação.

Como lidar com operações obsoletas na fila?

Operações com mais de 7 dias com zero sucessos são movidas para uma dead letter queue. Analise-as manualmente: a API pode ter mudado e o endpoint pode não existir mais. Limpeza automática — uma tarefa HealthCheck executada diariamente remove ou arquiva operações expiradas.

E se uma operação depender de outra que ainda não foi enviada?

Use um grafo de dependências (DAG): cada operação contém uma lista de parentOperationId que devem ser concluídos antes do seu envio. Uma consulta Room com ORDER BY parent retorna as operações na sequência correta. Envio em cascata — após concluir cada operação, verifique se as operações filhas estão desbloqueadas.

Como testar Offline Queue?

Use a Network Less Tool no Android Emulator ou Network Link Conditioner no iOS Simulator para simular perda de rede. Escreva testes que adicionem operações à fila no modo offline, restaurem a conexão e verifiquem se todas as operações foram enviadas e processadas pelo servidor.

Resumo

  • Offline Queue — uma fila FIFO de operações salva localmente para envio após restabelecer a conexão.
  • Persistent storage (Room / SQLite) — necessário para preservar a fila ao reiniciar o aplicativo.
  • Exponential backoff com jitter — a estratégia padrão de repetição para evitar sobrecarga do servidor.
  • Conflict resolution — LWW, OT, CRDT ou regras personalizadas para resolver colisões de dados offline.
  • Idempotency key — UUID de cada operação para garantir entrega exactly-once no servidor.
  • Dead letter queue — isolamento de operações problemáticas após esgotar as tentativas para análise manual.
  • Melhor prática para Android — WorkManager + Room + ExponentialBackoff — uma combinação comprovada do Google.

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também