Gidsen

Achtergrondtaken draaien in een webapp: wachtrijen, planners en cron

Om achtergrondtaken in een webapp te draaien, splits je het werk eerst in twee soorten. Getriggerde taken (een welkomstmail versturen, een upload verwerken) kun je opslaan in een taakwachtrij, vaak een tabel in je database, en laten afhandelen door een worker met herhaalpogingen. Geplande taken (een nachtelijk rapport, herinneringen elke 15 minuten) hebben iets nodig dat op een schema afgaat: de cron-functie van een host, of een externe planner die een beveiligd eindpunt in je app aanroept. Zorg er altijd voor dat taken veilig twee keer kunnen draaien, registreer fouten, en vertrouw nooit op een timer in een server die kan slapen of opnieuw kan starten.

Deze gids legt de opties uit, wanneer elk past, en hoe je ze instelt met een AI-app-builder, ook op hosts die naar nul schalen.

Wat telt als achtergrondtaak

Alles wat traag of onbetrouwbaar is, of niet nodig is voor de directe reactie aan de gebruiker:

  • E-mails, meldingen en bonnetjes versturen
  • Afbeeldingen verkleinen, video’s transcoderen, PDF’s genereren
  • Trage API’s van derden aanroepen, inclusief AI-modellen voor lange taken
  • Gegevens importeren of synchroniseren vanuit een ander systeem
  • Nachtelijk opschonen, rapporten en herinneringen

Dit binnen het verzoek doen maakt pagina’s traag en kwetsbaar: als de e-mailprovider uitvalt, mislukt de aanmelding van de gebruiker. Naar de achtergrond verplaatsen betekent dat de gebruiker een directe reactie krijgt en de taak opnieuw kan worden geprobeerd.

De opties

OptieHoe het werktVoordelenNadelen
Fire-and-forget in hetzelfde procesReageer, en werk daarna verder op de serverGeen installatieVerloren als de server stopt; geen herhaalpogingen
Timer binnen het proces (setInterval, setTimeout)Een timer in de draaiende serverHeel eenvoudigDraait niet terwijl de app slaapt; dubbel bij meerdere kopieën
DatabasewachtrijTaken opgeslagen als rijen; een worker pakt ze op en draait zeGebruikt de database die je al hebt; duurzaam; makkelijk te inspecterenJe bouwt herhaalpogingen en locking zelf; iets moet de worker draaien
Aparte wachtrij (op Redis gebaseerd of beheerd)Een wachtrijdienst plus workersVolwassen functies voor herhalen en plannenNog een dienst om te draaien en te betalen
Gehoste taak- of workflowdienstEen derde partij roept je eindpunten aan met herhalingen en schema’sPlanning en herhalingen worden voor je afgehandeldAfhankelijk van een leverancier; nog een account en sleutel
Externe planner die een eindpunt aanroeptEen timer elders stuurt op schema een HTTP-verzoekWerkt op elke host, ook op hosts die naar nul schalenMinimale intervallen en vertragingen; beveilig het eindpunt
Ingebouwde cron van de hostHet platform draait op schema een commandoEenvoudig waar het bestaatNiet elke host biedt het

Er is geen enkel juist antwoord. Een kleine app heeft vaak alleen een databasewachtrij en een externe planner nodig.

Waarom hosts die naar nul schalen het verhaal veranderen

Veel moderne hosts zetten je app slapen wanneer niemand hem gebruikt en wekken hem bij het volgende verzoek. Dat bespaart geld, maar een slapende server draait geen code: timers gaan niet af en workers pollen niet. Op deze hosts moet geplande werk starten met een inkomend verzoek, en de makkelijkste bron van dat verzoek is een externe planner. Elke aanroep wekt de app (en vaak de database), dus elke minuut aanroepen kost meer dan elke 15 minuten. Kies het langzaamste schema dat aan de behoefte voldoet.

Patroon 1: een databasewachtrij voor taken

Voor getriggerde taken:

  1. Maak een tabel jobs aan: type, payload (JSON), status (pending, running, done, failed), attempts, run_after, last_error, tijdstempels.
  2. Wanneer er iets gebeurt, voeg je een taakrij in binnen dezelfde transactie als de wijziging die het veroorzaakte, zodat ze samen slagen of mislukken.
  3. Een worker pakt taken op die aan de beurt zijn, zet ze op running, voert het werk uit en zet ze op done.
  4. Bij een fout verhoog je attempts, zet je run_after later (bijvoorbeeld 1, 5, en daarna 30 minuten) en sla je de fout op. Na een maximum zet je de taak op failed en waarschuw je iemand.

