Opens in a new tab
Guide

OpenTelemetry Collector queues and the wait for fresh data

In brief

A durable queue can preserve telemetry through an outage, then take longer to catch up. Arrival rate, export capacity and event age explain what recovery looks like.

8 min read

Sources
Conceptual illustration of old clock-marked observations replaying from a queue while a separate current observation is inspected.
Preserved observations explain the earlier window. A separate current observation is needed before an assistant treats a replayed spike as evidence for action now.
On this page6 sections

Consider a hypothetical inference service whose telemetry backend is unavailable for four minutes while requests continue. A persistent OpenTelemetry Collector queue preserves many of those observations. After reconnection, an incident assistant sees the replayed error spike, but the records describe work performed during the outage. If it treats arrival time as event time, authentic data can prompt an action based on a condition that may have ended.

The assistant needs an age limit for the observations used to trigger that action. Without current observations, it cannot establish whether the old spike is continuing. The monitoring-freshness principle therefore gives recovery two separate goals: preserve the history that explains the outage, and restore observations timely enough to decide what to do now.

A durable queue protects one part of the journey

Telemetry enters a Collector, passes through processors and leaves through an exporter. A sending queue holds work that cannot yet be delivered, while retry policy governs attempts after retryable failures. Persistence can keep queued work across a process restart. The OpenTelemetry resilience documentation distinguishes these protections because they act at different points rather than making the whole pipeline durable.

Trace one observation from its application SDK through any local Collector, gateway, backend ingestion and consuming query before sizing the queue. An event discarded by the SDK never reaches a gateway queue. Likewise, making exporter storage disk-backed does not automatically persist a processor’s private memory. The path tells the team which loss a particular setting can actually prevent.

Application events pass through a Collector queue, backend and decision. Queue depth checks delivery pressure; event age at the decision checks freshness. A separate observation path supports decisions during a telemetry outage.
Recovery has two checks: delivery resumes, and the evidence used for the decision is fresh enough. Neither check substitutes for the other.

If an operational decision cannot wait for that path to recover, provide a separate observation or suspend the decision. A narrowly scoped synthetic request can test service behavior without relying on the unavailable telemetry backend. Its result covers the path it exercises, while absent traces still leave other causes or dependencies unexamined.

The backend needs spare capacity to catch up

First identify the unit being queued. The exporter-helper configuration supports sizing in requests, items or serialized bytes. Requests may contain different batch sizes, so a request count cannot be substituted for a span count. Keep the unit with each calculation and verify support in the exact exporter and Collector version.

For steady-rate planning, let arrivals be λ items per second, delivery be μ items per second and backlog be B items. A total delivery outage of T seconds adds λ × T items of demand. Once delivery returns, catch-up takes approximately B ÷ (μ − λ), and only when μ exceeds λ. The difference is the capacity left for history after current arrivals are served; these equations do not predict scheduling or RAM use.

In the illustrative four-minute outage, 1,500 spans per second creates 360,000 queued spans if none is lost or exported. Delivery of 2,000 spans per second leaves 500 per second for that backlog, taking about 720 seconds to drain. Delivery at 1,500 merely keeps pace with new arrivals. A larger buffer can postpone overflow, but cannot supply the spare delivery capacity the arithmetic requires.

That estimated drain time is not the age of every record. Different retry paths can allow newer work to arrive ahead of older work. Measure event age where the assistant reads data, and preserve the source event window with its evidence. Then a recent retrieval timestamp cannot quietly turn a historical observation into a current one.

QuestionEvidence to collectWhat it does not prove
Can the queue absorb the planned outage?Arrival rate, sizing unit, capacity and overflow behaviorThat data remains timely enough to act on
Can the pipeline catch up?Sustained delivery capacity above new arrivalsThat the backend has indexed every accepted event
Is the decision using current evidence?Source event age and expected coverage at query timeThat an unrelated service dependency is healthy

A test Collector with a persistent sending queue

Use a nonproduction Collector and disposable backend or controlled destination. Establish the exact distribution, version and components; a writable test volume; internal-metric access; and permission to interrupt the destination. Agree on a rate and disk allowance, name the pipeline owner and identify who can stop the experiment. Those limits keep a queue-capacity test from consuming shared resources unexpectedly.

The fragment below illustrates how persistence, capacity, consumers and retry settings fit together. It is not a complete configuration or version-pinned deployment. Merge it into a working test pipeline with its existing receivers, processors, backend authentication and TLS, then validate it using the binary that will run the pilot.

extensions:
  file_storage/pilot:
    directory: /var/lib/otelcol/pilot-queue

exporters:
  otlp/pilot:
    endpoint: telemetry-test.example.com:4317
    sending_queue:
      enabled: true
      storage: file_storage/pilot
      sizer: items
      queue_size: 500000
      num_consumers: 4
    retry_on_failure:
      enabled: true
      initial_interval: 5s
      max_interval: 30s
      max_elapsed_time: 10m

service:
  extensions: [file_storage/pilot]
  # Retain your test pipeline and reference otlp/pilot there.

Treat these values as trial inputs rather than production defaults. In particular, the ten-minute retry setting bounds retries for a failed request; it does not promise ten minutes of retention from the source event’s timestamp. Work refused before enqueueing never reaches that retry policy. The test must therefore distinguish failure to enter the queue from failure to export later.

The file-storage extension needs a writable directory. In Kubernetes, choose a volume lifecycle that survives the replacement or restart being tested and provide appropriate separate storage for each Collector. Do not assume multiple processes can safely write one improvised directory. After replacement, verify attachment and permissions: an unchanged path string alone does not prove that the same retained data is present.

The retained data itself is another cost of persistence. Use synthetic payloads rather than credentials or customer prompts, and apply access, encryption and retention requirements to the volume. Include disk, I/O, egress and backend-ingestion costs during replay. More storage can mean both more sensitive material retained and a larger burst when delivery resumes.

Tracing a synthetic sequence through replay

Inspect the Collector’s internal telemetry for queue size and capacity, enqueue failures, receiver refusals, export failures and sent items. These show pressure at different boundaries. An export failure can be retried, so its counter is not a count of permanently lost records. Check actual metric names, labels and units from the pinned build against the queries used to judge it.

For a concrete delivery test, emit a small synthetic sequence with identifiers and source timestamps recorded at the producer. After a defined wait, query the destination and compare unique IDs, duplicates, delays and omissions. This establishes what happened to that sample without claiming exactly-once delivery. Keep IDs in the test data, not in unbounded metric labels.

Watch memory beside the persistent volume. The memory limiter may refuse work under pressure, after which recovery depends on upstream retries. Receivers, processors and active requests still need memory even when export waiting is disk-backed. Enlarging the queue without inspecting the rest of the process can simply move the loss boundary earlier.

How an assistant interprets delayed telemetry

Before failure injection, define two acceptance conditions: the planned short interruption should leave the intended historical evidence available, and immediate automation should visibly abstain whenever its evidence exceeds the owner’s freshness limit. Choose that limit from the consequence of a stale decision, not the amount of disk available to keep records.

  1. At the agreed rate, establish that the synthetic sequence reaches the destination and event age is within the decision’s limit.
  2. Interrupt only the test destination and observe queue growth and export failures. Record when downstream evidence becomes stale and confirm that its reader reports unavailable evidence rather than healthy service.
  3. Restart the Collector while delivery remains unavailable. Check that the intended storage restores the queue, recording losses before that queue separately.
  4. Restore delivery with new arrivals still active. Measure catch-up and query freshness, including whether replay delays or throttles current work.
  5. In a separate bounded test, exceed queue capacity or deny writes to the disposable volume. Confirm that a working path alerts the responsible owner; do not fill shared production storage.
  6. Compare the final synthetic sequence with the producer record and review decisions made along the way. Account for duplicates and gaps, distinguishing a known loss limit from an unexplained omission.

The result has two histories: what arrived and what the responder could justifiably conclude at each stage. A shrinking queue can coexist with stale automation inputs. A fresh synthetic probe can establish current behavior while historical trace gaps remain unexplained. When those gaps matter for diagnosis or audit, preserve them with an owner rather than erasing them from the account of recovery.

When a persistent queue helps

Roll out first to one owned workload and expand only when storage, refusal rate, catch-up and event-age results meet the agreed conditions. Keep the previous configuration and a stop procedure. Before rollback changes queue identity or removes storage, deliberately stop or redirect test input and account for retained work. Deleting the volume would remove evidence the pilot still needs to interpret.

If the allowed evidence age is shorter than the outage being buffered, persistence cannot make replay suitable for an immediate decision. Preserve useful history, but give the urgent action an independent observation path or wait until current visibility returns. An hourly, low-consequence trend may reasonably accept delay instead of adding another durable component.

For a consuming alert or agent, the Collector runbook should identify the permitted event age and the alternate observation used during an outage. The four-minute example then yields two useful answers: which historical spans survived, and when the incoming observations became fresh enough to guide the next action. Exporter reconnection marks the beginning of that recovery, while the queue and query measurements show how far it has progressed.

Sources & context

Sources linked in this article. Read alongside the author’s analysis; a citation does not independently verify a publisher’s claims.

Report an error or outdated detail

Related reading

Explore a related question