How OpenSEO Handles Scheduled Rank Checks: Cloudflare Workers Cron Architecture Explained

OpenSEO executes scheduled rank checks using Cloudflare Workers' cron triggers that invoke runScheduledRankChecks, which identifies due configurations, enforces runtime budgets, validates plan eligibility, and launches RankCheckWorkflow instances to perform the actual keyword monitoring.

OpenSEO is an open-source SEO platform that automates rank tracking through robust scheduled tasks. This article explains how the system handles scheduled rank checks using Cloudflare Workers' cron infrastructure, ensuring reliable, cost-controlled execution across free and paid tiers.

Cron Architecture and Configuration

OpenSEO leverages Cloudflare Workers' cron triggers to execute rank checks on a regular schedule. The cron definitions reside in the worker configuration (worker-configuration.d.ts) and are wired into the Cloudflare deployment via the crons field in wrangler.toml.

When a cron tick fires, Cloudflare automatically invokes the scheduled handler, which imports and executes runScheduledRankChecks from src/server/features/rank-tracking/services/scheduledRankChecks.ts. This entry point serves as the orchestration layer for all automated rank-tracking operations.

The Execution Flow: Five-Step Processing Pipeline

The runScheduledRankChecks function implements a sophisticated five-step pipeline to ensure fair, efficient, and plan-aware task execution.

Step 1: Identifying Due Configurations

The scheduler first queries RankTrackingRepository.getDueConfigsWithOrganization to discover every rank-check configuration whose nextCheckAt timestamp has passed. This database query returns all pending jobs across organizations, prioritized by their scheduled execution time.

Step 2: Enforcing Runtime Limits and Budgets

To prevent cron overruns and control costs, OpenSEO implements strict resource guards:

  • TICK_DEADLINE_MS – A per-tick wall-clock deadline that stops processing new configs once exceeded
  • SCHEDULED_TASK_UNIT_BUDGET – A cap on task units consumed during a single cron invocation

These limits ensure the worker terminates gracefully within Cloudflare's execution constraints, preventing partial processing of configurations that might exceed runtime limits.

Step 3: Validating Plan Eligibility

For hosted deployments, the system checks organization entitlements via customerHasPaidPlan. Configurations belonging to free-plan organizations are immediately skipped and marked with a "plan_required" badge. This validation occurs before any resource-intensive workflow launching, protecting infrastructure from unpaid usage.

Step 4: Atomic Slot Claiming

To guarantee exactly-once execution semantics, RankTrackingRepository.claimDueConfig performs an atomic database update that:

  • Advances nextCheckAt to the next scheduled interval
  • Clears any previous lastSkipReason
  • Locks the configuration to the current worker instance

If another worker has already claimed the slot, the scheduler logs the conflict and moves to the next configuration, ensuring fairness across the entire config pool.

Step 5: Launching the RankCheckWorkflow

Once claimed, beginRankCheckRun initiates the RankCheckWorkflow defined in src/server/workflows/RankCheckWorkflow.ts. This Cloudflare Workflow receives the config object, project ID, and billing context, then executes the following sequence:

  1. prepareRankCheckKeywords – Loads and prepares keyword lists for processing
  2. Execution strategy selection – Chooses between runLiveCheck (immediate) or runQueuedCheck (batched) based on the trigger type
  3. Snapshot recording – Captures ranking data for historical comparison
  4. Finalization – Updates the repository with status codes, result counts, and error messages

Manual Triggers and API Integration

While cron triggers handle automation, OpenSEO also supports manual execution via API routes. Developers can programmatically trigger rank checks using the same infrastructure:

// Example: manual trigger of a scheduled rank-check (e.g. from an API route)
import { beginRankCheckRun } from "@/server/features/rank-tracking/services/rankCheckRunGuards";
import { RankTrackingRepository } from "@/server/features/rank-tracking/repositories/RankTrackingRepository";

async function triggerManualRun(configId: string, env: Env) {
  const config = await RankTrackingRepository.getConfigById({ configId, projectId: "" });
  if (!config) throw new Error("Config not found");

  await beginRankCheckRun({
    workflow: env.RANK_CHECK_WORKFLOW,
    config,
    projectId: config.projectId,
    billingCustomer: {
      userId: "system",
      userEmail: "system@openseo.so",
      organizationId: config.organizationId,
      projectId: config.projectId,
    },
    keywordsTotal: await RankTrackingRepository.getKeywordCount(config.id),
    trigger: "manual",
    workflowStartErrorMessage: "Failed to start manual rank check",
  });
}

This pattern allows administrative interfaces or webhook endpoints to force immediate rank checks without waiting for the next cron tick.

Error Handling and Fairness Guarantees

The scheduler implements defensive error handling to maintain system stability. When plan validation fails or workflow initiation errors occur, the system logs the failure without resetting nextCheckAt. This critical design choice prevents "stuck" configurations from re-triggering immediately on the next cron tick, effectively implementing a circuit breaker pattern for problematic jobs.

If a configuration cannot be claimed due to concurrent access, the scheduler logs the conflict and proceeds to the next item, ensuring that a single slow or stuck workflow cannot block the entire queue.

Summary

  • OpenSEO scheduled rank checks run on Cloudflare Workers using native cron triggers defined in worker-configuration.d.ts and wrangler.toml.
  • The runScheduledRankChecks function in src/server/features/rank-tracking/services/scheduledRankChecks.ts orchestrates the entire process through a five-step pipeline.
  • Runtime guards (TICK_DEADLINE_MS and SCHEDULED_TASK_UNIT_BUDGET) prevent cron overruns and control infrastructure costs.
  • Plan validation occurs before workflow launch, skipping free-tier configs with a "plan_required" badge to protect resources.
  • Atomic claiming via RankTrackingRepository.claimDueConfig ensures exactly-once execution semantics across distributed workers.
  • The RankCheckWorkflow handles the actual keyword processing, deciding between live and queued execution modes based on trigger context.

Frequently Asked Questions

How does OpenSEO prevent the same rank check from running twice simultaneously?

OpenSEO uses RankTrackingRepository.claimDueConfig to atomically update the nextCheckAt timestamp and lock the configuration to the current worker. If another worker has already claimed the slot, the second attempt detects the conflict and skips to the next configuration, ensuring only one workflow instance processes each config at a time.

Can I trigger a rank check manually outside the cron schedule?

Yes. The beginRankCheckRun function accepts a trigger: "manual" parameter, allowing API routes or administrative interfaces to launch RankCheckWorkflow instances on demand. This uses the same infrastructure as scheduled checks but bypasses the cron-based discovery and claiming logic.

What happens if a scheduled rank check fails to start?

If workflow initiation fails due to plan validation errors or infrastructure issues, the scheduler logs the error but does not reset the nextCheckAt timestamp. This prevents the failed configuration from immediately re-entering the queue on the next cron tick, protecting the system from infinite retry loops on persistent errors.

Where are the cron intervals defined in the OpenSEO codebase?

Cron schedules are defined in worker-configuration.d.ts as TypeScript type definitions and implemented in the Cloudflare wrangler.toml file under the crons field. These trigger the scheduledRankChecks entry point at the specified intervals, which then delegates to runScheduledRankChecks for actual processing.

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 →