Als er meer dan één worker tegelijk kan draaien, moeten taken veilig worden geclaimd. In Postgres laat SELECT ... FOR UPDATE SKIP LOCKED elke worker verschillende rijen claimen zonder met elkaar te botsen.

Wat draait de worker? Op een altijd aanstaande server een lus in een apart proces. Op een host die naar nul schaalt, kan het geplande eindpunt uit Patroon 2 bij elke aanroep een batch verschuldigde taken verwerken.

Patroon 2: een externe planner die je app aanroept

Voor geplande taken:

  1. Voeg een eindpunt toe zoals POST /api/cron/send-reminders.
  2. Beveilig het: vereis een geheim token in een header, dat aan beide kanten als geheim is opgeslagen, en wijs alles af zonder dat token.
  3. Maak het idempotent: twee keer draaien in dezelfde minuut mag niet twee herinneringen versturen. Registreer wat er is verstuurd.
  4. Houd elke aanroep kort: verwerk een batch (bijvoorbeeld 100 items) en laat de volgende aanroep de rest oppakken.
  5. Richt een planner erop.

Keuzes voor een planner:

  • Geplande GitHub Actions-workflows. Gratis binnen de gebruikslimieten van GitHub. Volgens de documentatie van GitHub is vanaf september 2026 het kortste interval eens per 5 minuten, kunnen runs vertraging oplopen op drukke momenten (vooral aan het begin van elk uur), gebruiken geplande schema’s standaard UTC, en worden geplande workflows in een openbare repository uitgeschakeld na 60 dagen zonder activiteit in de repository.
  • Gehoste cronservices. Er bestaan veel diensten die alleen als taak hebben een URL op schema aan te roepen. Controleer betrouwbaarheid, minimaal interval en waarschuwingen voordat je erop vertrouwt.
  • De planner van je cloudprovider. Als je al een grote cloudprovider gebruikt, heeft die een beheerde planner die een HTTPS-eindpunt kan aanroepen.
  • Een gehoste taak- of workflowdienst. Deze combineren planning, wachtrijen en herhalingen, en roepen je eindpunten voor elke stap aan. Vergelijk prijzen en limieten op de site van elke leverancier.

Patroon 3: laat de provider het doen

Soms is de beste achtergrondtaak helemaal geen taak:

  • Betalingen. Stripe probeert mislukte abonnementsbetalingen opnieuw en stuurt webhooks; jij reageert in plaats van te pollen. Zie wat een webhook is.
  • E-mail. Providers zetten berichten in de wachtrij en proberen ze opnieuw te bezorgen zodra jij het bericht hebt aangeleverd.
  • Bulk-AI-werk. OpenAI en Anthropic bieden batch-API’s voor niet-urgente verzoeken die je indient en later ophaalt.

Prompts voor je AI-builder

Voor een wachtrij:

Voeg een achtergrondwachtrij toe met een tabel jobs in onze database (type, payload JSON, status, attempts, run_after, last_error). Wanneer een gebruiker zich aanmeldt, voeg je een taak send_welcome_email in binnen dezelfde transactie, in plaats van inline te versturen. Voeg een functie processJobs(limit) toe die vervallen taken claimt met SELECT ... FOR UPDATE SKIP LOCKED, ze uitvoert, en mislukkingen opnieuw probeert na 1, 5 en 30 minuten, en ze op failed zet na 4 pogingen.

Voor een geplande trigger:

Voeg POST /api/cron/tick toe, beveiligd met een bearer-token uit het geheim CRON_SECRET; wijs elk verzoek zonder dat token af. Elke aanroep draait processJobs(100) en verstuurt boekingsherinneringen die in de komende 24 uur vervallen en nog niet zijn verstuurd, waarbij verstuurde herinneringen worden geregistreerd zodat niets dubbel wordt verstuurd. Geef een JSON-samenvatting van wat er is gedraaid terug. Schrijf daarna een GitHub Actions-workflow die dit eindpunt elke 15 minuten aanroept, met de URL en het token uit de repository-geheimen.

