What Background Tasks Are Scheduled in OpenSEO: Cloudflare Workers Cron Guide

OpenSEO runs background tasks using Cloudflare Workers' scheduled events (cron triggers) to execute rank-check workflows, audit reconciliation watchdogs, Dub referral sale sweeps, and self-host pre-flight validation.

The open-source SEO platform OpenSEO (every-app/open-seo) relies on a sophisticated cron-driven architecture to automate monitoring, billing, and data reconciliation. These background tasks execute automatically on defined schedules, handling everything from 5-minute rank tracking updates to daily billing synchronizations. Understanding what background tasks are scheduled in OpenSEO is essential for operators monitoring system health and developers extending the platform.

How OpenSEO Dispatches Scheduled Tasks

OpenSEO centralizes its cron logic in src/server.ts through the Cloudflare Workers scheduled export. The handler receives a ScheduledController (typed as ExportedHandlerScheduledHandler) that contains the triggering cron expression. Based on the cron name, the dispatcher invokes specific workflow bindings configured in the worker environment, such as RANK_CHECK_WORKFLOW or SITE_AUDIT_WORKFLOW.

export const scheduled: ExportedHandlerScheduledHandler = async (controller, env, ctx) => {
  if (controller.cron === "0 */5 * * * *") {
    // Every 5 minutes – rank-check workflow
    await env.RANK_CHECK_WORKFLOW.run({ /* payload */ }, ctx);
  }
  // …other cron names for audit, Dub, etc.
};

This architecture ensures that all background tasks share a single entry point while maintaining isolation between different job types.

Core Background Tasks in OpenSEO

Rank-Check Workflow

The rank-check workflow polls user-defined rank-tracking configurations every five minutes. Defined in src/server/workflows/RankCheckWorkflow.ts, this task claims work slots, validates plan limits against the database, and triggers individual rank checks for each active configuration. The service implementation in src/server/features/rank-tracking/services/scheduledRankChecks.ts contains the core iteration logic. When errors occur, the system logs them with a [cron] prefix for easy filtering in Cloudflare Logs.

Audit Reconciliation Watchdog

Running on each cron tick, the audit reconciliation watchdog identifies and resolves stale or timed-out audits. The reconciliation logic lives in src/server/features/audit/services/auditReconciler.ts, which marks unfinished audits as failed or retries them based on configuration. This watchdog is invoked from the global scheduler in src/server.ts, ensuring that audit states remain consistent even when individual jobs fail mid-execution.

Dub Referral Sale Sweep

A daily cron job walks through every referred organization to verify that invoice events from the Dub billing webhook have been processed. Implemented in src/server/referrals/dub.ts (marked with a daily cron comment), this sweep ensures referral commissions are accurately calculated. Failed sweeps are logged with the specific error message "[cron] Dub referral sale sweep failed" and automatically retried on the next tick.

Self-Host Pre-Flight Checks

Though not triggered by a cron schedule, self-host pre-flight checks run as a background task on every worker start. Located in src/lib/selfhost-preflight.ts, this routine validates that required bindings—KV, R2, D1, and other Cloudflare resources—are properly configured. If validation fails, the worker aborts before processing any requests, preventing runtime errors in mis-configured environments.

Secondary Stale-Audit Reconcile

As a safety mechanism, a specific scheduled handler at the end of src/server.ts performs a secondary pass to catch any unreconciled audit states after the main cron loop completes. This task logs errors with the message "[cron] Stale-audit reconcile failed", providing a final safety net for audit consistency.

Running and Debugging Background Tasks

You can manually trigger the rank-check workflow for testing purposes by calling the workflow binding directly:

import { env } from "./server"; // assume env is populated
await env.RANK_CHECK_WORKFLOW.run(
  { payload: { /* config ID, domain, etc. */ } },
  { waitUntil: (p) => p }   // minimal ExecutionContext stub
);

When implementing custom scheduled tasks, follow the established logging convention to ensure errors are traceable:

console.error("[cron] Failed to start scheduled rank check for config", config.id);

Additionally, auxiliary maintenance scripts for D1 default-project cleanup and cost-profile calculations exist in the scripts/ directory, though these are invoked manually rather than through the hourly cron loop.

Summary

  • Rank-Check Workflow: Runs every 5 minutes via RANK_CHECK_WORKFLOW to poll rank-tracking configurations and trigger checks.
  • Audit Reconciliation Watchdog: Reconciles stale audits on each tick using src/server/features/audit/services/auditReconciler.ts.
  • Dub Referral Sale Sweep: Daily cron job in src/server/referrals/dub.ts that processes billing webhook events for referrals.
  • Self-Host Pre-Flight Validation: Startup checks in src/lib/selfhost-preflight.ts that validate Cloudflare bindings before accepting traffic.
  • Secondary Stale-Audit Check: Final safety net in src/server.ts that catches unreconciled audit states.

Frequently Asked Questions

How often do OpenSEO background tasks run?

The rank-check workflow runs every 5 minutes using the cron pattern 0 */5 * * * *. The Dub referral sale sweep runs daily, while the audit reconciliation watchdog and secondary stale-audit check execute on every cron tick. Self-host pre-flight checks run once per worker instance start-up.

Where is the main scheduler entry point in OpenSEO?

The main entry point is the scheduled export in src/server.ts. This ExportedHandlerScheduledHandler receives the ScheduledController and routes execution to the appropriate workflow based on the triggering cron expression.

Can I manually trigger OpenSEO background tasks for testing?

Yes. You can manually invoke workflows such as RANK_CHECK_WORKFLOW or SITE_AUDIT_WORKFLOW by calling the .run() method on the workflow binding, passing a payload and a minimal ExecutionContext stub with a waitUntil function.

What happens when a scheduled task fails in OpenSEO?

Failed tasks are logged with a [cron] prefix for visibility in Cloudflare Logs. The Dub referral sweep and similar tasks automatically retry on the next cron tick. Rank-check and audit workflows handle failures internally through their respective service layers, updating job statuses without crashing the global scheduler.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →