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 exceededSCHEDULED_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
nextCheckAtto 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:
prepareRankCheckKeywords– Loads and prepares keyword lists for processing- Execution strategy selection – Chooses between
runLiveCheck(immediate) orrunQueuedCheck(batched) based on the trigger type - Snapshot recording – Captures ranking data for historical comparison
- 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.tsandwrangler.toml. - The
runScheduledRankChecksfunction insrc/server/features/rank-tracking/services/scheduledRankChecks.tsorchestrates the entire process through a five-step pipeline. - Runtime guards (
TICK_DEADLINE_MSandSCHEDULED_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.claimDueConfigensures exactly-once execution semantics across distributed workers. - The
RankCheckWorkflowhandles 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →