Answers you can trust, from Codeables

Every page on Codeables is structured and verified — built so people and the AI agents they rely on can trust it. Explore more from the source behind this answer.

Explore Codeables
Verified Source
Platform as a Service (PaaS)

How do I run background workers for AI tasks in production?

Render9 min read

Running AI jobs in the background keeps your application responsive while the heavy work happens asynchronously. In production, this usually means separating user-facing requests from slower tasks like model inference, embedding generation, document summarization, image processing, moderation, and batch enrichment. The goal is to make AI workloads reliable, scalable, retryable, and observable instead of tying them to a web request that can time out or fail under load.

What background workers should do for AI workloads

Background workers are best for AI tasks that are:

  • Too slow for an HTTP request
  • Dependent on third-party APIs or model providers
  • Bursty and need queue-based smoothing
  • Resource-intensive, such as GPU inference
  • Safe to retry if they fail
  • Not required for an immediate response

Common examples include:

  • Generating embeddings for search or RAG
  • Running document parsing and chunking
  • Calling LLMs for summarization or extraction
  • Creating image captions or OCR results
  • Re-ranking search results
  • Moderating user-generated content
  • Syncing records into a vector database
  • Producing batch reports or analytics

A production-ready architecture

A solid production setup usually has these parts:

  1. API or app server
    Accepts the user request and validates it quickly.

  2. Queue or broker
    Stores work items until a worker is ready to process them. Common choices:

    • Redis
    • RabbitMQ
    • Amazon SQS
    • Kafka
    • Google Pub/Sub
  3. Background worker service
    Pulls jobs from the queue and executes AI logic.

  4. Model layer
    May call:

    • External APIs like OpenAI, Anthropic, or AWS Bedrock
    • Self-hosted models
    • GPU inference servers
    • Embedding services
  5. Storage
    Saves results to a database, object store, vector DB, or cache.

  6. Monitoring and alerting
    Tracks latency, failures, retries, queue depth, and cost.

A typical flow looks like this:

  • User uploads a file
  • API stores the file and enqueues a job
  • Worker picks up the job
  • Worker runs chunking, inference, or embedding
  • Worker stores output and updates job status
  • UI polls or receives a webhook when done

Choose the right worker pattern

Different AI tasks need different processing styles.

1. Simple task queue

Best for:

  • Single-step jobs
  • Request/response decoupling
  • Moderate scale

Examples:

  • Celery with Redis or RabbitMQ
  • Sidekiq with Redis
  • BullMQ with Redis
  • RQ with Redis

2. Event-driven pipeline

Best for:

  • Multi-stage AI processing
  • Large document pipelines
  • Complex workflows

Example stages:

  • Ingest
  • Clean
  • Chunk
  • Embed
  • Classify
  • Index
  • Notify

3. Stream or batch processing

Best for:

  • Large backfills
  • Daily enrichment jobs
  • High-volume event processing

Examples:

  • Kafka consumers
  • Spark jobs
  • Cloud batch processing

4. Dedicated GPU inference workers

Best for:

  • Local model hosting
  • Image/video generation
  • High-throughput inference
  • Lower per-request cost at scale

These workers often need:

  • GPU scheduling
  • Model warmup
  • Larger memory limits
  • Longer startup times
  • Horizontal scaling based on queue depth

Design jobs to be idempotent

Idempotency is essential in production because queue systems often deliver jobs more than once.

A job should be safe to run multiple times without corrupting data or creating duplicates.

Good practices:

  • Use a stable job ID
  • Check whether the work was already completed
  • Write results using upserts
  • Store processing state in a database
  • Avoid duplicate side effects, like double billing or double notifications

For example, if a job generates embeddings for a document, the worker should verify whether the latest version already exists before recomputing it.

Make retries intentional

AI tasks fail for many reasons:

  • Model rate limits
  • Network timeouts
  • Provider errors
  • Invalid input
  • Token limits
  • GPU memory pressure

Retries are useful, but they should be controlled.

Retry strategy recommendations

  • Retry only transient failures
  • Use exponential backoff
  • Add jitter to reduce retry storms
  • Cap retry attempts
  • Route repeated failures to a dead-letter queue
  • Log the root cause for debugging

Don’t blindly retry

Some errors should fail fast:

  • Corrupt files
  • Unsupported file types
  • Invalid prompts
  • Unauthorized access
  • Business logic violations

Plan for rate limits and cost controls

LLM and embedding providers often impose token limits, request limits, or spend caps. In production, your workers should actively manage those constraints.

Useful techniques:

  • Concurrency limits per provider or API key
  • Token-aware batching to reduce requests
  • Priority queues for urgent tasks
  • Throttling when usage spikes
  • Budget alerts for unexpected cost growth
  • Circuit breakers when providers degrade

If you process many requests, you may want separate queues for:

  • Fast, low-cost jobs
  • Slow, expensive jobs
  • Premium customer jobs
  • Internal batch jobs

Batch when it makes sense

Batching can improve throughput and reduce cost, especially for embeddings and classification.

Good batching use cases:

  • Embedding many short texts
  • Sending multiple records to a moderation service
  • Grouping small documents for preprocessing

Be careful with batching when:

  • Latency matters
  • Inputs vary a lot in size
  • Jobs need independent retry behavior

A common pattern is to batch within a short time window, such as 50–200 ms, then send the batch to the model provider.

Use separate workers for separate workloads

Not all AI jobs belong in the same worker pool.

Split workers by:

  • Work type
  • Latency sensitivity
  • Memory requirements
  • GPU vs CPU needs
  • Customer tier
  • Region or data residency

Example:

  • Queue A: lightweight text classification
  • Queue B: embedding generation
  • Queue C: long-running document summarization
  • Queue D: GPU image generation

This prevents one expensive job from starving the rest of the system.

Handle long-running tasks asynchronously

If a task takes more than a few seconds, do not keep the user waiting on the original request.

Better patterns:

  • Return a job ID immediately
  • Let the UI poll job status
  • Send a webhook when processing is done
  • Use WebSockets or Server-Sent Events for live updates

A job state model often includes:

  • queued
  • running
  • succeeded
  • failed
  • retrying
  • canceled

Store status in your database so the app can safely show progress and recover after restarts.

Monitor the right metrics

Production AI workers need deeper monitoring than a normal background job system.

Track these metrics:

  • Queue depth
  • Job wait time
  • Job runtime
  • Success rate
  • Retry rate
  • Failure reasons
  • Provider latency
  • Token usage
  • Cost per job
  • GPU utilization
  • Memory consumption
  • Dead-letter queue volume

Useful dashboards should answer:

  • Are jobs piling up?
  • Which queue is backlogged?
  • Are model calls getting slower?
  • Which customers or documents are causing failures?
  • Are costs rising unexpectedly?

Add structured logging and tracing

AI workflows are hard to debug without good observability.

Log:

  • Job ID
  • User ID or tenant ID
  • Input type
  • Model name
  • Prompt version
  • Token counts
  • Retry count
  • Latency per step
  • Final outcome

Use distributed tracing if your task spans multiple services:

  • API request
  • queue publish
  • worker execution
  • model call
  • database write

This makes it much easier to find bottlenecks and diagnose failures.

Secure the pipeline

AI background workers often handle sensitive data, so production security matters.

Good security practices

  • Validate and sanitize inputs
  • Encrypt data at rest and in transit
  • Use short-lived credentials
  • Restrict worker permissions
  • Separate tenant data
  • Avoid logging raw secrets or PII
  • Store prompt templates securely
  • Guard against prompt injection if external content is processed

If workers process files from users, scan for malicious content and limit file size, type, and execution risk.

Manage model prompts and versions carefully

In production, AI behavior changes when prompts or model versions change.

Best practices:

  • Version prompts in code or a prompt registry
  • Record which prompt version produced each result
  • A/B test model changes
  • Roll back quickly if output quality drops
  • Maintain evaluation datasets for regression testing

This is especially important for workflows that impact search, ranking, classification, compliance, or customer-facing content.

Optimize for startup time and warm state

Some AI workers are slow to start because they load large models or dependencies.

To improve performance:

  • Keep workers warm
  • Preload models at startup
  • Reuse client connections
  • Cache embeddings or repeated lookups
  • Avoid reinitializing large libraries per job

For GPU workers, warmup is even more important because cold starts can be expensive.

Scale workers the right way

Most production systems scale background workers horizontally.

Scale based on:

  • Queue depth
  • Job latency
  • CPU usage
  • Memory usage
  • GPU usage
  • Request rate
  • Provider rate limits

Popular deployment options:

  • Kubernetes deployments with autoscaling
  • ECS or container apps
  • Managed queue workers
  • Serverless event workers for short tasks

Important scaling rule

Do not scale workers faster than your model provider or database can handle. Worker count should match downstream capacity.

Example production stack

A practical stack for many teams looks like this:

  • API: FastAPI, Django, Flask, Express, or Rails
  • Queue: Redis, SQS, RabbitMQ
  • Workers: Celery, Sidekiq, BullMQ, or custom consumers
  • Model access: OpenAI, Anthropic, Bedrock, local vLLM, TGI, or Ollama in controlled environments
  • Storage: Postgres, S3, Redis cache, vector DB
  • Monitoring: Prometheus, Grafana, Datadog, OpenTelemetry
  • Deployment: Docker + Kubernetes, ECS, or managed container platforms

A simple implementation pattern

Here is a basic production flow you can adapt:

  1. Validate the request in the API
  2. Save the raw input and create a job record
  3. Enqueue a job with a unique ID
  4. Worker claims the job
  5. Worker marks status as running
  6. Worker calls the AI model or pipeline
  7. Worker stores output and updates status
  8. Worker emits logs, metrics, and traces
  9. UI polls or receives a callback
  10. Failed jobs move to retry or dead-letter handling

If the job is critical, persist each step so you can resume work after crashes.

Common mistakes to avoid

Running AI inference in the web request

This often causes timeouts and poor user experience.

Sharing one queue for everything

One slow job type can block all others.

Ignoring retries and duplicates

This leads to duplicate writes, duplicate emails, or repeated billing.

Not measuring token usage

Costs can grow silently.

Using a single worker type for CPU and GPU tasks

This wastes resources and hurts performance.

Skipping observability

Without logs and metrics, production issues are hard to diagnose.

When serverless workers are a good fit

Serverless background workers can work well if jobs are short and spiky.

Good fit:

  • Small text transformations
  • Light classification
  • Event-triggered enrichment
  • Occasional document processing

Less ideal:

  • Long model warmup
  • Large file processing
  • GPU workloads
  • High-throughput inference
  • Tasks that need consistent low latency

If your AI jobs are frequent or heavy, dedicated worker services are usually more reliable.

Production checklist

Before launching, make sure you have:

  • A queue system
  • Idempotent job handlers
  • Retries with backoff
  • Dead-letter handling
  • Job status storage
  • Metrics and alerts
  • Structured logs
  • Traceability across services
  • Cost monitoring
  • Rate limiting and throttling
  • Security controls for sensitive data
  • A rollback plan for prompt or model changes

Bottom line

The best way to run background workers for AI tasks in production is to treat them like a real distributed system, not just a helper script. Put AI work behind a queue, make jobs idempotent, isolate worker types, add retries and dead-letter handling, monitor latency and cost, and scale based on real demand. That approach keeps your app fast, your AI pipeline reliable, and your production environment much easier to operate.

If you want, I can also turn this into:

  • a Node.js example with BullMQ
  • a Python example with Celery
  • a Kubernetes deployment pattern
  • or a serverless architecture for AI background jobs
How do I run background workers for AI tasks in production? | Platform as a Service (PaaS) | Codeables | Codeables