Veelgemaakte fouten

  • Vertrouwen op setInterval. Het stopt stilletjes wanneer de server slaapt of opnieuw start, en verdubbelt wanneer twee kopieën draaien.
  • Een onbeveiligd cron-eindpunt. Iedereen die het vindt, kan je taken activeren, of je e-mailrekening laten oplopen.
  • Taken die niet idempotent zijn. Herhalingen en dubbele aanroepen van de planner gebeuren. Ontwerp daarvoor.
  • Geen zicht op fouten. Een taak die een week stilletjes faalt, is erger dan een die luid faalt. Log fouten en waarschuw bij herhaalde mislukkingen.
  • Lange runs in één verzoek. Verzoeken verlopen na een tijd. Verwerk in batches.
  • Te vaak plannen. Elke aanroep op een host die naar nul schaalt, wekt de app en brengt kosten in rekening. Stem het interval af op de echte behoefte.
  • Tijdzones. „9 uur ’s ochtends” betekent iets anders voor je planner (vaak UTC) en je gebruikers. Sla tijden op in UTC en reken per gebruiker om.
  • Geheimen in het workflowbestand. Bewaar tokens in de geheimenopslag van de planner. Zie hoe je API-sleutels veilig houdt.

Checklist

  • Trage werkzaamheden zijn uit gebruikersverzoeken gehaald
  • Taken zijn duurzaam opgeslagen, niet alleen in het geheugen
  • Herhalingen met oplopende vertragingen en een maximum
  • Elke taak is veilig om twee keer te draaien
  • Geplande eindpunt is beveiligd met een geheim token
  • Elke run verwerkt een begrensde batch
  • Mislukte taken zijn zichtbaar, met waarschuwingen
  • Het schema-interval is gekozen met de hostingkosten in gedachten
  • Tijden zijn opgeslagen in UTC

Achtergrondtaken in Mythex

De documentatie van Mythex beschrijft geen geplande of cron-taken, en gepubliceerde apps en hun databases slapen als ze inactief zijn en worden wakker bij het volgende verzoek (zie Hostinglimieten). Vertrouw dus niet op timers binnen je app. De aanpak die werkt is die hierboven: vraag de agent om een taakentabel en een eindpunt met tokenbeveiliging, en richt daarna een externe planner op je gepubliceerde URL. Bewaar het token als projectgeheim, en onthoud dat elke wekbeurt credits kost voor de tijd dat de app en database wakker zijn, dus kies een verstandig interval. Als je app hiervoor een API-backend nodig heeft, is het REST API-backend-recept een startpunt, en hoe je een REST API bouwt behandelt het ontwerpen van de eindpunten. Als altijd draaiende workers of bots de kern van je product zijn, past een host die is gebouwd voor blijvende processen misschien beter.

Veelgestelde vragen

Wat is een achtergrondtaak?

Een achtergrondtaak is werk dat je app doet buiten het verzoek waarop een gebruiker wacht, zoals e-mails versturen, afbeeldingen verkleinen, rapporten genereren of gegevens synchroniseren. De gebruiker krijgt een snelle reactie, de taak draait apart en kan opnieuw worden geprobeerd als hij mislukt.

Hoe draai ik een geplande taak als mijn host geen cron heeft?

Voeg een beveiligd eindpunt toe dat het werk doet, en laat daarna een externe planner dat eindpunt op een schema aanroepen. Opties zijn een geplande GitHub Actions-workflow, een gehoste cronservice of de planner van je cloudprovider. Beveilig het eindpunt met een geheim token.

Kan ik setInterval of setTimeout gebruiken voor geplande taken?

Alleen voor kleine, niet-kritieke taken op een server die altijd draait. Als de server opnieuw start, naar nul schaalt of meerdere kopieën draait, gaan timers verloren of draaien ze meer dan één keer. Sla geplande werkzaamheden op in een database of gebruik een planner.

Ondersteunt Mythex cron-taken?

De documentatie van Mythex beschrijft geen geplande of cron-taken, en gepubliceerde apps slapen als ze inactief zijn. De betrouwbare aanpak is een externe planner die een beveiligd eindpunt in je app aanroept, waardoor de app wakker wordt en het werk draait.

Mythex · Pricing · Bouw alles met AI · Website- en app-templates · Mythex vergeleken · Woordenlijst voor apps bouwen met AI · Gratis tools voor apps bouwen met AI · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål ਪੰਜਾਬੀ 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 简体中文 繁體中文(香港) 繁體中文(台灣)