Offline Queue: principios, estrategias y mecanismos de funcionamiento

Autor: IT Sectr Publicado: 2026-06-13 Tiempo de lectura: 10 min

Offline Queue es un mecanismo que guarda las operaciones del usuario localmente cuando el dispositivo está fuera de red y las envía al servidor tras restablecer la conexión. Sin una cola offline, el usuario pierde todas las acciones realizadas sin internet, lo cual es inaceptable en aplicaciones móviles. Según Google Developers (2025), implementar una arquitectura offline-first aumenta la retención de usuarios en un 30% en regiones con internet inestable.

Puntos clave

  • Offline Queue — una cola FIFO de operaciones que el usuario realiza sin internet, para su posterior sincronización.
  • Persistent storage — la cola se almacena en una BD local (SQLite, Room) para conservarse al reiniciar la aplicación.
  • Exponential backoff — estrategia de reintentos con intervalos crecientes cuando falla el envío.
  • Conflict resolution — mecanismo de resolución de colisiones cuando los cambios offline entran en conflicto con los datos del servidor.
  • Idempotency keys — claves únicas de operación para evitar duplicados en el servidor al reenviar.

¿Qué es una cola offline?

Offline Queue es una colección ordenada de operaciones (crear, actualizar, eliminar) que la aplicación guarda localmente cuando el dispositivo no tiene acceso a la red. Una vez restablecida la conexión, la cola envía las operaciones al servidor en el mismo orden en que el usuario las realizó.

Imagina un escenario: un usuario de mensajería escribe mensajes en el metro sin internet. Cada toque de “Enviar” se añade a la Offline Queue. Cuando el tren sale del túnel y la red aparece, todos los mensajes se envían automáticamente. Experiencia de usuario — sin interrupciones: no nota que estuvo offline, excepto por una ligera demora en el envío.

Según Uber Engineering (2024), su cola offline procesa más de 2 millones de operaciones al día en regiones con mala calidad de conexión. La cola usa almacenamiento local Room con orden FIFO y un mecanismo de entrega garantizada 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 operación contiene todos los datos necesarios para el reenvío: endpoint, cuerpo de la solicitud, marca de tiempo e idempotencyKey. Room DB garantiza la persistencia de la cola al reiniciar la aplicación y ante fallos del SO.

Por qué se necesita una cola de operaciones en una app móvil

Garantía de entrega — el objetivo principal de la cola. El usuario debe tener la seguridad de que su acción (enviar un mensaje, dar like, hacer un pedido) se completará, incluso si la red no está disponible en ese momento. Offline Queue con mecanismo de reintento garantiza la entrega eventual.

Mejora de la UX en condiciones de conectividad deficiente — según GSMA Mobile Economy Report (2025), alrededor del 40% de los usuarios móviles en el mundo tienen conexiones a internet inestables. Offline Queue hace que la aplicación sea utilizable en el metro, ascensores, áreas remotas — en cualquier lugar donde la conectividad sea intermitente.

Reducción de la pérdida de datos — sin cola, todas las acciones realizadas offline se pierden. Un usuario podría llenar un formulario extenso, tocar “Enviar” y ver un error de red — toda la entrada se pierde. Offline Queue guarda los datos y los envía en la primera oportunidad. Auto-guardado en Google Docs es un ejemplo clásico de cola offline para documentos.

Sincronización asíncrona — la cola permite que la aplicación no bloquee la interfaz de usuario durante el envío. El usuario sigue trabajando mientras el gestor de sincronización procesa la cola en segundo plano. Esto sigue los principios de Arquitectura Reactiva y mejora la capacidad de respuesta de la interfaz.

Arquitectura de la cola offline: almacenamiento y procesamiento

Tres capas de la cola: almacenamiento (persistencia), planificador (scheduler) y ejecutor. Almacenamiento — Room con una tabla QueuedOperation. Planificador — WorkManager (Android) o BGTaskScheduler (iOS) que inicia la sincronización cuando aparece la red. Ejecutor — un iterador FIFO secuencial que envía operaciones una por una.

Orden de procesamiento — crítico para la consistencia de los datos. Si un usuario creó un registro y luego lo editó, ambas operaciones deben enviarse en el mismo orden. De lo contrario, el servidor recibe primero una actualización de un registro inexistente — error. FIFO secuencial — orden estricto con control de dependencias entre operaciones.

Estrategia de fusión — si la cola tiene un CREATE seguido inmediatamente de un DELETE del mismo objeto, ambas operaciones pueden eliminarse sin envío: el estado final es que el objeto no se creó. Del mismo modo, CREATE + UPDATE se pueden fusionar en un solo CREATE con los datos más recientes. Optimización de cola reduce la cantidad de solicitudes HTTP y acelera la sincronización.

Según Android Developers (2025), WorkManager es la forma preferida de manejar Offline Queue en Android: garantiza la ejecución incluso tras reiniciar el dispositivo, admite restricciones de red y permite configurar políticas de reintento a travé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 procesa lotes de operaciones y devuelve Result.retry() en caso de fallo — WorkManager reintenta automáticamente con retroceso exponencial. Esta es la forma más sencilla de obtener una Offline Queue confiable en Android.

Estrategias de reintento: exponential backoff y política de reintentos

Exponential Backoff — estrategia estándar de reintentos con intervalos crecientes: 2 seg, 4 seg, 8 seg, 16 seg y así hasta un umbral máximo. Esto evita la sobrecarga repetida del servidor si está temporalmente no disponible. La biblioteca Java Resilience4j (2024) proporciona una implementación lista de Retry con backoff configurable.

Número máximo de intentos — parámetro crítico. Si después de 5–10 intentos la operación falla, más reintentos son derrochadores e inútiles. Se recomienda una dead letter queue: tras agotar los intentos, la operación se mueve a una tabla separada para análisis manual. Según Microsoft Patterns & Practices (2024), una dead letter queue simplifica la depuración de problemas de sincronización y evita que operaciones erróneas bloqueen la cola.

Jitter — variación aleatoria — añadir un número aleatorio al intervalo de backoff. Si mil dispositivos recuperan la red simultáneamente tras una interrupción, todos comienzan a sincronizar al mismo tiempo. Jitter los distribuye en el tiempo, evitando Cache Stampede en el servidor. Jitter completo: delay = random(0, backoff) — recomendado por AWS (2024) para clientes de API.

Resolución de conflictos: cómo resolver colisiones de datos

Last Write Wins (LWW) — la estrategia más simple: en caso de conflicto, gana la operación con la marca de tiempo más reciente. LWW requiere sincronización de tiempo — la marca de tiempo debe generarse en el servidor o usar un Reloj Lógico (relojes de Lamport). Desventaja: los datos de un usuario pueden ser sobrescritos por los de otro sin advertencia.

OT (Transformación Operacional) — el algoritmo usado por Google Docs y Figma para edición colaborativa en tiempo real, incluido el modo offline. OT transforma las operaciones para que puedan aplicarse a cualquier estado del documento, garantizando consistencia sin bloqueos. CRDT (Tipos de Datos Replicados Sin Conflicto) — alternativa a OT que gana popularidad en apps móviles: los datos se estructuran para que los conflictos sean matemáticamente resolubles sin un servidor central.

Fusión personalizada — para apps con modelos de datos simples (notas, contactos), se pueden implementar reglas de fusión personalizadas. Por ejemplo, para una nota: si el texto se modifica en dos versiones, fusionarlas como concatenación con un separador. Conflicto resuelto por el usuario — si la fusión automática es imposible, mostrar al usuario ambas versiones y que elija. Dropbox (2024) usa este enfoque para conflictos de archivos offline, creando copias con el prefijo “Conflicted Copy”.

Claves de idempotencia — protección contra duplicados

Clave de Idempotencia — un identificador único de operación que el servidor usa para detectar solicitudes duplicadas. Si el cliente envía la misma solicitud con la misma clave, el servidor devuelve el resultado de la operación ya completada sin ejecutarla de nuevo. Esto es críticamente importante para Offline Queue, donde los reenvíos son posibles debido a errores de red.

El formato de la clave de idempotencia es un UUID o un hash de los parámetros de la solicitud. El servidor debe almacenar las claves completadas junto con el resultado durante algún tiempo (normalmente 24 horas) para detectar duplicados. La API de Stripe (2024) es el ejemplo de referencia: la clave se pasa en el encabezado Idempotency-Key, y las solicitudes repetidas con la misma clave devuelven una respuesta en caché.

Generación del lado del cliente — la clave se crea en el cliente antes de enviar la operación y se almacena en la tabla QueuedOperation. Al reintentar, la clave no cambia. Arquitectura exactly-once — la combinación de una clave de idempotencia en el cliente y la desduplicación en el servidor es la única forma de garantizar que una operación no se ejecute dos veces.

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 operación recibe dos UUID: uno — el identificador del registro en la cola, el segundo — la clave de idempotencia para el servidor. La desduplicación del lado del servidor mediante idempotencyKey garantiza que incluso al reenviar, el pedido no se duplique.

Preguntas frecuentes

¿En qué se diferencia Offline Queue del caché?

El caché almacena copias de datos para lectura rápida offline. Offline Queue almacena operaciones del usuario para su posterior escritura en el servidor. El caché funciona para lectura, la cola para escritura. Ambos componentes pueden coexistir en una arquitectura offline-first.

¿Qué tamaño de cola es seguro para un dispositivo móvil?

Límite recomendado — 100–500 operaciones. Más crea riesgo de desbordamiento de memoria y sincronización larga al restaurar la red. Al superar el límite, la aplicación debe advertir al usuario y sugerir priorizar operaciones. Límite razonable — 50 operaciones de actualización + 10 de creación.

¿Cómo manejar operaciones obsoletas en la cola?

Operaciones de más de 7 días con cero éxitos se mueven a una dead letter queue. Analícelas manualmente: la API puede haber cambiado y el endpoint ya no existe. Limpieza automática — una tarea HealthCheck ejecutada diariamente elimina o archiva las operaciones vencidas.

¿Qué pasa si una operación depende de otra que aún no se ha enviado?

Use un grafo de dependencias (DAG): cada operación contiene una lista de parentOperationId que deben completarse antes de su envío. Una consulta Room con ORDER BY parent devuelve las operaciones en la secuencia correcta. Envío en cascada — tras completar cada operación, verifique si las operaciones hijas están desbloqueadas.

¿Cómo probar Offline Queue?

Use la Network Less Tool en Android Emulator o Network Link Conditioner en iOS Simulator para simular pérdida de red. Escriba pruebas que añadan operaciones a la cola en modo offline, restauren la conexión y verifiquen que todas las operaciones se envían y son procesadas por el servidor.

Resumen

  • Offline Queue — una cola FIFO de operaciones guardada localmente para su envío tras restablecer la conexión.
  • Persistent storage (Room / SQLite) — necesario para conservar la cola al reiniciar la aplicación.
  • Exponential backoff con jitter — la estrategia de reintento estándar para evitar la sobrecarga del servidor.
  • Conflict resolution — LWW, OT, CRDT o reglas personalizadas para resolver colisiones de datos offline.
  • Idempotency key — UUID de cada operación para garantizar la entrega exactly-once en el servidor.
  • Dead letter queue — aislamiento de operaciones problemáticas tras agotar los reintentos para análisis manual.
  • Mejor práctica para Android — WorkManager + Room + ExponentialBackoff — una combinación probada de Google.

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también