What Is the Memory Limiter Processor in OpenTelemetry?

What Is the Memory Limiter Processor in OpenTelemetry?

The OpenTelemetry Collector sits in the middle of your telemetry traffic, and a sudden flood of data can push it out of memory and crash it. The memory limiter processor is the safety valve that watches memory use and politely turns data away before disaster strikes.

Imagine a small tea shop with ten seats and a kitchen that can prepare a fixed number of orders at once. On a normal day, customers arrive in a steady trickle and everything runs smoothly. Then a bus full of tourists arrives. If the shopkeeper accepts every single order, the kitchen overflows, cups pile up, and eventually the whole shop shuts down in chaos. A wise shopkeeper puts up a sign that says “please wait outside for a few minutes,” keeps serving the customers already inside, and reopens the door as soon as space is free. The memory limiter processor is that wise shopkeeper for your telemetry pipeline.

1The Problem: A Collector That Runs Out of Memory

Every program that receives data from outside has a danger hiding inside it: what if too much arrives at once?

Telemetry traffic is never smooth

Applications send traces, metrics, and logs to a central program called the OpenTelemetry Collector. In calm times the amount of data is predictable. But real systems have spikes. A new release can double the number of log lines. A retry storm can multiply the number of spans. A single misbehaving service can start sending metrics with thousands of new label combinations.

The Collector must hold data in memory while it processes it. It may batch the data, enrich it, or wait to send it to a backend that is temporarily slow. When data arrives faster than it leaves, the extra data piles up in memory, and the pile keeps growing.

What happens when memory runs out

Every computer has a limited amount of memory. In a container platform such as Kubernetes, each container is given a strict memory allowance. If the program inside uses more than its allowance, the platform kills it immediately. This is called an out-of-memory kill, or OOM kill. The Collector disappears without warning, and every piece of data it was holding in memory is lost.

Worse, when the Collector restarts, the senders often retry all their pending data at once. That creates another spike, which may crash the Collector again. This repeating pattern is called a crash loop, and it can leave you blind exactly when you need observability the most.

Simple Analogy

Think of a water tank with a pipe flowing in and a tap flowing out. If water comes in faster than it goes out, the tank overflows and floods the room. A float valve on the inlet pipe closes when the water level gets high, and reopens when the level falls. The memory limiter is the float valve for your Collector.

i
Key Idea

The memory limiter does not make the Collector use less memory in general. It protects the Collector from running out of memory during unusual surges by controlling how much new data is allowed in.

2A Quick Refresher on the Collector and Its Pipelines

To place the memory limiter correctly, you first need a clear picture of the Collector’s structure.

The Collector in one paragraph

The OpenTelemetry Collector is a standalone program that receives telemetry, processes it, and exports it onward. It is vendor neutral, which means it can accept data in many formats and send it to many different backends. Teams use it to avoid sending data directly from every application to every backend, and to centralize tasks such as filtering, batching, and retrying.

The four building blocks

Block 1

Receiver

The front door. It accepts incoming data, such as an OTLP network call from an application, or it pulls data from somewhere, as a scraper does.

Block 2

Processor

A workshop station in the middle. It can change, filter, group, or limit data as it passes through.

Block 3

Exporter

The back door. It sends the finished data to a destination such as a tracing backend, a metrics store, or a log platform.

Block 4

Pipeline

The assembly line that connects receivers, then processors in order, then exporters, for one type of signal such as traces, metrics, or logs.

Order matters

Inside a pipeline, processors run one after another in the order you list them. The output of the first becomes the input of the second. This ordering is not a minor detail. It decides what each processor sees and what protection each one can offer. For the memory limiter, the order is especially important, as later chapters will show.

flowchart LR
    R["Receivers"] --> P1["Processor 1"]
    P1 --> P2["Processor 2"]
    P2 --> P3["Processor 3"]
    P3 --> E["Exporters"]
        
FIG 1 — A simple Collector pipeline with processors in sequence
Simple Analogy

A pipeline is like an airport. Receivers are the entrance doors, processors are the security checks and passport counters in a fixed order, and exporters are the departure gates. A guard at the entrance can stop a crowd from flooding the checkpoints.

3So, What Is the Memory Limiter Processor?

A plain definition first, then the behavior that makes it useful.

The definition

The memory limiter processor is a component of the OpenTelemetry Collector that periodically measures how much memory the Collector is using and, when that memory gets too high, starts refusing new data so that the Collector can recover before it crashes. It is designed to prevent out-of-memory situations caused by sudden surges of incoming telemetry.

The three things it does

1

It watches

At regular short intervals, it checks the current memory use of the Collector process and compares it to the limits you configured.

2

It refuses

When memory passes a warning level called the soft limit, it begins rejecting incoming data, sending an error back toward the receiver instead of passing the data down the pipeline.

3

It forces cleanup

When memory passes the harder, higher limit, it asks the runtime to run garbage collection, which means cleaning up memory that is no longer needed, to bring usage down faster.

What it is not

It is not a data filter that chooses which telemetry is important. It does not look at the content of spans, metrics, or logs. It makes no decisions based on what the data says, only on how full memory is. It is also not a replacement for giving the Collector enough memory in the first place, and not a replacement for scaling out when your normal load grows.

“The memory limiter does not decide what is valuable; it decides when to say ‘not right now.'”
!
Common Misconception

Some people think the memory limiter caps memory like a strict ceiling that the process can never cross. It does not. It is a reactive guard that checks at intervals and reacts. Memory can still rise between checks, which is why the settings leave a safety margin.

4A Gentle Look at How the Collector Uses Memory

You do not need to be a systems expert, but a few simple ideas make the settings much easier to understand.

The Collector is written in Go

The Collector is a program written in the Go language. Go manages memory automatically. It hands out memory to your data as needed and has a background cleaner, called the garbage collector, that finds memory no longer in use and frees it. This is convenient, but it means memory use is not always a precise, instant number. The cleaner runs from time to time, not constantly.

The heap

The part of memory where the program stores most of its changing data, such as batches of spans waiting to be sent, is called the heap. The memory limiter looks at the heap size when it measures. Besides the heap, the process also needs some extra memory for itself, such as program code and internal bookkeeping, so the total used by the container is somewhat higher than the heap alone.

Where the memory goes inside a Collector

Place 1

Receiver buffers

Incoming requests are decoded and held briefly before being passed on. Large or numerous requests mean larger buffers.

Place 2

Batch processor

Telemetry waits here until enough has gathered or a timer fires, so that it can be sent in efficient groups.

Place 3

Exporter queues

When a backend is slow or down, exporters keep data in a queue and retry. This is often the biggest memory consumer during outages.

Place 4

Stateful processors

Some processors, such as those that group spans into whole traces or compute metric deltas, must remember data for a while.

Simple Analogy

Think of a kitchen counter. Dishes waiting to be cooked, dishes waiting to be served, and dishes waiting to be washed all take up counter space. A cleaner comes by now and then to clear it. If dishes arrive faster than the cleaner and the cooks can handle them, the counter fills up and nothing else fits.

i
Good to Know

The memory limiter does not know which of these places is using the memory. It looks only at the total. That is why it works well as a general protector regardless of the cause of the pressure.

5Soft Limit, Hard Limit, and Spike Limit

The processor works with two thresholds and a safety margin. Understanding them is the heart of the topic.

The hard limit

The hard limit is the maximum amount of memory, in mebibytes, that you want the Collector process heap to use. A mebibyte is a standard unit of memory slightly larger than a megabyte. When measured memory goes above the hard limit, the processor not only refuses data but also triggers garbage collection to push memory back down.

The spike limit

The spike limit is a safety margin. It estimates how much memory could suddenly be added between two checks. If the Collector is receiving data very fast, memory could jump a lot in one second. The spike limit is the room you keep in reserve for that jump. If you do not set it, a default of about twenty percent of the hard limit is commonly used.

The soft limit

The soft limit is not set directly. It is calculated as the hard limit minus the spike limit. Once memory goes above the soft limit, the processor starts refusing new data. Because the soft limit sits below the hard limit, refusing starts early enough that the spike margin can absorb data still in flight.

ThresholdHow it is setWhat happens when memory crosses it
Soft limitHard limit minus spike limitNew data is refused until memory falls back below this level
Hard limitConfigured directlyData is refused and garbage collection is forced to reduce memory
Spike limitConfigured, or a default share of the hard limitActs as the safety margin that defines the soft limit
stateDiagram-v2
    [*] --> Normal
    Normal --> Refusing: Memory above soft limit
    Refusing --> Normal: Memory below soft limit
    Refusing --> ForcedGC: Memory above hard limit
    ForcedGC --> Refusing: Garbage collection done, still above soft limit
    ForcedGC --> Normal: Memory drops below soft limit
        
FIG 2 — The states of the memory limiter as memory rises and falls

A worked example in words

Suppose you set the hard limit to 1,000 mebibytes and the spike limit to 200 mebibytes. The soft limit is then 800 mebibytes. While memory stays under 800, everything flows normally. When memory climbs past 800, the processor begins refusing incoming data. If memory somehow still climbs past 1,000, it also forces garbage collection. When memory falls back under 800, data is accepted again.

Simple Analogy

A lift has a rule that says “stop letting people in at 8 passengers” even though the true limit is 10. The two empty spots are the safety margin for people already running toward the doors. The soft limit is 8, the hard limit is 10, and the spike margin is 2.

!
Common Mistake

Setting the spike limit larger than or equal to the hard limit makes no sense, because the soft limit would become zero or negative. The processor is designed to reject such configuration at startup.

6The Settings You Can Tune

There are only a few settings, which is part of what makes the processor easy to adopt.

Setting 1

check_interval

How often memory is measured. A common recommendation is about one second. Spiky traffic benefits from shorter intervals, because there is less time for memory to jump unnoticed.

Setting 2

limit_mib

The hard limit as a fixed number of mebibytes. Use this when you know exactly how much memory the Collector gets.

Setting 3

spike_limit_mib

The safety margin as a fixed number of mebibytes. The soft limit equals the hard limit minus this value.

Setting 4

limit_percentage

The hard limit expressed as a percentage of the total memory available to the process, such as the container allowance. Handy when the same configuration runs on machines of different sizes.

Setting 5

spike_limit_percentage

The safety margin expressed as a percentage of the total available memory, used together with the percentage-based hard limit.

Fixed numbers versus percentages

You choose between two styles. Fixed numbers are simple and predictable, and they are good when you control the container size. Percentages adapt automatically to the memory the process can see, which is helpful when the same configuration file is shared across environments with different resource sizes. You should pick one style for the hard limit and not mix the two for the same threshold.

StyleBest forWatch out for
Fixed mebibytesStable environments with a known container sizeForgetting to update the limit when the container size changes
PercentageShared configuration across varied machine sizesPercentages are based on what the process detects as available, so verify detection in your platform
i
Documentation Tip

Exact setting names, default values, and which settings are required can change between Collector versions. Always confirm the details in the current Collector documentation for the version you run.

~1 sec
Commonly recommended check interval
2
Thresholds: soft and hard
1
Safety margin: the spike limit

7Back-pressure: What Happens to Refused Data

Refusing data sounds simple, but what the sender does next decides whether you lose anything.

What refusing really means

When the memory limiter is in refusing mode, it does not quietly throw data away. It returns an error up the chain, back to the receiver that handed it the data. The receiver is then expected to tell the sender that the Collector is temporarily unable to accept the data. This signal going backwards against the flow of data is called back-pressure.

Why back-pressure is a good thing

Back-pressure moves the problem to the place that is best able to handle it. Instead of the Collector crashing and losing everything, the sender, which has the data, is told to wait. Many senders keep the data in a small buffer and retry after a short delay. By the time they retry, the Collector has recovered.

It depends on the receiver and the sender

How well this works depends on both ends. A push-style receiver, such as one accepting OTLP calls, can return a retryable error to the application’s exporter. A pull-style receiver, which scrapes data from targets, simply skips or fails that scrape, and the data for that moment may be lost, although the next scrape will usually succeed.

