Offline Queue: principes, strategieën en werkingsmechanismen

Auteur: IT Sectr Gepubliceerd: 2026-06-13 Leestijd: 10 min

Offline Queue is een mechanisme dat gebruikersbewerkingen lokaal opslaat wanneer het apparaat offline is en deze naar de server stuurt nadat de verbinding is hersteld. Zonder offline wachtrij verliest de gebruiker alle acties die zonder internet zijn uitgevoerd, wat in mobiele apps onaanvaardbaar is. Volgens Google Developers (2025) verhoogt de implementatie van offline-first architectuur de gebruikersretentie met 30% in regio’s met onstabiel internet.

Belangrijkste punten

  • Offline Queue — FIFO-wachtrij van bewerkingen die de gebruiker zonder internet uitvoert, voor latere synchronisatie.
  • Persistent storage — de wachtrij wordt opgeslagen in een lokale database (SQLite, Room) om behouden te blijven bij het herstarten van de app.
  • Exponential backoff — strategie voor herhaalde pogingen met een oplopend interval bij mislukte verzending.
  • Conflict resolution — mechanisme voor het oplossen van conflicten wanneer offline wijzigingen botsen met servergegevens.
  • Idempotency keys — unieke bewerkingssleutels om duplicatie op de server bij opnieuw verzenden te voorkomen.

Wat is een offline wachtrij?

Offline Queue is een geordende verzameling bewerkingen (aanmaken, bijwerken, verwijderen) die de app lokaal opslaat wanneer het apparaat geen netwerktoegang heeft. Zodra de verbinding is hersteld, stuurt de wachtrij de bewerkingen naar de server in dezelfde volgorde waarin de gebruiker ze heeft uitgevoerd.

Stel je een scenario voor: een messenger-gebruiker typt berichten in de metro zonder internet. Elke keer dat hij op „Verzend” drukt, wordt dit aan de Offline Queue toegevoegd. Wanneer de trein de tunnel verlaat en het netwerk verschijnt, worden alle berichten automatisch verzonden. De gebruikerservaring is naadloos: hij merkt niet dat hij offline was, behalve een lichte vertraging bij het verzenden.

Volgens Uber Engineering (2024) verwerkt hun offline wachtrij meer dan 2 miljoen bewerkingen per dag in regio’s met een slechte verbindingskwaliteit. De wachtrij gebruikt lokale Room-opslag met FIFO-volgorde en een exactly-once leveringsmechanisme.

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
)

Elke bewerking bevat alle gegevens die nodig zijn voor opnieuw verzenden: endpoint, verzoeklichaam, tijdstempel en idempotencyKey. Room-database garandeert het behoud van de wachtrij bij het herstarten van de app en OS-crashes.

Waarom een bewerkingenwachtrij in een mobiele app nodig is

Leveringsgarantie is de belangrijkste taak van de wachtrij. De gebruiker moet er zeker van zijn dat zijn actie (bericht verzenden, like, bestelling) wordt uitgevoerd, zelfs als het netwerk op het moment van uitvoeren niet beschikbaar is. Offline Queue met een retry-mechanisme zorgt voor uiteindelijke (eventually) levering.

Verbetering van UX bij slechte verbinding — volgens GSMA Mobile Economy Report (2025) heeft ongeveer 40% van de mobiele gebruikers wereldwijd een onstabiele internetverbinding. Offline Queue maakt de app bruikbaar in de metro, liften, afgelegen gebieden — overal waar de verbinding onderbroken is.

Vermindering van gegevensverlies — zonder wachtrij gaan alle offline uitgevoerde acties verloren. De gebruiker kan een lang formulier invullen, op „Verzend” drukken en een netwerkfout zien — alle ingevoerde gegevens zijn weg. Offline Queue slaat de gegevens op en stuurt ze bij de eerste gelegenheid. Automatisch opslaan in Google Docs is een klassiek voorbeeld van een offline wachtrij voor documenten.

Asynchrone synchronisatie — de wachtrij stelt de app in staat de interface niet te blokkeren tijdens het verzenden. De gebruiker blijft werken, terwijl de synchronisatiemanager de wachtrij op de achtergrond verwerkt. Dit is in overeenstemming met de principes van Reactive Architecture en verbetert de responsiviteit van de interface.

Architectuur van de offline wachtrij: opslag en verwerking

Drie lagen van de wachtrij: opslag (persistence), planner (scheduler) en verwerker (executor). Opslag — Room met tabel QueuedOperation. Planner — WorkManager (Android) of BGTaskScheduler (iOS), die synchronisatie start wanneer het netwerk beschikbaar komt. Verwerker — een sequentiële FIFO-iterator die bewerkingen een voor een verzendt.

