Doculytix Engineering

Handling 100,000 Documents in Parallel Is a Decade-Old Engineering Problem—Not an AI Problem

Handling one document well proves AI capability. Handling 100,000 in parallel is a decade-old engineering problem. Apply queues, workers, backpressure, multi-model extraction, and confidence scores—the full set of engineering principles—to solve it.

8 min read
ArchitectureCeleryMulti-modelAsync

When teams evaluate document AI, the first question is usually about the model: How accurately does it read invoices, contracts, or forms? That question is useful for a proof of concept. It is almost never what breaks in production.

At Doculytix, we see this pattern constantly. A strong model can extract fields from a single PDF with impressive accuracy. That proves AI capability. Moving 100,000 documents in parallel—with retries, mixed formats, confidence thresholds, validation queues, and downstream systems waiting on clean JSON—is not a new AI breakthrough. It is a decade-old engineering problem, and it only yields when you apply the full set of engineering principles—not a larger model alone.

From the Doculytix team

Handling one document well proves AI capability. Handling 100,000 documents in parallel is a decade-old engineering problem—not an AI problem. Async queues, task IDs, load-aware workers, observability, multi-model extraction, and confidence scores are how you solve it.

Why “more model” fails at 100k

At one document, latency and prompt quality dominate. At 100,000, the failure modes shift to places most demos never touch:

  • Ingestion and OCR are largely I/O-bound; some post-processing is CPU-bound; extraction is often GPU- or rate-limit-bound.
  • Retries that reprocess the wrong unit of work create duplicate outputs and noisy review queues.
  • A fast intake path can outrun extraction and validation until queues, storage, or connection pools collapse.
  • Schema enforcement, confidence scoring, and human review become first-class stages—not optional polish.
  • A single LLM is not enough. Text, tables, and images need specialized models that run together and report confidence per field.

Treating every stage the same way leaves throughput on the table. In our view, scaling document understanding is orchestration: independently sized stages, durable queues, and clear ownership of each bottleneck.

Request execution flow: async by design

When a document request hits Doculytix, we do not hold the HTTP connection open while models run. The flow is deliberately asynchronous:

  1. Request received — API authenticates and validates the payload (document, schema, options).
  2. Logged to the queue — the job is written to a durable message broker. A task ID is returned to the client immediately.
  3. Load-aware processing — Celery workers pull jobs based on current system load, concurrency caps, and queue depth—not as fast as possible at all costs.
  4. Observable execution — Flower visualizes workers, task states, runtimes, and failures so operators can see which pool is drowning before customers feel it.
  5. Result delivery — the client polls, receives a webhook, or consumes via MCP/API using the same task ID.

Async is not an implementation detail. It is how we absorb spikes, protect SLAs, and keep intake from melting the understanding layer.

Doculytix request execution flow with Celery, Flower, and multi-model extractionAfter a request is received it is logged to a queue and a task ID is returned. Celery workers process jobs based on system load. Flower visualizes the flow. Specialized models for text, tables, and images run with an LLM and confidence scoring.100,000 Documents in Parallel: a Decade-Old Engineering ProblemNot an AI problem — queue first, return a task ID, process under load with engineering principlesRequest Intake PoolClient / APIUpload / Extract1API GatewayAuth + validate2Enqueue job · Return task_idClient gets task ID immediately — no blocking wait3Message Broker / QueueRedis / RabbitMQ · durable backlogCelery Worker PoolProcess by current system load4Load-aware dispatch · prefetch & concurrency capsWorkerCeleryWorkerCeleryWorkerCeleryScale workers horizontally as queue depth growsFlower · live task & worker visualizationQueue depth · success / failure · runtimeAsync Result Path5Task status storePENDING → STARTED → SUCCESS / FAILUREPoll / webhook / MCP streamClient retrieves structured result by task_idStructured output + confidenceFields · tables · review flagsUnderstanding Pipeline · multi-model, not LLM-onlyCelery workers run specialized models per use case, then fuse results with confidence scoresDocumentPDF / image6Routepage / region7Text modelOCR + NLP8Table modelgrids / lines9Image modelstamps / seals10LLM fuseschema map11Confidencescore + review12Specialized model clusterText · Tables · Images / visionRouted by page layout & content typeRun in parallel on Celery workersLLM (schema reasoning)Maps model outputs → target schemaResolves ambiguity across regionsNot the only model in the pathConfidence & validation layerPer-field scores from each specialist modelLow-confidence fields → human review queueHigh-confidence fields → auto-accept / API
Handling 100,000 documents in parallel is a decade-old engineering problem—not an AI problem. Doculytix applies queues, task IDs, Celery under load, Flower visibility, and multi-model extraction with confidence scores.

Celery workers and Flower: process under load

Celery gives us a worker pool that scales horizontally. Workers do not blindly drain the queue; they process based on current system load—prefetch limits, concurrency per worker, and backpressure when downstream stages are saturated.

Flower sits on top of that pool so the team can see live task flow: pending vs started vs success/failure, which workers are busy, and where latency accumulates. Without that visibility, “async” becomes a black box and bulk imports turn into silent outages.

Celery worker pool

  • Pull jobs as capacity frees
  • Horizontal scale with queue depth
  • Retries with idempotent task keys
  • Separate queues for intake vs understanding when needed

Flower observability

  • Live worker and task visualization
  • Queue depth and runtime trends
  • Failure surfaces before SLA breach
  • Operational proof that async is healthy

Not just an LLM: multi-model architecture with confidence

A common misconception is that document AI equals “call an LLM.” An LLM is powerful for schema reasoning and ambiguity—but invoices, contracts, and forms are multi-modal artifacts. Text blocks, line-item tables, stamps, signatures, and scanned photos each need the right specialist.

In Doculytix, Celery workers run a multi-model pipeline per document:

  • Text models — OCR and language understanding for paragraphs, headers, and free-form fields.
  • Table models — grid detection, header bands, and line-item structure that generic LLMs often flatten incorrectly.
  • Image / vision models — stamps, seals, logos, handwriting regions, and photo-quality pages.
  • LLM fusion — maps specialist outputs into the target schema and resolves cross-region ambiguity.

Every extracted field carries a confidence score. High-confidence fields can auto-accept into downstream systems. Low-confidence fields route to validation or human review. That is how accuracy at one document becomes trust at 100,000—without pretending a single model is infallible.

Architecture rule

Route by content type → run specialized models in parallel on workers → fuse with an LLM → attach confidence → accept or review. The LLM is one stage in the path, not the entire path.

How we think about high-volume document systems

Beyond the request path, the systems that survive enterprise document loads share a few architectural choices. This is how the Doculytix team designs for them.

1. Two levels of parallelism

Treating 100,000 documents as one giant job is a bottleneck by design. We shard the corpus into jobs, then batch expensive work inside each Celery worker:

  • Pipeline parallelism — distribute shards across workers so many jobs run at once.
  • Task parallelism — inside a worker, process batches and fan out text / table / image models concurrently where the page layout allows.

That two-level pattern is the difference between “we tested 20 clean files” and “we can absorb a quarter-end dump without rewriting the product.”

2. Separate work pools by bottleneck

Collapsing raw intake and “document → structured data” into one monolithic path hides the real constraints. We keep them as independently scalable pools:

Intake work pool

Uploads, scanners, transforms, storage—mostly I/O.

  • Normalize sources into durable jobs
  • Enqueue and return task IDs immediately
  • Batch-load documents into object and metadata stores

Understanding work pool

Multi-model extraction, validation, delivery—heterogeneous compute.

  • Text, table, and image specialists + LLM fusion
  • Confidence scoring and review routing
  • Batch writes of structured outputs to APIs and agents

Every stage has a different bottleneck. Designing for independent scale is what turns throughput into a controllable property of the platform—not a hopeful byproduct of a bigger LLM.

3. Backpressure between pools

The failure mode demos never show: intake cheerfully accepts more work than understanding can finish. Queues grow without bound. Storage costs spike. Connection pools die three weeks after go-live when someone dumps a bulk import.

The fix is intentional: cap queue depth, let Celery slow or shed intake when the downstream pool falls behind, and watch the signal in Flower. Without it, “we can handle 100k” is a false positive.

4. Failure isolation and retry units

Batching improves throughput—and defines your retry boundary. If a worker crashes mid-batch after writing part of the results, naive whole-batch retries risk duplicates and review noise. We prefer:

  • Idempotent writes keyed by document ID, task ID, and schema version
  • Checkpointing at a smaller unit than the full shard when stages are expensive
  • Splitting pools so a failed model step does not force a full re-ingest of raw bytes

What this means in Doculytix

Doculytix is built so document understanding survives real enterprise traffic—not only polished sample PDFs. In practice that means:

  • Async request execution: queue first, task ID back, process under load
  • Celery workers with Flower visibility for operators
  • Multi-model extraction (text, tables, images) with LLM fusion—not LLM-only shortcuts
  • Per-field confidence scores that drive auto-accept vs review
  • Schema-driven extraction so structure is a contract, not an afterthought
  • API and MCP-native delivery so agents and backends consume clean data as documents arrive
  • Deployment options—including private and self-host capable paths on enterprise plans—for environments where volume and data residency travel together

Models are necessary. Applying decade-old engineering principles—and the right model for each region of the page—is what makes 100,000 documents in parallel a planned outcome instead of an incident.

A checklist: apply engineering principles before you “just scale the model”

Handling 100,000 documents in parallel is a decade-old engineering problem. Before buying more inference capacity, we ask teams to answer these:

  1. Do you return a task ID and process asynchronously, or block on every request?
  2. Can intake and understanding scale independently under Celery (or equivalent)?
  3. Can operators see queue depth and worker health (e.g. Flower) in real time?
  4. Do you run specialized text / table / image models plus an LLM—or only one model for everything?
  5. Does every field carry a confidence score with a clear accept vs review path?
  6. What happens when someone drops a bulk import overnight—does the system shed load or melt?

If any of these answers are unclear, you do not have a model gap yet. You have an architecture gap—and that is the gap Doculytix is designed to close.

Closing: engineering principles, not model magic

Handling one document well proves AI capability. Handling 100,000 documents in parallel is a decade-old engineering problem—not an AI problem. The solution is to apply the principles that have always governed reliable distributed systems: async queues, task IDs returned immediately, Celery workers sized to current load, Flower for visibility, multi-model extraction with confidence scores, backpressure between pools, idempotent retries, and operators who can see which pool is drowning.

Scaling document understanding is not primarily about adding GPUs or swapping to a larger LLM. It is about designing a platform where every bottleneck—and every content type—can scale independently, so accuracy at one document becomes reliability at enterprise volume.

See Doculytix at your document volume

Talk with the Doculytix team about async execution, multi-model extraction, and confidence-driven validation for production workloads.