Receiver styleWhat the memory limiter’s refusal causesIs data lost?
Push receiver with retrying clientsClient gets a retryable error and tries again laterUsually no, if the client buffers and retries long enough
Push receiver with non-retrying clientsClient gets an error and drops the dataYes, on the client side
Pull receiver, such as a scraperThat collection round fails or is skippedPossibly a gap for that interval
Receiver reading from a message queueConsumption slows and messages stay in the queueUsually no, the queue acts as a buffer
sequenceDiagram
    participant A as Application Exporter
    participant R as Receiver
    participant M as Memory Limiter
    participant X as Rest of Pipeline
    A->>R: Send batch of telemetry
    R->>M: Pass data to first processor
    M->>M: Check memory state
    alt Memory below soft limit
        M->>X: Accept and forward
        X-->>A: Success
    else Memory above soft limit
        M-->>R: Refuse with error
        R-->>A: Retryable error response
        Note over A: Wait and retry later
    end
        
FIG 3 — How a refusal travels back to the sender
!
Heads Up

Refusing is only safe if senders are configured to retry. Check the retry and buffering settings in your SDKs and agents. A sender that drops data on the first error turns every memory pause into permanent data loss.

Simple Analogy

A post office that is overloaded can say “please come back in ten minutes,” and customers keep their parcels. That is far better than the post office silently shredding parcels or collapsing from overload.

8Where to Place It: The First Processor Rule

If you remember one placement rule, remember this one.

The recommendation

The memory limiter should be the first processor in each pipeline, placed immediately after the receivers. This is the standard guidance in the Collector documentation, and the reasons are practical.

1

Refused data never enters the pipeline

If the limiter is first, data that is rejected does no further work. It is not decoded further, enriched, or batched, which saves memory right at the source.

2

The error returns directly to the receiver

Because nothing has happened in between, the refusal reaches the receiver quickly and cleanly, so the sender can react without delay.

3

Memory-hungry processors are protected

Processors that hold data, such as batching or trace grouping, come after the limiter, so they only receive data that the Collector has room for.

What goes wrong with bad placement

If the limiter is placed after a batching processor, the batcher may already have accepted and stored a large amount of data before the limiter gets a chance to say no. The data in the batcher still occupies memory, and the limiter can only protect against data that has not yet reached it. In effect, you have put the guard inside the shop instead of at the door.

flowchart LR
    R["Receiver"] --> M["Memory limiter first"]
    M --> A["Attribute and filter processors"]
    A --> B["Batch processor"]
    B --> E["Exporter"]
        
FIG 4 — The recommended order with the memory limiter first
i
Rule of Thumb

Put the memory limiter first, and put the batch processor last among processors, just before exporters. Everything else goes in between.

!
Every Pipeline Needs It

Each pipeline that handles a signal type, such as traces, metrics, or logs, should include the limiter. Protecting only one pipeline leaves the others exposed, and memory pressure in any pipeline affects the whole process.

Simple Analogy

A bouncer works at the club entrance, not at the dance floor. By the time guests are on the dance floor, it is too late to decide the room is full.

9Choosing the Right Numbers

Good settings come from understanding your container, your traffic, and your safety margins.

Start from the container allowance

The first number to know is the total memory your Collector container or machine is allowed to use. The memory limiter’s hard limit must sit comfortably below that total. This is because the process uses extra memory beyond the heap, and because the limiter reacts with a small delay. If the hard limit equals the container allowance, an OOM kill can still happen before the limiter acts.

A common guideline

A widely used rule of thumb is to set the hard limit at roughly eighty percent of the container’s memory allowance, and the spike limit at roughly twenty to twenty-five percent of the hard limit. This leaves a buffer for non-heap memory and for the fast spikes between checks. Treat these as starting points, then adjust using real measurements from your environment.

Container memorySuggested hard limit (about 80 percent)Suggested spike limit (about 20 to 25 percent of hard)Resulting soft limit
512 MiBAbout 400 MiBAbout 80 to 100 MiBAbout 300 to 320 MiB
1,024 MiBAbout 800 MiBAbout 160 to 200 MiBAbout 600 to 640 MiB
2,048 MiBAbout 1,600 MiBAbout 320 to 400 MiBAbout 1,200 to 1,280 MiB
4,096 MiBAbout 3,200 MiBAbout 640 to 800 MiBAbout 2,400 to 2,560 MiB

Match the spike limit to your traffic pattern

