Skip to content
ONLINE·BOOKING Q4 2026 ENGAGEMENTS·ONDINE v1.10.1·--:-- UTC
← all work
Open SourceLLMOpsPython

The review queue was the bottleneck
Ondine distributed 2,000 concurrent LLM checks across workers

A mechanical batch processor checkpointing data strips and weaving them into structured columns

I turned product-pair verification into a typed, recoverable DataFrame operation, then partitioned the work across multiple Ondine instances. This is the architecture behind the 2,000 concurrent checks, including the failures, quotas and evidence boundaries hidden by that headline number.

2,000
Concurrent Checks
Multi
Ondine Instances
Azure OpenAI
Measured Provider
100+
Compatible Providers

Product substitutions were waiting in a verification queue. The AI system could propose a replacement, but each product pair still needed a decision that could be traced back to its evidence. A loop over a DataFrame left that recovery and tracking work to the application.

I used Ondine to turn those checks into a recoverable, typed DataFrame operation. The workload was partitioned across multiple Ondine instances, each making bounded asynchronous requests to Azure OpenAI through LiteLLM. Together, the deployment ran 2,000 verification checks concurrently. That figure describes the deployment reported here; this page does not include the run logs needed to reproduce it. The architecture below explains how row identity, retries, cost and partial results were handled.

01 · THE CASE IN 90 SECONDS

From a review queue to distributed verification

Initial problemAI-proposed product pairs waited for slow, manual verification.
Unit of workOne DataFrame row containing the evidence for one verification check.
ImplementationMultiple Ondine instances, bounded asynchronous execution, LiteLLM and Azure OpenAI.
Reported scale2,000 concurrent checks across the deployment, not inside one Python process.
Execution controlsStructured outputs, row-level recovery, provider-aware retries and explicit cost limits.
What the number means: 2,000 is the aggregate number of in-flight verification checks across multiple Ondine instances. It is not a benchmark for one laptop, one event loop, one Azure deployment or every model provider.
Fleet-level view of 2,000 concurrent verification checks distributed across multiple bounded Ondine workers
FIG. 01 The reported concurrency belongs to the fleet, not to a single process.
02 · THE BOTTLENECK

A returned answer is not yet a completed row

A verification request formats a prompt, calls a model and parses the answer. Across a dataset, calls can time out, responses can fail validation and providers can throttle bursts. A worker may stop after thousands of successful calls. The output still needs to be a table that can be filtered, audited and joined back to the source catalogue.

Async execution overlaps requests; it does not record which rows are safe to retry. A restart also needs completed results, failure state and accumulated cost. Ondine puts those concerns in the pipeline so application code does not have to reconstruct them from logs after each interruption.

The design target was the completed dataset. Individual requests could fail or finish out of order. The job still had to return each result to the correct row, preserve completed work and isolate the rows that needed attention.
03 · THE PROGRAMMING MODEL

A prompt behaves like a typed DataFrame transformation

Each row contained a proposed product pair and its evidence. The prompt produced three output columns: a decision, a confidence value and a reason. Keeping the operation inside the DataFrame made the input-to-output relationship explicit.

from pydantic import BaseModel, Field

class Verification(BaseModel):
    is_equivalent: bool
    confidence: float = Field(ge=0, le=1)
    reason: str

# Conceptual shape: input columns become typed output columns.
# proposed_product | reference_product | evidence
#        ↓ Ondine prompt + Verification schema
# is_equivalent | confidence | reason

Pydantic checks the response against that schema. A missing decision or an out-of-range confidence value fails validation. A valid response can still contain a wrong decision: neither the schema nor a confidence value between zero and one establishes that two products are equivalent.

Analysts can inspect the resulting columns alongside the source evidence, then approve, reject or route a substitution for human review. Prompt construction, provider calls and validation stay within the same data workflow.

04 · HORIZONTAL SCALE

One process was not the scaling unit

I partitioned the input work across multiple Ondine instances. Each instance owned a bounded number of asynchronous requests. LiteLLM provided a common model interface, and the requests were served by Azure OpenAI. Results were written back with their row identity so that finishing out of order did not scramble the final table.

Distributed Ondine architecture from partitioned DataFrame rows through bounded workers and LiteLLM to Azure OpenAI and typed results
FIG. 02 Data and control paths stay separate: rows flow through workers while quota, retry pressure and cost govern the fleet.

Partitioning moved work beyond one Python process while keeping a separate concurrency ceiling on each worker. The reported 2,000 checks describe their combined activity. They do not establish the right worker setting for a different model, quota or request size.

Why this is not simply “asyncio at 2,000”: an event loop can create that many tasks, but the provider still has request and token quotas. A count of tasks in flight says nothing by itself about completed rows per second.
05 · BACKPRESSURE

Unbounded concurrency only moves the queue to the provider

HTTP 429 is a signal to reduce request pressure, not add more tasks to the queue. Each instance has a concurrency ceiling. Ondine handles the provider'sRetry-After guidance; its adaptive limiter can lower concurrency after throttling and raise it as requests succeed. These are execution capabilities, not measurements of the settings used in this deployment.

Per-worker limits are only half of the story in a fleet. Ten individually reasonable workers can still exceed one shared provider quota. Ondine includes a Redis-backed distributed rate-limiting option for deployments that need coordination across processes. Workers sharing a quota need the same limiter scope. Redis failure can fall back to local limits, which no longer coordinate the fleet. This option is not evidence that Redis was used in the production topology described here.

ControlWhat it protectsWhat it cannot guarantee alone
Worker semaphoreOne process from creating an unlimited burstA quota shared by many processes
Retry with backoffTemporary provider and network failuresRecovery from permanent bad input
Adaptive concurrencyThroughput when provider capacity changesA globally fair allocation between workers
Distributed limiterOne shared request budget across a fleetModel quality or valid structured output
06 · RECOVERY

A failed worker must not erase completed checks

import os
from uuid import UUID
from ondine import PipelineBuilder
from pydantic import BaseModel, Field

class Verification(BaseModel):
    is_equivalent: bool
    confidence: float = Field(ge=0, le=1)
    reason: str

pipeline = (
    PipelineBuilder.create()
    .from_dataframe(
        df_in,
        input_columns=["proposed_product", "reference_product", "evidence"],
        output_columns=["is_equivalent", "confidence", "reason"],
    )
    .with_prompt(
        "Compare {proposed_product} with {reference_product}. "
        "Use only this evidence: {evidence}"
    )
    .with_llm(
        provider="azure_openai",
        model="<base-model>",
        azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
        azure_deployment=os.environ["AZURE_OPENAI_DEPLOYMENT"],
        use_managed_identity=True,
    )
    .with_structured_output(Verification)
    .with_concurrency(20)  # Per worker, tune to the deployment quota.
    .with_checkpoint_dir(".checkpoints")
    .with_checkpoint_interval(100)
    .with_max_budget(50.0)
    .build()
)

result = pipeline.execute()

# After a failed run, resume with the session UUID it printed.
result = pipeline.execute(resume_from=UUID("<session-uuid>"))

Ondine stores lightweight execution counters in compressed checkpoint files and completed responses in SQLite. SQLite runs in write-ahead logging mode, and each completed call is appended independently. If a process is killed, rows already written remain available. Passing the session UUID back to execute resumes the unfinished work while skipping stored responses. An answer billed by the provider but lost before it reaches the store may still be requested and charged again on retry.

Workers naturally complete out of order: a short response may return while an earlier request is still waiting. The response store retains the original row index, allowing the final output to be reconstructed in dataset order. Failed rows can also be retried separately instead of replaying a successful partition.

Checkpoint recovery timeline showing completed rows surviving a worker crash in SQLite WAL storage and unfinished rows resuming by UUID
FIG. 03 Recovery skips stored responses; it cannot recover an answer that never reached the response store.
07 · COST CONTROL

Cost is a property of the whole dataset

A cost estimate has to cover the dataset, not just one prompt. Retries and validation failures can add billable calls. Ondine can estimate cost before execution, track reported response cost while running and stop an instance after its configured threshold is crossed.

A limit is not an exact invoice ceiling. Providers report exact usage after a response, and several calls may already be in flight. The last responses can take the final total above the threshold. In a multi-instance deployment, a true fleet-wide budget also needs coordination above individual worker limits.

The limit therefore needs headroom for requests already in flight. The example above sets a per-instance budget; it does not reserve or enforce a shared budget across all workers.

08 · OPERATIONS

A fleet total can hide a stuck partition

A distributed batch can appear healthy while one partition is repeatedly throttled or one schema failure consumes every retry. The useful view combines fleet throughput with worker detail: completed and pending rows, requests in flight, 429 rate, retry count, response latency, validation failures and accumulated cost.

Labels must remain bounded. Provider, model, worker and status are useful dimensions; product IDs and raw prompts are not. High-cardinality identifiers make metrics expensive and can leak business data. Row-level debugging belongs in the checkpoint or response store, connected to a controlled run identifier.

09 · EVIDENCE BOUNDARIES

What is reported, and what remains unmeasured here

Reported in this caseNot established here
The verification workload was distributed across multiple Ondine instances.One Ondine process sustained 2,000 concurrent calls.
The fleet reached 2,000 concurrent checks using Azure OpenAI through LiteLLM.2,000 is a safe default for another provider, quota or model.
The workflow returned structured results to their source rows and supported recovery.A measured p95 latency, accuracy gain or cost reduction.
Horizontal execution removed the single-worker scaling assumption.More concurrency always produces more throughput.

This page provides the architectural account and illustrative code, not a benchmark package. It does not publish the run duration, model and quota configuration, or raw traces behind the concurrency figure. Those would be needed to reproduce the result or compare it with another deployment.

10 · LESSONS

The next boundary is between workers

The DataFrame interface gives each check an input row and a place for its result. Checkpointing preserves stored work when a worker stops. Neither mechanism, on its own, decides which worker owns the next partition or how much of a shared quota it may use.

That is where I would keep investing: shared work leasing, coordinated provider limits, a fleet-wide budget and an operational view that traces a failed result to its source row without exposing the prompt in metrics. These are the next design priorities, not additional results claimed for this deployment.