# Live vs Queued Rank Check in OpenSEO: Key Differences Explained

> Understand the live vs queued rank check in OpenSEO. Get instant SERP results with live checks or save costs with queued checks for scheduled tasks.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: deep-dive
- Published: 2026-08-09

---

**TL;DR:** OpenSEO's **live** rank check delivers instant SERP results at higher cost for manual queries, while the **queued** method batches requests through DataForSEO's task queue at lower cost for scheduled checks, with automatic fallback to live for failed tasks.

OpenSEO provides two distinct execution paths for retrieving search engine rankings through the DataForSEO API. Understanding when to use **live versus queued rank check methods** helps optimize both cost and reliability for your SEO monitoring workflows.

## Core Purpose and Use Cases

The two methods serve fundamentally different operational needs:

- **Live method (`"live"`)** — Designed for **on-demand, instant checks** when a user manually triggers a rank check
- **Queued method (`"queued"`)** — Optimized for **cost-effective, background processing** of scheduled monitoring jobs

The `RankCheckWorkflow` in [`src/server/workflows/RankCheckWorkflow.ts`](https://github.com/every-app/open-seo/blob/main/src/server/workflows/RankCheckWorkflow.ts) selects the appropriate path at lines 40-45 based on the trigger type: `"manual"` routes to live, `"scheduled"` routes to queued.

## API Endpoints and Execution Flow

### Live Endpoint: Direct Synchronous Calls

The live method calls DataForSEO's `/v3/serp/google/.../live` endpoint directly. In [`src/server/workflows/rankCheckPaths.ts`](https://github.com/every-app/open-seo/blob/main/src/server/workflows/rankCheckPaths.ts), the `runLiveCheck` function (lines 27-33) sends keyword/device batches and immediately writes snapshot results.

### Queued Endpoint: Task Queue with Polling

The queued method posts to DataForSEO's **task queue** via `rankCheckTaskPost`, then polls repeatedly using `task_get` until results arrive. The `runQueuedCheck` function (lines 73-89) handles this orchestration, with fallback logic at lines 124-131 that reruns any stragglers on the live endpoint.

## Cost Comparison: Per-Request Pricing

Cost constants are defined in [`src/shared/rank-tracking.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/rank-tracking.ts):

| Component | Live Cost | Queued Cost |
|-----------|-----------|-------------|
| **Base page** | `$0.002` | `$0.0006` |
| **Extra pages** (per 10 results) | `$0.0015` | `$0.00045` |

**Source:** Lines 12-16 (live) and 18-22 (queued) in [`src/shared/rank-tracking.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/rank-tracking.ts)

Queued checks cost approximately **70% less** per request, making them economical for bulk scheduled monitoring.

## Workflow Implementation Details

### Trigger-Based routing

```typescript
// From src/server/workflows/RankCheckWorkflow.ts
if (trigger === "manual") {
  await runLiveCheck(step, context);    // instant, higher cost
} else {
  await runQueuedCheck(step, context);  // batched, lower cost
}

```

### Polling and Fallback Strategy

The queued implementation provides superior resilience:

1. Posts all keyword/device pairs as queued tasks
2. Polls the queue multiple times for completion
3. Writes snapshots as individual tasks finish
4. **Automatically falls back to live endpoint** for any tasks that timeout or fail (lines 64-71)

This ensures scheduled runs never hang due to individual task failures.

## Code Examples: Using Each Method

### Manual Live Rank Check

```typescript
import { createDataforseoClient } from "@/server/lib/dataforseo";
import { runLiveCheck } from "@/server/workflows/rankCheckPaths";

const client = createDataforseoClient(billingCustomer);

await runLiveCheck(step, {
  client,
  keywords: [{ id: "kw1", keyword: "open source seo" }],
  devices: "both",           // checks both desktop and mobile
  serpDepth: 30,             // 30 results (multiple of 10)
  domain: "example.com",
  locationCode: 2840,        // United States
  languageCode: "en",
  runId: "run-123",
});

```

Results write immediately upon API response.

### Scheduled Queued Rank Check

```typescript
import { createDataforseoClient } from "@/server/lib/dataforseo";
import { runQueuedCheck } from "@/server/workflows/rankCheckPaths";

const client = createDataforseoClient(billingCustomer);

await runQueuedCheck(step, {
  client,
  keywords: [
    { id: "kw1", keyword: "open source seo" },
    { id: "kw2", keyword: "rank tracking" },
    { id: "kw3", keyword: "serp api" },
  ],
  devices: "desktop",
  serpDepth: 20,
  domain: "example.com",
  locationCode: 2840,
  languageCode: "en",
  runId: "run-456",
});

```

Tasks post to the queue, poll for completion, and fallback to live if needed.

## Key Architectural Files

| File | Responsibility |
|------|--------------|
| [`src/shared/rank-tracking.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/rank-tracking.ts) | `RankCheckMethod` type definition, cost constants, credit estimation |
| [`src/server/workflows/rankCheckPaths.ts`](https://github.com/every-app/open-seo/blob/main/src/server/workflows/rankCheckPaths.ts) | `runLiveCheck()` and `runQueuedCheck()` implementations with polling logic |
| [`src/server/workflows/RankCheckWorkflow.ts`](https://github.com/every-app/open-seo/blob/main/src/server/workflows/RankCheckWorkflow.ts) | Trigger-based path selection and orchestration |
| [`src/server/lib/dataforseo/client.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/dataforseo/client.ts) | DataForSEO client wrapper with `fetchLiveSerp` and queue methods |

## Summary

- **Live rank check** provides immediate results at 3x the cost—ideal for manual, ad-hoc queries
- **Queued rank check** batches requests through DataForSEO's task queue at 70% lower cost—optimal for scheduled monitoring
- The queued method's **automatic fallback to live** ensures reliability without manual intervention
- Path selection is **trigger-driven** (`manual` vs `scheduled`) in [`RankCheckWorkflow.ts`](https://github.com/every-app/open-seo/blob/main/RankCheckWorkflow.ts)
- Both methods share the same `CheckContext` interface for consistent configuration

## Frequently Asked Questions

### Can I force a queued check to run immediately?

No—the queued method always posts to DataForSEO's task queue and requires polling. For instant results, use the live method via a manual trigger or call `runLiveCheck` directly.

### What happens if queued tasks fail or timeout?

Failed or timed-out queued tasks automatically fall back to the live endpoint. The `runQueuedCheck` function in [`src/server/workflows/rankCheckPaths.ts`](https://github.com/every-app/open-seo/blob/main/src/server/workflows/rankCheckPaths.ts) implements this at lines 64-71 and 124-131, ensuring no keyword remains unprocessed.

### How do I estimate costs before running a check?

Use the credit estimation logic in [`src/shared/rank-tracking.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/rank-tracking.ts), which calculates based on `serpDepth` (results requested) and the selected method's per-page pricing constants.

### Can I mix live and queued methods in the same workflow?

The standard `RankCheckWorkflow` selects one method per run based on trigger type. For hybrid behavior, implement custom logic that calls `runLiveCheck` for critical keywords and `runQueuedCheck` for bulk monitoring within the same execution.