If your traffic is steady, a smaller spike margin is fine. If your traffic arrives in sharp bursts, for example from batch jobs that send large payloads at once, a larger margin or a shorter check interval is wise. The goal is that the largest realistic jump in memory between two checks fits inside the spike margin.

Example: A bursty logging gateway

A team runs a gateway Collector that receives logs from many services. Every hour, a scheduled job flushes a large number of log lines in a few seconds. They find that memory occasionally touches the hard limit. They respond by shortening the check interval and enlarging the spike margin, and the container stops being killed.

i
Validate with Load

Test your settings by sending synthetic bursts at the Collector in a staging environment. Watch whether it enters refusing mode and recovers before the container is killed. Numbers that look right on paper may behave differently under real load.

Simple Analogy

When packing a suitcase for a flight with a weight limit, you do not aim for exactly the limit. You leave some room, because souvenirs may be added on the way back. The gap between your target and the real limit is your safety margin.

10Working Alongside the Garbage Collector, Batching, and Queues

The memory limiter is one safety tool among several, and it works best in combination.

The runtime memory limit setting

Go programs can be given a soft memory target through a standard environment variable named GOMEMLIMIT. When set, the Go runtime tries to garbage collect more aggressively as the process approaches that target. Many operators set this to a value a little below the container allowance, and some also align it with the memory limiter’s hard limit. It complements the limiter by making cleanup happen sooner, while the limiter controls the inflow of data. Confirm the current recommended practice in the Collector documentation for your version.

The old ballast approach

Older guides mention a memory ballast, which was a large block of unused memory allocated on purpose to change how the garbage collector behaved. That approach has been replaced by the runtime memory limit setting, and recent Collector versions have moved away from it. If you find tutorials describing ballast configuration, treat them as outdated and check current guidance.

Batch processor

The batch processor groups data before sending. Larger batches and longer wait times mean more data held in memory. It is wise to keep batch sizes reasonable and to place the batch processor after the memory limiter, so the limiter can control how much data arrives to be batched.

Exporter queues and retries

Exporters often have a sending queue that holds data while a backend is slow, and retry settings that decide how long to keep trying. A large queue can become the main consumer of memory during an outage. The queue size should be chosen with the memory budget in mind. Where durability matters, some deployments store the queue on disk through a storage extension, which reduces memory pressure and survives restarts.

Tool 1

Memory limiter

Controls how much new data is accepted, based on current memory use.

Tool 2

Runtime memory target

Makes the garbage collector work harder as memory nears a chosen target.

Tool 3

Bounded batch and queue sizes

Limits how much data the Collector may hold in internal buffers at any time.

Tool 4

Disk-backed queues

Moves waiting data out of memory when durability and memory savings are both needed.

Tool 5

Horizontal scaling

Adds more Collector instances when the normal load, not just spikes, outgrows one instance.

!
Common Mistake

Relying on the memory limiter alone while leaving exporter queues enormous. The limiter helps, but if queues can hold more than the whole memory budget, the system will spend most of its time refusing data. Size queues and limits together.

Simple Analogy

Preventing a flood uses several measures together: a dam, drainage channels, and a warning siren. The memory limiter is the siren-and-gate at the entrance, while queue limits and cleanup settings are the drainage.

11A Day in the Life: Surviving a Traffic Spike

Let us follow a realistic spike from the first signs to full recovery.

The scenario

A retail company runs a gateway Collector with a memory limiter configured as the first processor. A flash sale begins, and the volume of traces triples in a few minutes. At the same time, the tracing backend slows down because it is also under load.

1

Traffic rises

More spans arrive than the exporters can send. The sending queue begins to fill, and memory rises steadily.

2

Soft limit is crossed

At the next check, the limiter sees that memory has gone past the soft limit. It switches to refusing mode and starts returning errors to the receiver.

3

Applications back off

Application exporters receive retryable errors. They keep the data in their own buffers and retry after short delays, so the inflow to the Collector drops.

4

The Collector catches up

With less new data coming in, exporters drain the queue as the backend recovers. Garbage collection frees released memory, and usage falls.

5

Normal service resumes

When memory drops below the soft limit, the limiter stops refusing. Retried data flows in at a manageable pace, and the Collector never crashed.

flowchart TD
    S["Spike in incoming data"] --> Q["Queues fill, memory rises"]
    Q --> C{"Above soft limit?"}
    C -- "No" --> N["Keep accepting data"]
    C -- "Yes" --> R["Refuse new data with errors"]
    R --> B["Senders retry later"]
    B --> D["Queues drain, memory falls"]
    D --> C
        
FIG 5 — The feedback loop that keeps the Collector alive

What would have happened without the limiter

Without the memory limiter, the queue would have kept growing until the container exceeded its allowance. The platform would have killed the Collector, and all queued data would have vanished. When it restarted, every application would have retried at once, and the cycle might have repeated. The limiter converts a dangerous crash into a calm pause.

“A short pause is a gift; a crash is a debt.”
i
Observation

Notice that the system recovered by itself because all participants behaved well: the limiter refused politely, senders retried, and the backend eventually caught up. If any participant misbehaves, such as a sender that does not retry, the benefit is reduced.

12Monitoring the Memory Limiter

A safety valve that no one watches is a mystery. You should know when yours is doing its job.

Signals worth watching

The Collector exposes its own internal metrics, which describe its health. The memory limiter contributes counters that show how much data it has refused, separately for spans, metric points, and log records. A rising refusal count is a direct sign that the Collector is under memory pressure and sending back-pressure to your applications.

SignalWhat it tells youHow to react
Refused spans, metric points, or log records risingThe limiter is actively rejecting dataInvestigate the cause, then add capacity or tune limits
Process memory near the hard limit oftenThe Collector is regularly close to its ceilingIncrease memory or scale out, and review queue sizes
Exporter queue size near capacityA backend is slow or unreachableCheck backend health and exporter retry settings
Container restarts or OOM killsThe limiter was too lenient or reacted too lateLower the hard limit, enlarge the spike margin, shorten the check interval
Client-side dropped dataSenders are not retrying enoughAdjust retry and buffer settings in SDKs and agents

Alerting suggestions

Create alerts on a sustained non-zero refusal rate, not just a single blip, because brief refusals during a spike are normal and healthy. Alert separately on any container restart for the Collector, since that indicates the limiter did not do its job. Combine these with dashboards that show memory, queue sizes, and refusals side by side, so the story is easy to read.

!
Watch the Watcher

If your Collector sends its own metrics to itself, a memory crisis may interrupt the very data you need to diagnose it. Consider sending Collector self-monitoring data through a separate, small, stable path.

Simple Analogy

A pressure relief valve on a boiler is useful, but only if there is a gauge that tells you when it opens. Frequent opening means the boiler is working too hard and needs attention.

13Deployment Patterns and the Memory Limiter

Where you run your Collector changes how you think about memory protection.

Agent pattern

In the agent pattern, a small Collector runs next to each application, for example on every host or as a sidecar container. It receives data from nearby applications and forwards it onward. These Collectors usually have small memory allowances, so the limiter is especially valuable to keep them from competing with the application for resources.

Gateway pattern

In the gateway pattern, a central pool of Collectors receives data from many sources. These instances carry the most traffic and the most risk of sudden spikes. They benefit from the limiter, from careful queue sizing, and from the ability to scale horizontally behind a load balancer.

Why one limiter is not enough for scale

The limiter protects a single instance. It does not coordinate across instances. If one instance is refusing data, a load balancer might still send new traffic to it, unless it knows the instance is struggling. Good gateway designs combine the limiter with health checks, sensible load balancing, and automatic scaling based on resource use.

Pattern 1

Agent next to the app

Small footprint, protects the host. Refused data goes back to the local application, which can buffer briefly.

Pattern 2

Central gateway pool

Large traffic, shared by many senders. Needs scaling plus the limiter, and depends on retrying clients.

Pattern 3

Tiered agent plus gateway

Agents refuse toward applications, gateways refuse toward agents. Each tier absorbs pressure in turn.

Example: Two-tier protection

A platform team runs small agents on each node and a gateway pool behind a load balancer. During a backend outage, the gateways fill and start refusing. The agents, which also have limiters and modest queues, pass the back-pressure to applications. The pressure spreads across tiers instead of causing a crash at one point.

i
Scaling Reminder

Refusing data is a short-term defense. If the Collector refuses data most of the day, the real fix is more capacity, not looser limits.

14Benefits, Trade-offs, and Security Angle

Like every tool, the memory limiter has strengths and costs.

A defense against overload and abuse

Because the limiter reacts to memory pressure regardless of the cause, it also gives some protection against abusive or accidental floods. A misconfigured service or a malicious sender that blasts huge amounts of data at the Collector cannot force it to consume unlimited memory. The limiter will start refusing before the process crashes. It is not a complete security control, but it is a helpful safeguard for availability.

Advantages

  • Prevents out-of-memory crashes during sudden traffic spikes
  • Turns crashes into recoverable pauses using back-pressure
  • Simple to configure with only a few settings
  • Works regardless of which component is using the memory
  • Protects all signal types when added to every pipeline
  • Gives some resilience against accidental or abusive floods

Disadvantages / Trade-offs

  • Refused data may be lost if senders do not retry
  • Checks happen at intervals, so very fast spikes can slip past
  • Does not fix a chronic shortage of memory or capacity
  • Works per instance and does not coordinate across a fleet
  • Poor placement or poor numbers weaken its protection
!
Limits of the Protection

The limiter cannot take back memory that is already in use by data it accepted earlier. It only controls new arrivals. That is why the soft limit sits below the hard limit, and why other safety measures such as bounded queues are still necessary.

Simple Analogy

A fuse in an electrical circuit prevents damage during a surge, but it does not give you more electricity. If the fuse trips every day, you need a bigger supply or fewer appliances, not a stronger fuse.

15Troubleshooting, Best Practices, and Anti-patterns

A short field guide for when things do not behave as expected.

Troubleshooting guide

SymptomLikely causeWhat to check
Collector is killed by the platform despite having a limiterHard limit too close to container allowance, or spikes too fastLower the hard limit, enlarge the spike margin, shorten the check interval
Limiter refuses data constantlyLimits too low for normal load, or a slow backendCompare normal memory use to the soft limit, and check exporter health
Data is missing in the backend during spikesSenders drop data on refusalEnable retries and buffering in SDKs and agents
Memory stays high even when idleLarge queues or retained data in other componentsReview queue sizes, batch settings, and stateful processors
Limiter seems to have no effectPlaced late in the pipeline or missing from some pipelinesConfirm it is the first processor in every pipeline
Configuration fails to startSpike limit not smaller than the hard limit, or conflicting settingsCheck threshold values and avoid mixing fixed and percentage styles

Habits that work

Practice 1

Always include it

Add the memory limiter to every production pipeline as the first processor, even when traffic seems small.

Practice 2

Leave headroom

Set the hard limit comfortably below the container allowance, and size the spike margin to your burstiest traffic.

Practice 3

Configure retrying senders

Make sure SDKs and upstream agents retry on temporary errors, so that refusals do not become data loss.

Practice 4

Bound the queues

Choose exporter queue and batch sizes that fit within the memory budget, so the limiter is not constantly fighting them.

Practice 5

Monitor refusals

Track refusal counters, memory, and restarts, and alert on sustained patterns rather than single events.

Practice 6

Load test regularly

Rehearse spikes in a safe environment so you learn how the system behaves before real incidents.

Traps to avoid

ANTI-PATTERN-01 Avoid
Problem

The memory limiter is placed after the batch processor or other memory-holding processors in the pipeline.

Why It’s Harmful

Data is already accepted and stored by earlier processors before the limiter can refuse it. The protection arrives too late to prevent the pile-up.

Correct Approach

Place the limiter first, immediately after the receivers, in every pipeline.

ANTI-PATTERN-02 Avoid
Problem

The hard limit is set equal to, or very close to, the container memory allowance.

Why It’s Harmful

The process uses memory beyond the heap, and the limiter reacts only at intervals. The platform may kill the container before the limiter ever acts.

Correct Approach

Keep the hard limit well below the allowance, and keep a spike margin based on real traffic bursts.

ANTI-PATTERN-03 Avoid
Problem

Teams raise the limits again and again whenever refusals appear, without investigating why memory is high.

Why It’s Harmful

The underlying cause, such as a slow backend, huge queues, or growing traffic, remains. Eventually the limits run into the container’s physical ceiling and crashes return.

Correct Approach

Treat frequent refusals as a signal. Find the cause, then scale out, fix the backend, or resize queues, and only then retune the limits.

ANTI-PATTERN-04 Avoid
Problem

Senders are configured without retries, or with very short buffers, while the Collector is expected to refuse data under pressure.

Why It’s Harmful

Every refusal becomes permanent loss. The system appears to protect the Collector but silently damages data completeness.

Correct Approach

Enable sensible retry and buffering behavior at the sender, and test the whole path with a deliberate overload.

16Frequently Asked Questions

Quick answers to the questions people ask most often.

Q1Is the memory limiter processor required?

It is not forced by the software, but it is strongly recommended for any production Collector. Without it, a surge of data can push the process beyond its memory allowance and cause a crash.

Q2Does the memory limiter drop data?

It refuses to accept new data when memory is high, by returning an error to the receiver. Whether data is actually lost depends on the sender. If the sender retries, the data is usually delivered later. If the sender does not retry, the data may be lost.

Q3What is the difference between the soft and hard limit?

The soft limit is the point at which the processor starts refusing new data. It equals the hard limit minus the spike limit. The hard limit is the higher ceiling at which the processor also forces garbage collection to reduce memory.

Q4Why should it be the first processor?

Placing it first means refused data does no further work and consumes no extra memory, and the refusal reaches the receiver quickly. Later processors, which may hold data, receive only what the Collector has room for.

Q5Can I use percentages instead of fixed memory values?

Yes. The processor supports percentage-based settings relative to the memory available to the process. This is useful when the same configuration is used on machines or containers of different sizes. Confirm the exact behavior for your Collector version.

Q6How often should the processor check memory?

A check interval of around one second is the usual recommendation. If your traffic is very spiky, a shorter interval or a larger spike margin reduces the chance of memory overshooting between checks.

Q7Does the memory limiter replace scaling?

No. It protects one instance against short surges. If your normal load regularly approaches the limits, you need more memory per instance or more instances.

Q8Do I need it on both agents and gateways?

It is good practice on both. Agents keep local resource use in check, and gateways handle the largest and spikiest loads. Together they allow back-pressure to flow smoothly through each tier.

Q9How do I know the memory limiter is working?

Watch the Collector’s own metrics for refused spans, metric points, and log records, along with memory use, exporter queue sizes, and container restarts. Occasional refusals during spikes show the limiter doing its job. Container kills show it is not enough.

Q10Does it work for all signal types?

Yes, the processor is designed to work with traces, metrics, and logs. You add it to each pipeline you run so that all signal types are protected.

17Summary and Key Takeaways

The memory limiter processor is a small but vital part of a healthy OpenTelemetry Collector. It watches memory at regular intervals, refuses new data when memory passes a soft limit, and forces cleanup when memory passes a hard limit. By sending errors back to receivers, it creates back-pressure that gives senders a chance to wait and retry, turning a possible crash into a short pause. It works best as the first processor in every pipeline, with limits set comfortably below the container allowance, with sensible queue sizes, and with senders that retry. It is a guard against surges, not a cure for chronic under-provisioning, so monitor refusals and scale when the pressure is constant rather than occasional.

Key Takeaways

  • It protects the Collector from out-of-memory crashes — it measures memory at intervals and refuses new data when usage is too high.
  • Two thresholds and a margin — the soft limit, equal to the hard limit minus the spike limit, starts refusals; the hard limit also forces garbage collection.
  • Refusal creates back-pressure — errors flow back to receivers and senders, so retrying senders usually deliver the data later without loss.
  • Place it first in every pipeline — right after the receivers, so refused data costs nothing and memory-holding processors are protected.
  • Leave headroom below the container limit — a common starting point is about eighty percent for the hard limit, then tune with real measurements.
  • It works with other safeguards — combine it with a runtime memory target, bounded batches and queues, and horizontal scaling.
  • Monitor and act on refusals — occasional refusals are healthy, but constant refusals mean you need more capacity or a fix elsewhere in the pipeline.