Skip to content
System types · Built-in All levels

Paperless-ngx

The built-in Paperless-ngx system type - detection prefixes, getting traces and metrics out of an instance that ships neither, starter checks for ingest failures, backlog, component health and storage, and the two prerequisites the checks depend on.

SLSluicio team 6 min read Updated Aug 2026

Paperless-ngx is an open-source document management system: it watches a folder, an inbox and an API for incoming documents, runs OCR, classifies them, and files them into a searchable archive. That intake is a pipeline, and pipelines fail in ways a “is it up” check never sees - a scanner feeding unreadable PDFs, an OCR stage that quietly doubles in duration, a queue that stops draining while the web UI stays perfectly responsive.

Key: paperless-ngx · applied automatically to services emitting paperless_-prefixed metrics.

Paperless-ngx ships no OpenTelemetry support and no metrics endpoint. Both signals come from outside it, and both are needed - they answer different questions.

Traces come from Python auto-instrumentation layered onto the published image. Nothing in paperless changes; a sitecustomize.py on PYTHONPATH instruments every process the container starts, and each reports as its own service (paperless-webserver, -worker, -consumer, -scheduler).

Metrics come from prometheus-paperless-exporter, which reads paperless’ REST API with least-privilege view permissions. Scrape it with the Collector’s prometheus receiver:

otel-collector.yaml (excerpt)
receivers:
prometheus:
config:
scrape_configs:
- job_name: paperless-exporter # becomes service.name
scrape_interval: 30s
static_configs:
- targets: [exporter:8081]
processors:
# paperless_task_status is one series per task id. Aggregate the id away
# and sum: pending becomes queue depth, failure becomes an error count.
metricstransform/tasks:
transforms:
- include: paperless_task_status
action: update
operations:
- action: aggregate_labels
label_set: [status]
aggregation_type: sum

A working end-to-end setup - compose file, instrumented image, scenario scripts that drive every ingest outcome - is published at github.com/syron/paperless-ngx-otel.

Metrics whose names start with paperless_, emitted by the exporter. Auto-instrumentation alone produces only process.*, system.* and flower.* - far too generic to claim a system type from, so detection requires the exporter. Traces alone won’t identify the system.

CheckConditionSeverityWhy it matters
Document ingest failedError traces in 15 minutesWarningA document failed to consume. The trace names the document and the stage.
New ingest failurespaperless_task_status{status="failure"} increasing (delta)WarningOverlaps the trace check deliberately - this one still fires when the worker’s telemetry pipeline is down.
Slow document ingestp95 consume time > 60,000 msWarningOCR dominates ingest time; a step change usually means bigger scans or a starved worker.
Ingest backlogpaperless_task_status{status="pending"} > 25WarningTasks are queued and not draining - a wedged worker, or intake outrunning OCR.
Documents unfiledpaperless_statistics_documents_inbox_count > 100WarningDocuments consumed fine but nobody has filed them. A business backlog, not a fault.
Celery worker unhealthypaperless_status_celery_status < 1CriticalNothing will consume - and no trace will be emitted to tell you so.
Redis unhealthypaperless_status_redis_status < 1CriticalThe broker paperless queues through is unreachable.
Database unhealthypaperless_status_database_status < 1CriticalPaperless cannot reach its database.
Unapplied migrationspaperless_status_database_unapplied_migrations > 0WarningThe image was upgraded but migrations never ran - a half-upgraded instance.
Low document storagepaperless_status_storage_available_bytes < 2 GiBWarningPaperless fails ingest hard when document storage runs out.
Classifier staleLast trained more than 7 days agoWarningAuto-tagging quality drifts silently, with no failure anywhere.
  • Ingest latency. 60 seconds is generous because it has to cover OCR on a multi-page scan. If you ingest mostly digital PDFs with a text layer, tighten it hard - those complete in well under a second, and 60 s would hide a tenfold regression.
  • Backlog threshold. 25 pending tasks suits a household or small office. A bulk import legitimately queues thousands; raise it, or silence the check during migrations.
  • Unfiled documents. This one tracks a human habit, not system health. If you file in weekly batches it will nag every week - raise it or disable it.
  • Duplicate rejections do not appear as failures in traces. consume_file returns a duplicate result rather than raising, so the span looks identical to a success. Paperless does record the task as a failure, so the metric check catches it - expect the two failure checks to disagree, and treat the metric as the broader signal.
  • A silent instance is normal. No dead-man check ships with this type on purpose: most paperless instances legitimately go hours without a document. If yours has continuous intake, add a trace-volume check yourself.