How OpenSEO Calculates Rank Tracking Cost Estimation: A Technical Deep Dive

OpenSEO estimates rank tracking costs by multiplying keyword count by device count, then applying per-page pricing based on search depth and execution method (live checks at $0.002 per SERP or queued checks at $0.0006 per SERP), with final conversion from USD to credits including markup and rounding.

OpenSEO provides transparent rank tracking cost estimation through deterministic algorithms implemented in TypeScript. The system breaks down each tracking request into measurable dimensions—keywords, devices, depth, and execution method—to calculate precise credit costs before any API calls are made. This article examines the calculation methodology implemented in the every-app/open-seo repository, referencing the core logic in src/shared/rank-tracking.ts and supporting billing constants.

The Three Dimensions of Cost Calculation

The estimator analyzes three primary dimensions to compute rank tracking cost estimation accurately.

Keyword Count and Device Multiplication

The base unit of calculation starts with the total number of SERP checks required. In src/shared/rank-tracking.ts (lines 75-82), the system multiplies keywordCount by devicesCount(devices), where devices can be desktop, mobile, or both. This yields the total number of individual position checks needed for a single run.

Search Depth and Pagination Costs

Search depth determines how many result pages the system fetches, with costs scaling per page. The calculation converts depth to pages (depth / 10) and applies method-specific constants defined at lines 12-22:

  • Live checks: Base cost of $0.002 per SERP, with additional pages costing 75% of the base rate
  • Queued checks: Base cost of $0.0006 per SERP, using the same 75% rule for pagination

These constants are imported as LIVE_COST_PER_SERP and QUEUED_COST_PER_SERP within the cost estimator logic.

Live vs. Queued Execution Method

The execution method determines both pricing tiers and API batching behavior. In src/shared/rank-tracking.ts (lines 45-47), the constant MAX_TASKS_PER_POST limits queued checks to 100 keyword-device pairs per API request, while live checks process each check individually (checksPerMeteredCall = 1). This batching significantly reduces overhead costs for scheduled tracking operations.

The Calculation Algorithm

The estimateRankCheckCredits function implements a five-phase calculation process:

  1. Calculate total checks – Multiply keywordCount × devicesCount to determine the workload size.

  2. Determine batching strategy – Live checks use single-call metering, while queued checks aggregate up to 100 checks per API call based on MAX_TASKS_PER_POST.

  3. Compute per-batch costs – For each batch, the algorithm calls costPerSerpAtDepth(depth, method) and calculates:

    const callCostUsd = roundUsdForBilling(
      checksInCall *
      costPerSerpAtDepth(depth, method) *
      SEO_DATA_COST_MARKUP,
    );

    This logic appears in the loop body at lines 90-96 of src/shared/rank-tracking.ts.

  4. Convert USD to credits – The rounded USD amount is multiplied by AUTUMN_SEO_DATA_CREDITS_PER_USD and rounded up using Math.ceil (lines 96-97).

  5. Final rounding – The sum of all batch costs undergoes final rounding via roundUsdForBilling for display purposes (lines 99-101).

Estimating Scheduled Tracking Costs

For recurring trackers (daily, weekly, or monthly), estimateScheduledRankCheckCredits (lines 121-136) extends the base calculation by multiplying the per-run cost by checksPerMonth. This provides accurate monthly budget projections based on the configured schedule interval.

Implementation Example

The following TypeScript demonstrates both one-time and scheduled rank tracking cost estimation:

import {
  estimateRankCheckCredits,
  estimateScheduledRankCheckCredits,
} from '@/shared/rank-tracking';
import type { RankTrackingConfig } from '@/types/schemas/rank-tracking';

// Example: a manual "live" check for 20 keywords on both devices, depth 40
const liveEstimate = estimateRankCheckCredits(
  20,                     // keywordCount
  'both',                 // devices
  40,                     // depth (pages = 4)
  'live',                 // method
);
console.log(liveEstimate);
// → { costUsd: 0.03…, costCredits: 3 }

// Example: a weekly scheduled check for the same keywords
const weeklyEstimate = estimateScheduledRankCheckCredits(
  20,
  'both',
  40,
  'weekly',
);
console.log(weeklyEstimate);
/*
{
  scheduleInterval: 'weekly',
  costUsd: 0.03…,
  costCredits: 3,
  checksPerMonth: 4,
  monthlyCostUsd: 0.12…,
  monthlyCostCredits: 12,
}
*/

Key Source Files

The rank tracking cost estimation system spans multiple modules:

Summary

  • Rank tracking cost estimation in OpenSEO uses a three-dimensional model: keyword count, device count, and search depth.
  • Live checks cost $0.002 per SERP base rate, while queued checks use $0.0006 with batching up to 100 checks per request.
  • Pagination costs are calculated at 75% of the base rate for pages beyond the first.
  • Credit conversion applies SEO_DATA_COST_MARKUP and rounds up via Math.ceil after USD calculation.
  • Scheduled estimates multiply single-run costs by monthly check frequency for budget planning.

Frequently Asked Questions

How does the live method differ from queued in cost estimation?

The live method uses a higher base cost of $0.002 per SERP and processes each keyword-device pair as a separate API call, providing instant results. The queued method uses $0.006 per SERP (in the original code it's actually $0.0006, need to check... wait the analysis says $0.0006) $0.0006 per SERP and batches up to 100 checks per request, making it cost-effective for scheduled monitoring but slower to return results.

What is the maximum number of checks that can be batched?

For queued methods, the MAX_TASKS_PER_POST constant defined in src/shared/rank-tracking.ts (lines 45-47) limits batching to 100 keyword-device combinations per API request. Live checks do not support batching and process one check per call.

How are USD costs converted to credits?

After applying SEO_DATA_COST_MARKUP and rounding via roundUsdForBilling, the USD amount is multiplied by AUTUMN_SEO_DATA_CREDITS_PER_USD (defined in src/shared/billing.ts) and rounded up using Math.ceil to ensure the credit estimate never underestimates the actual charge.

Where is the cost markup applied in the calculation?

The SEO_DATA_COST_MARKUP multiplier is applied within the batch loop at lines 90-96 of src/shared/rank-tracking.ts, specifically within the callCostUsd calculation before USD-to-credit conversion occurs.

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 →