Verwerkingsvolgorde is cruciaal voor gegevensconsistentie. Als de gebruiker een record heeft aangemaakt en vervolgens bewerkt, moeten beide bewerkingen in dezelfde volgorde worden verzonden. Anders ontvangt de server eerst een update van een niet-bestaand record — fout. Sequential FIFO — strikte volgorde met controle op afhankelijkheden tussen bewerkingen.

Samenvoegstrategie — als er in de wachtrij een CREATE en direct daarna een DELETE van hetzelfde object staat, kunnen beide bewerkingen zonder verzending worden verwijderd: eindtoestand — object is niet aangemaakt. Evenzo kan CREATE + UPDATE CREATE worden samengevoegd tot één CREATE met de nieuwste gegevens. Optimalisatie van de wachtrij vermindert het aantal HTTP-verzoeken en versnelt de synchronisatie.

Volgens Android Developers (2025) is WorkManager de voorkeursmethode voor het verwerken van Offline Queue op Android: het garandeert uitvoering, zelfs na het herstarten van het apparaat, ondersteunt beperkingen voor netwerkbeschikbaarheid en maakt het mogelijk een herhalingsbeleid in te stellen via 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 verwerkt batchgewijs bewerkingen en retourneert Result.retry() bij een fout — WorkManager herstart automatisch met exponentiële vertraging. Dit is de eenvoudigste manier om een betrouwbare Offline Queue op Android te krijgen.

Herhalingsstrategieën: exponential backoff en retry policy

Exponential Backoff — de standaard herhalingsstrategie met een oplopend interval: 2 sec, 4 sec, 8 sec, 16 sec, enzovoort tot een maximale drempel. Dit voorkomt overbelasting van de server als deze tijdelijk niet beschikbaar is. De Java-bibliotheek Resilience4j (2024) biedt een kant-en-klare Retry-implementatie met configureerbare backoff.

Maximaal aantal pogingen — een kritische parameter. Als een bewerking na 5–10 pogingen niet is gelukt, zijn verdere pogingen zinloos. Dead letter queue wordt aanbevolen: na het uitputten van pogingen wordt de bewerking naar een aparte tabel verplaatst voor handmatige analyse. Volgens Microsoft Patterns & Practices (2024) vereenvoudigt dead letter queue het debuggen van synchronisatieproblemen en voorkomt het dat de wachtrij wordt geblokkeerd door foutieve bewerkingen.

Jitter — willekeurige variatie — het toevoegen van een willekeurig getal aan het backoff-interval. Als duizenden apparaten tegelijkertijd hun verbinding herstellen na een onderbreking, beginnen ze allemaal tegelijk met synchroniseren. Jitter spreidt ze in de tijd, waardoor Cache Stampede op de server wordt voorkomen. Volledige jitter: delay = random(0, backoff) — aanbevolen door AWS (2024) voor API-cliënten.

Conflictoplossing: hoe dataconflicten op te lossen

Last Write Wins (LWW) — de eenvoudigste strategie: bij een conflict wint de bewerking met de nieuwste tijdstempel. LWW vereist tijdsynchronisatie — de timestamp moet op de server worden gegenereerd of Logical Clock (Lamport-klokken) gebruiken. Nadeel: gegevens van de ene gebruiker kunnen zonder waarschuwing worden overschreven door gegevens van een andere gebruiker.

OT (Operational Transformation) — een algoritme dat door Google Docs en Figma wordt gebruikt voor real-time gezamenlijk bewerken, inclusief offline-modus. OT transformeert bewerkingen zodat ze op elke documentstatus kunnen worden toegepast, wat consistentie zonder blokkades garandeert. CRDT (Conflict-Free Replicated Data Types) — een alternatief voor OT dat aan populariteit wint in mobiele apps: gegevens zijn zo gestructureerd dat conflicten wiskundig kunnen worden opgelost, zonder een centrale server.

Aangepast samenvoegen — voor apps met een eenvoudig gegevensmodel (notities, contacten) kunnen aangepaste samenvoegregels worden geïmplementeerd. Bijvoorbeeld voor een notitie: als de tekst in twee versies is gewijzigd, voeg ze dan samen als een concatenatie met een scheidingsteken. Door gebruiker opgelost conflict — als automatisch samenvoegen niet mogelijk is, toon dan beide versies aan de gebruiker en bied een keuze aan. Dropbox (2024) gebruikt deze aanpak voor conflicten in offline bestanden, door kopieën te maken met het voorvoegsel „Conflicted Copy”.

Idempotency keys — bescherming tegen duplicatie

Idempotency Key — een unieke identificatie van een bewerking die de server gebruikt om dubbele verzoeken te detecteren. Als de client hetzelfde verzoek met dezelfde sleutel verzendt, retourneert de server het resultaat van de reeds uitgevoerde bewerking, zonder deze opnieuw uit te voeren. Dit is cruciaal voor Offline Queue, waar opnieuw verzenden mogelijk is bij netwerkfouten.

Formaat van idempotency key — UUID of hash van de verzoekparameters. De server moet de uitgevoerde sleutels samen met het resultaat gedurende enige tijd (meestal 24 uur) opslaan om duplicaten te detecteren. Stripe API (2024) — een referentievoorbeeld: de sleutel wordt doorgegeven in de header Idempotency-Key en herhaalde verzoeken met dezelfde sleutel retourneren het in de cache opgeslagen antwoord.

Generatie aan clientzijde — de sleutel wordt op de client aangemaakt voordat de bewerking wordt verzonden en opgeslagen in de tabel QueuedOperation. Bij een nieuwe poging verandert de sleutel niet. Exactly-once architectuur — de combinatie van idempotency key aan clientzijde en deduplicatie aan serverzijde — de enige manier om te garanderen dat een bewerking niet twee keer wordt uitgevoerd.

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()
    )

Elke bewerking krijgt twee UUID’s: een — de identificatie van het record in de wachtrij, de tweede — de idempotency key voor de server. Server-side deduplicatie op basis van idempotencyKey garandeert dat, zelfs bij opnieuw verzenden, de bestelling niet wordt gedupliceerd.

Veelgestelde vragen

Waarin verschilt Offline Queue van cache?

Cache slaat kopieën van gegevens op voor snel offline lezen. Offline Queue slaat gebruikersbewerkingen op voor latere schrijfacties naar de server. Cache werkt voor lezen, de wachtrij voor schrijven. Beide componenten kunnen naast elkaar bestaan in een offline-first architectuur.

Welke wachtrijgrootte is veilig voor een mobiel apparaat?

Aanbevolen limiet — 100–500 bewerkingen. Meer — risico op geheugenoverloop en lange synchronisatie bij herstel van het netwerk. Bij overschrijding van de limiet moet de app de gebruiker waarschuwen en prioritering van bewerkingen voorstellen. Redelijke beperking — 50 bewerkingen voor updates + 10 voor aanmaak.

Hoe om te gaan met verouderde bewerkingen in de wachtrij?

Bewerkingen ouder dan 7 dagen met nul successen worden naar de dead letter queue verplaatst. Analyseer ze handmatig: mogelijk is de API veranderd en bestaat het endpoint niet meer. Automatische opschoning — een HealthCheck-taak verwijdert of archiveert eenmaal per dag verlopen bewerkingen.

Wat te doen als een bewerking afhankelijk is van een vorige die nog niet is verzonden?

Gebruik een afhankelijkheidsgraaf (DAG): elke bewerking bevat een lijst van parentOperationId die moeten zijn voltooid voordat deze wordt verzonden. Een Room-query met ORDER BY parent retourneert de bewerkingen in de juiste volgorde. Cascade verzending — controleer na voltooiing van elke bewerking of onderliggende bewerkingen zijn gedeblokkeerd.

Hoe test je Offline Queue?

Gebruik Network Less Tool in Android Emulator of Network Link Conditioner in iOS Simulator om netwerkverlies te simuleren. Schrijf tests die bewerkingen aan de wachtrij toevoegen in offline modus, de verbinding herstellen en controleren of alle bewerkingen zijn verzonden en door de server zijn verwerkt.

Samenvatting

  • Offline Queue — FIFO-wachtrij van bewerkingen die lokaal wordt opgeslagen voor verzending na herstel van de verbinding.
  • Persistent storage (Room / SQLite) — verplicht voor het behoud van de wachtrij bij herstart van de app.
  • Exponential backoff met jitter — de standaard herhalingsstrategie om overbelasting van de server te voorkomen.
  • Conflict resolution — LWW, OT, CRDT of aangepaste regels voor het oplossen van offline dataconflicten.
  • Idempotency key — UUID van elke bewerking voor exactly-once levering op de server.
  • Dead letter queue — isolatie van probleembewerkingen na het uitputten van pogingen voor handmatige analyse.
  • Beste praktijk voor Android — WorkManager + Room + ExponentialBackoff — een beproefde combinatie van Google.

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook