SDK & Framework Guides

Error Tracking for RQ Jobs

Master Python RQ job queue monitoring with external error tracking. Get stack traces, grouped issues, and alerts for silent job failures.

RQ is a lightweight, Redis-backed job queue for Python that lets you offload work without the operational weight of Celery. But RQ dashboards show you that a job failed—not why. When a background job silently crashes in production, you're left digging through logs or replaying the job locally. Python RQ job queue monitoring demands more than job status; it demands the full context: stack traces, the events that led to failure, and the ability to group similar errors. This guide covers how to instrument RQ with external error tracking to catch job failures before they impact users.

Why Job Queue Errors Fly Under the Radar

RQ's dashboard is excellent for ops: it shows queue depth, job status, failed counts, and retry history. But from a debugging perspective, it's incomplete. A failed job appears in the UI, but without a stack trace, breadcrumbs, or context data—you're guessing what went wrong. Worse, if a job fails silently (timeout, out-of-memory, uncaught exception), the error is often logged only to the RQ worker process's stdout, which may or may not be persisted. If you're running workers in containers or on ephemeral infrastructure, those logs disappear. The result: production errors in RQ jobs become invisible until a customer complains.

Unlike Celery, which has more battle-tested monitoring integrations, RQ remains an underexplored niche. Most teams instrument their web request handlers with error tracking, but leave job processing unmonitored. This gap is easily fixed: RQ supports custom failure handling, and Sentry's Python SDK (which also works with LightTrace) integrates seamlessly with job exception handlers.

The RQ Dashboard Isn't Enough

The built-in RQ dashboard tells you:

  • How many jobs are queued, working, or failed
  • The Job ID, function, and arguments
  • Retry attempts and timestamps
  • Rough queue health

It doesn't tell you:

  • The stack trace that caused the failure
  • Variables or state at the time of crash
  • Whether this failure is a repeat of a known issue
  • Events (API calls, database queries, cache misses) that led to the error
  • How many unique error patterns are happening vs. raw count

This means a single job queue can fail 1,000 times in a day, all from the same bug, and you'd treat each as a separate incident. A real error tracker deduplicates by fingerprint—grouping identical errors into a single issue—and can alert you once instead of spamming your inbox.

If you're only looking at RQ's dashboard, you're not seeing the full picture. Instrument your job handlers with error tracking to get stack traces, breadcrumbs, and grouped issues—the same visibility you have in your web request handler.

What External Error Tracking Adds

When you wire RQ job failures into an error tracker, you gain:

Stack traces & context: The full backtrace, local variables, and environment at the moment of crash.

Grouping & deduplication: Identical errors are automatically merged into a single issue. If the same bug causes 50 job failures, you see one issue with 50 events, not 50 separate tickets.

Breadcrumbs: A time-ordered log of events that led to the failure—Redis calls, database queries, API requests, log messages.

Tags & affected context: Job ID, queue name, worker hostname, user ID if applicable—anything you want to add as searchable metadata.

Release tracking & health: If a job failure correlates with a deploy, you'll see it. Track session or job health—"99.9% of jobs succeeded after release v1.2.3."

Alerts: Set thresholds (new error type, or frequency spike) and get notified via email. No more waiting for a user report.

When you add error tracking to your app, the same SDK that instruments your web server can also instrument RQ. The difference is a few extra lines in your job failure handler.

Setting Up Sentry SDK with RQ

The Sentry Python SDK works with RQ out of the box. Start by installing and initializing:

import sentry_sdk
from sentry_sdk.integrations.rq import RqIntegration

sentry_sdk.init(
    dsn="https://<your-key>@light-trace.robomiri.com/1",
    integrations=[RqIntegration()],
    traces_sample_rate=1.0,  # Capture all transaction events
)

Replace light-trace.robomiri.com with your LightTrace instance (e.g., errors.light-trace.robomiri.com if you signed up), and your-key with your project's DSN key.

The RqIntegration() handles job execution spans and failure capture automatically. No further setup is needed—when a job crashes, Sentry captures the exception and all attached context.

If you don't have a LightTrace account yet, a Sentry-compatible project DSN works here—just point the dsn to your LightTrace host instead of sentry.io.

Capturing Job Failures & Retries

RQ's job.meta and custom failure handlers give you fine-grained control over what context gets attached to an error. Here's a realistic job that deliberately captures useful context:

import sentry_sdk
from rq import Queue
from redis import Redis

redis_conn = Redis()
q = Queue(connection=redis_conn)

def process_payment(order_id, amount):
    """A background job that might fail mid-transaction."""
    # Attach context to this transaction
    sentry_sdk.set_context("order", {
        "order_id": order_id,
        "amount": amount,
    })
    
    # Simulate a failure
    if amount > 10000:
        raise ValueError("Amount exceeds limit")
    
    return f"Payment of {amount} for order {order_id} processed"

# Enqueue the job
job = q.enqueue(process_payment, 12345, 500)

When process_payment raises an exception, Sentry captures it with the order context attached. In the error tracker, you'll see a grouped issue titled "Amount exceeds limit" with all events tagged by order_id.

For retries, RQ's default behavior is to re-queue failed jobs. Sentry captures each attempt separately, so you can see the retry history: did the job succeed on retry #2? Or keep failing with the same error? The error tracker shows you the full progression.

# Enqueue with explicit retries
job = q.enqueue(
    process_payment,
    12345,
    500,
    job_timeout=300,
    failure_ttl=500,  # Keep failed job record for 500 seconds
    meta={"retry_count": 0},
)

Distributed Tracing for Async Workflows

RQ jobs often chain or depend on each other. A payment processing job might spawn a billing-email job downstream. Sentry's distributed tracing (which LightTrace supports) connects these transactions across service boundaries.

import sentry_sdk
from sentry_sdk import start_transaction

def create_invoice(order_id):
    """Main job."""
    with start_transaction(op="job", name="create_invoice"):
        sentry_sdk.set_context("order", {"order_id": order_id})
        
        # Do work...
        invoice_id = generate_invoice(order_id)
        
        # Spawn a follow-up job
        q.enqueue(send_invoice_email, invoice_id)
        
        return invoice_id

def send_invoice_email(invoice_id):
    """Spawned from create_invoice."""
    with start_transaction(op="job", name="send_invoice_email"):
        sentry_sdk.set_context("invoice", {"invoice_id": invoice_id})
        # Do work...

In the error tracker, if send_invoice_email fails, you'll see the full trace: which parent job spawned it, what order triggered it, and the exact point of failure. This visibility is crucial when debugging workflows that span multiple services or job types.

Alert Rules & Monitoring Job Health

Once you're capturing job errors, set up alert rules. In most error trackers, you can alert on:

  • New error type: A previously unseen crash pattern—catch bugs before they spread.
  • Frequency threshold: "Alert if the error rate exceeds 10 errors per hour."
  • Release regression: "Alert if this error didn't occur in v1.2.2 but does in v1.2.3."

Configure alerts to notify your team via email (the primary channel for error tracking). When a critical job failure spike happens at 3 AM, you'll know immediately instead of discovering it from error logs during standup.

You can also track release health: deploy v1.2.3, and watch the percentage of jobs that succeed vs. fail. If a deploy causes a regression in a specific job type, it's immediately visible.

Set a low threshold for new errors (e.g., "alert on first occurrence") and a higher threshold for recurring errors (e.g., "alert if rate > 100/hour"). This prevents alert fatigue while catching novelty issues fast.

Beyond RQ: Expanding Job Monitoring

If you're using RQ for background work, you likely have other async processes: scheduled tasks, webhooks, cron jobs. The same error tracking setup works for all of them. If you're running a Node.js service alongside your Python workers, or a GraphQL API, each can instrument its own error tracking. A single error tracker acts as a unified incident hub across your entire platform.

As your system grows, you might evaluate other job queues (Celery for heavier workflows) or alternative approaches. But whatever you choose, external error tracking is non-negotiable. It's the difference between "we have a job queue" and "we understand what our job queue is doing."

Start monitoring your RQ jobs today—catch silent failures before they compound into outages.

Start tracking errors in minutes

Get visibility into your RQ job failures. Start a free LightTrace account to see full stack traces, grouped issues, and alerts for your background jobs.

Fix your next production error faster

Point any Sentry SDK at LightTrace — free up to 5,000 events/month.