OTel Arrow and Columnar Encoding in OpenTelemetry

OTel Arrow and Columnar Encoding in OpenTelemetry

A deep, plain-English guide to how OpenTelemetry Protocol with Apache Arrow rearranges telemetry from rows into columns, why that shrinks network traffic so dramatically for busy pipelines, how it works in the Collector, and when it is, and is not, worth using.

Imagine you run a school and must send the exam results of ten thousand students to the head office. The simple way is to send one sheet per student: name, class, subject, score, name, class, subject, score, and so on, over and over. The head office receives a mountain of paper, and most of it repeats itself: the same class names, the same subject names, the same dates. Now imagine a smarter way. You send one list of class names, one list of subject names, and then a compact table that just says “student 17, class number 3, subject number 5, score 82”. Almost nothing repeats, and the package is a fraction of the size. That change, from repeating everything row by row to organising information column by column, is the heart of OTel Arrow.

This guide explains that idea in the world of OpenTelemetry. We begin with why moving telemetry is expensive, build up the vocabulary of rows, columns, and Apache Arrow, then look closely at how the OpenTelemetry Protocol with Apache Arrow encodes and streams data, how it appears in the Collector, how to size and deploy it, and what it costs. No prior knowledge is assumed.

1The Problem: Moving Telemetry Is Expensive

Before we meet any new protocol, we need to feel the cost that it tries to reduce.

Telemetry is a lot of data

Telemetry is the information that software produces about itself: traces that follow requests, metrics that count and measure, and logs that record events. A modern system with hundreds of services can produce millions of these records every minute. Each record carries many details: names, labels, timestamps, identifiers, and values. When you add them all up, the volume is enormous.

All of that data must travel. It leaves applications, passes through collectors and gateways, crosses networks, and reaches a backend where it is stored and queried. Every step of that journey costs something.

Simple Analogy

Think of shipping goods between two cities. The cost depends not only on what you ship but on how you pack it. A truck full of loosely packed boxes, each with its own wrapping and its own label, costs far more than the same goods packed tightly on pallets. Telemetry is the same: how you pack it decides what it costs to move.

Where the cost shows up

Cost 1

Network egress charges

Cloud providers often charge for data that leaves a region or a cloud. Telemetry sent across regions or to an external vendor can become a surprisingly large line on the bill.

Cost 2

Bandwidth limits

Remote sites, edge locations, and shared links have limited capacity. Telemetry competes with business traffic for the same pipe.

Cost 3

Processing time

Every byte must be encoded, sent, received, decoded, and often copied. The processor time spent on these steps adds up across a large fleet.

Cost 4

Vendor ingestion limits

Some backends limit or charge for the volume received. Shrinking the bytes on the wire can ease limits and lower charges.

i
Remember

Reducing telemetry has two very different strategies. You can send less data, by sampling and filtering, or you can send the same data in a smaller package. OTel Arrow belongs to the second family: same information, fewer bytes.

Why simply compressing is not the whole answer

The standard way to shrink data on the network is compression, using general-purpose tools that look for repeated patterns in a stream of bytes. Compression helps a great deal and is already widely used. But a general-purpose compressor sees only a stream of bytes. It does not know that one stretch of bytes is a service name and another is a timestamp. If the data is arranged in a way that scatters similar values far apart, even a good compressor misses many chances to shrink it. Arranging the data so that similar values sit side by side gives the compressor a much better starting point, and that is the opportunity columnar encoding creates.

2Foundations You Need First

A short, friendly refresher on the pieces of OpenTelemetry that OTel Arrow builds on.

OpenTelemetry in one paragraph

OpenTelemetry, often shortened to OTel, is an open standard and a set of tools for producing and moving telemetry. Applications use SDKs to create traces, metrics, and logs. A separate program called the Collector receives that telemetry, processes it, and forwards it to backends. The standard format used between these pieces is called the OpenTelemetry Protocol, or OTLP.

The building blocks

Piece 1

OTLP

The native language of OpenTelemetry, a description of how traces, metrics, and logs are laid out when they are sent.

Piece 2

Protocol Buffers

A compact way to turn structured records into bytes. OTLP messages are described and encoded with it.

Piece 3

gRPC

A common way for programs to call each other over a network. OTLP is carried by gRPC or by plain web requests.

Piece 4

Collector

The program that receives, processes, and exports telemetry using receivers, processors, and exporters.

Piece 5

Batch

A group of many records sent together in a single message, which is more efficient than sending them one at a time.

Piece 6

Compression

A general technique that shrinks bytes on the wire, commonly applied on top of OTLP.

How OTLP lays out data: a nested tree

OTLP organises telemetry as a tree. At the top is a resource, which describes where the data came from, such as a particular service running on a particular machine. Under each resource are one or more scopes, which describe the library that produced the data. Under each scope are the actual records: spans for traces, data points for metrics, and log records for logs. Each record carries its own list of attributes, which are named labels such as “http method” or “customer region”.

flowchart TD
  R["Resource: service and host details"] --> S1["Scope: instrumentation library A"]
  R --> S2["Scope: instrumentation library B"]
  S1 --> A1["Span 1 with its own attributes"]
  S1 --> A2["Span 2 with its own attributes"]
  S2 --> A3["Span 3 with its own attributes"]
        
FIG 1 — OTLP arranges telemetry as a nested tree of resources, scopes, and records

This tree is natural and easy to understand, and it already saves some repetition, because details about the resource and the scope are written once instead of on every record. But inside each record, the attribute names and many values still repeat again and again.

!
Common Misconception

Many people think OTel Arrow replaces OpenTelemetry’s data model. It does not. The meaning of the data, spans, metrics, logs, resources, and attributes, stays exactly the same. Only the way the data is arranged for transport changes.

3Rows Versus Columns: The Big Idea

The whole story of OTel Arrow rests on one simple choice: how to arrange a table of information.

Row-oriented layout

Picture a spreadsheet of spans. Each row is one span, and the columns are fields such as service name, operation name, start time, duration, and status. A row-oriented layout writes the data row by row: all the fields of span one, then all the fields of span two, then span three, and so on. This is how most people naturally think about records, and it is how OTLP encodes data inside each batch.

Column-oriented layout

A column-oriented layout writes the same table column by column: first every service name from every span, then every operation name, then every start time, then every duration. Nothing about the information changes. You can rebuild any row by reading the same position in each column. But the bytes sit in a very different order.

flowchart LR
  subgraph ROW["Row layout"]
    R1["span 1: checkout, pay, 10:00, 120ms"]
    R2["span 2: checkout, pay, 10:01, 95ms"]
    R3["span 3: checkout, cart, 10:01, 40ms"]
  end
  subgraph COL["Column layout"]
    C1["service: checkout, checkout, checkout"]
    C2["operation: pay, pay, cart"]
    C3["start: 10:00, 10:01, 10:01"]
    C4["duration: 120, 95, 40"]
  end
        
FIG 2 — The same three spans, arranged by row and by column

Why columns compress so well

Look at the column layout above. The service column contains “checkout” three times in a row. The operation column contains “pay” twice. The start times are close together. Values in the same column tend to be similar to each other, because they all describe the same kind of thing. When similar values sit side by side, simple tricks can shrink them enormously.

Trick 1

Dictionary encoding

Store each distinct value once in a list, and replace every occurrence with a small number pointing into the list.

Trick 2

Run-length encoding

When the same value repeats many times in a row, store the value once and say how many times it repeats.

Trick 3

Delta encoding

For numbers that grow steadily, such as timestamps, store the first number and then only the small differences between neighbours.

Trick 4

Better byte compression

After these tricks, the general compressor still runs, and it finds even more patterns because similar bytes are now adjacent.

Simple Analogy

Imagine packing a suitcase. If you throw in one item after another as you pick them up, socks end up scattered among shirts and shoes, and the suitcase is lumpy and wasteful. If you pack by category, all socks together, all shirts folded in a stack, all shoes in a row, everything fits tightly. Columnar layout is packing by category.

“Same information, different arrangement, far fewer bytes.”

Columns also help computers read faster

Columns are friendly to computer hardware as well. Processors work best when they handle long runs of the same kind of value, because they can process several values in one step. Many analytical databases store data by column for exactly this reason. OTel Arrow borrows that long-proven idea and applies it to telemetry in motion.

i
Design Tip

Columnar layout pays off most when batches are large and the data is repetitive. A tiny batch with all-different values has little repetition to exploit. That is why this approach shines on busy links and large batches rather than on single small messages.

4Apache Arrow in Plain Words

The “Arrow” in OTel Arrow is a well-known open standard for columnar data. Knowing what it is makes the rest easy.

What Apache Arrow is

Apache Arrow is an open standard for representing tables of data in columnar form. It defines exactly how each column is laid out in memory, how missing values are marked, how text and nested values are stored, and how groups of columns are packaged together. It is used widely in data analysis tools, databases, and data engineering pipelines, and it has libraries in many programming languages.

Key ideas in Arrow

Idea 1

Columnar memory

Each column’s values sit together in one block, making scans and compression efficient.

Idea 2

Record batch

A group of equal-length columns that together represent a chunk of a table, the basic unit that is sent and processed.

Idea 3

Schema

A description of the columns in a record batch: their names, their types, and whether they may be missing.

Idea 4

Dictionary arrays

A column type that stores distinct values once and refers to them by number, built into the standard.

Idea 5

Streaming format

A way to send a schema once, followed by a sequence of record batches, which suits long-lived connections.

Idea 6

Language neutrality

Because the layout is standardised, a program written in one language can read data produced by another without translation.

Simple Analogy

Arrow is like the standard shipping container of data. Before containers, every port handled cargo differently. After containers, any ship, crane, and truck could move the same box. Arrow gives data tools a shared box format, so they can pass tables to each other without unpacking and repacking.

Why Arrow suits streaming telemetry

Three Arrow features line up well with telemetry. The streaming format lets a sender transmit the description of the columns once and then keep sending batches that follow it. Dictionary arrays let repeated names and values be sent once and reused. And the whole design favours long runs of similar values, which is exactly what telemetry from a busy service looks like.

!
Do Not Confuse the Names

Apache Arrow is a general data standard that existed long before this project. OTel Arrow is the OpenTelemetry project’s way of using Arrow for telemetry transport. They are related but not the same thing.

5What OTel Arrow Really Is

Now we can state the idea precisely and place it in the OpenTelemetry world.

A working definition

OTel Arrow is the name of an OpenTelemetry project that defines and implements a way of sending the same traces, metrics, and logs as OTLP, but encoded with Apache Arrow in columnar form and sent over long-lived streaming connections. The protocol is often called OTAP, the OpenTelemetry Protocol with Apache Arrow. It is designed as a companion to OTLP, not a replacement for it.

What stays the same and what changes

AspectOTLPOTel Arrow
Meaning of the dataResources, scopes, spans, metrics, logs, attributesThe same
Layout on the wireNested tree, row by rowRelated tables, column by column
Connection styleSeparate request for each batchLong-lived stream of batches
Repeated names and valuesRepeated in each recordStored once in dictionaries and referred to by number
Typical network sizeLargerSmaller for large, repetitive batches
Processor effort to encodeLowerHigher
Support in backendsVery broadNarrow, usually converted back to OTLP

A bridge, not a rewrite

The most important design choice is that OTel Arrow is meant to live alongside OTLP. Applications keep using the normal SDKs and OTLP. The savings are collected at the hops between Collectors, especially long or expensive ones. A sender converts OTLP data into Arrow form, ships it compactly, and a receiver at the other end converts it back to OTLP. Every other part of your system sees ordinary OTLP and never needs to know that Arrow was used in the middle.

flowchart LR
  APP["Applications with standard SDKs"] -->|"OTLP"| E["Edge Collector"]
  E -->|"OTel Arrow, compact"| G["Gateway Collector"]
  G -->|"OTLP"| BE["Backend"]
        
FIG 3 — OTel Arrow compresses the expensive middle hop, while the ends keep using plain OTLP
Simple Analogy

Think of an international flight between two cities. Before and after the flight, you travel by ordinary roads. The aircraft is the fast, efficient section for the long, expensive distance. OTel Arrow is the aircraft for the long hop of your telemetry journey. The roads at each end stay as they were.

Where the project came from

The work began as a collaboration between engineers at observability companies who were looking for ways to cut the cost of moving very large volumes of telemetry. They published the design and the first implementations openly, and the work was contributed to the OpenTelemetry community, where it is developed in its own repository alongside the main project. The first implementation focuses on Collector components written in Go. Later work explores a more native Arrow-based processing engine, so the project continues to evolve.

!
Check the Current Status

The components, their stability levels, and even some design details of OTel Arrow have been changing as the project matures. Treat the descriptions in this guide as a map of the ideas, and confirm exact settings and stability with the project’s current documentation before you depend on them.

6How OTel Arrow Arranges Telemetry

The tree of OTLP becomes a small family of related tables. Understanding this step explains most of the savings.

From a tree to related tables

OTLP stores telemetry as a nested tree. Columnar formats like Arrow work with flat tables, so OTel Arrow first reorganises the tree into several tables that point to each other. This is the same idea that relational databases use: instead of copying details into every row, you keep each kind of detail in its own table and connect them with short identifiers.

For traces, the main table holds one row per span, with columns such as trace identifier, span identifier, name, start time, duration, and status. Separate tables hold the pieces that vary in size: the attributes of the resource, the attributes of the scope, the attributes of each span, the events that happened inside spans, the links between spans, and the attributes of those events and links. Each of these side tables refers back to its parent row with a small number.

flowchart TD
  SP["Spans table: one row per span"]
  RA["Resource attributes table"]
  SA["Scope attributes table"]
  PA["Span attributes table"]
  EV["Span events table"]
  EA["Event attributes table"]
  LK["Span links table"]
  LA["Link attributes table"]
  SP --- RA
  SP --- SA
  SP --- PA
  SP --- EV
  EV --- EA
  SP --- LK
  LK --- LA
        
FIG 4 — A trace batch becomes a main table plus side tables joined by small identifiers

Why side tables help

Take the attributes of a span, such as the HTTP method, the route, and the status code. In OTLP, each span carries its own list of named attributes, so the name “http.method” is written again for every span. In the columnar form, all attributes go into one attributes table with three kinds of columns: the owner (which span), the key (the attribute name), and the value. The key column then contains the same few names repeated, which dictionary encoding turns into tiny numbers. The value column can be stored by type, with separate columns for text, whole numbers, decimals, and true or false values, so that each column holds values of one kind.

Table

Main signal table

One row per span, data point, or log record, holding the fields that every record has.

Table

Attribute tables

Rows of owner, key, and typed value. They replace the repeated named labels inside each record.

Table

Child record tables

Events, links, exemplars, and similar sub-records, each in its own table pointing back to its parent.

Table

Resource and scope tables

Descriptions of where data came from, stored once and referenced by number rather than copied.

Sorting to create runs

The sender can also reorder rows within a batch before encoding, because telemetry records within a batch do not depend on their order. Sorting by fields such as resource, scope, or name puts identical values next to each other, lengthening runs of repeats. Longer runs mean better compression. This is a classic trick from the world of analytical databases, applied here to telemetry in transit.

Simple Analogy

Imagine a library moving ten thousand books. If every book is shipped with a full description card stapled inside, the same publisher address is repeated ten thousand times. If instead you ship a separate card index of publishers and write only a small publisher number on each book, the shipment is much lighter. Sorting books by publisher makes the shipping manifest shorter still.

The same idea for metrics and logs

Metrics follow the same pattern with their own tables. There is a table of metric descriptions, and tables for the different kinds of data points, such as plain numbers, histograms, and summaries, each with its own attribute table and, where relevant, a table of exemplars, which are sample traces linked to a metric value. Logs use a main table of log records and an attribute table. The principle is identical: keep each kind of detail in a tidy column, and refer to shared pieces by number.

!
Schema Details Evolve

The exact names of tables and columns, and the fine points of the encoding, are defined in the project’s specification and may change between versions. The structure described here is the stable idea. For exact details, consult the current specification.

7The Streaming Protocol

OTel Arrow does not just change the layout. It also changes how batches travel, using long-lived streams that remember what has already been sent.

From many requests to one stream

With classic OTLP over gRPC, each batch is a separate request and response. Every request is independent, so nothing is remembered between them. OTel Arrow instead opens a bidirectional stream: a single long-lived connection over which the sender keeps pushing batches, and the receiver keeps sending back acknowledgements. Because the stream stays open, both sides can keep shared state.

Schemas and dictionaries are sent once

The first message on a stream carries the description of the columns, the schema, and the initial contents of the dictionaries, the lists of distinct values such as service names and attribute keys. Later messages carry only what is new: the actual rows, plus any dictionary entries that were not seen before. A value that has already been sent is referred to by its number. This is the delta idea, and it is where much of the long-run saving comes from.

sequenceDiagram
  participant S as Sender
  participant R as Receiver
  S->>R: Open stream
  S->>R: Batch 1 with schema and full dictionaries
  R-->>S: Acknowledge batch 1
  S->>R: Batch 2 with rows and only new dictionary entries
  R-->>S: Acknowledge batch 2
  S->>R: Batch 3 with rows and few new entries
  R-->>S: Acknowledge batch 3
  Note over S,R: Each later batch is smaller because shared values are already known
        
FIG 5 — A stream sends the dictionary once and then only changes

Acknowledgements keep delivery honest

For every batch the sender transmits, the receiver replies with a status that says whether the batch was accepted, whether it failed temporarily so that it can be retried, or whether it failed permanently. This gives the sender the same kind of reliability signal it gets from separate request and response calls in classic OTLP, while still using one long connection. The sender also learns when the receiver is overloaded and can slow down.

State has a price

Because both ends remember dictionaries and schemas, each open stream occupies memory on the receiver. If the stream breaks, that remembered state is lost, and the sender must open a new stream and start again with a full schema and dictionaries. Well-designed senders also close streams on purpose after a chosen lifetime and open fresh ones, which keeps the remembered state from growing without limit and helps spread load across receivers.

1

Convert

The sender takes a batch of OTLP data and rearranges it into columns and tables.

2

Encode with dictionaries

Repeated names and values are replaced with numbers, and only new dictionary entries are included.

3

Send on the stream

The encoded batch is transmitted on an open stream, usually with general compression applied on top.

4

Decode and rebuild

The receiver applies the dictionaries, reads the tables, and rebuilds ordinary OTLP data.

5

Acknowledge

The receiver reports success or failure for the batch so the sender can retry or move on.

Graceful fallback to OTLP

A sender that tries to use OTel Arrow with a receiver that does not understand it must not simply fail. The design allows a sender to detect that Arrow is not supported and fall back to standard OTLP, so that data keeps flowing, only at the normal size. This makes it safe to roll out gradually, and it protects you from outages caused by mismatched versions.

i
Rollout Tip

Because of the fallback, you can upgrade senders and receivers in any order. During the transition some traffic will flow as plain OTLP. Watch the metrics that report fallbacks so you know when the transition is complete.

8Why It Compresses So Well: A Worked Example

Numbers make the idea concrete. The figures below are illustrative, chosen to show the mechanism rather than to promise a particular result.

The batch

Suppose a batch holds 1,000 spans from one service. The spans share the same resource and scope. There are only 5 different service operations in the batch. Each span has 8 attributes, and the names of those attributes, such as the method, the route, the region, and the status code, are the same set of 8 names for every span. The start times are all within a one-second window, and the durations are small whole numbers.

Row by row

In a row-oriented layout, the operation name is written 1,000 times, once per span. The 8 attribute names are written 8,000 times in total. Every start time is written as a full-size number. Even with a good general compressor, which will notice many repeats, the compressor must discover these patterns while scanning a mix of different kinds of bytes.

Column by column

ColumnWhat it holdsTechniqueEffect
Operation name1,000 values from only 5 distinct namesDictionary plus sortingFive names stored once, then 1,000 tiny numbers in long runs
Attribute key8,000 values from only 8 distinct namesDictionaryEight names stored once, then 8,000 tiny numbers
Start time1,000 close-together numbersDelta encodingOne full number, then 999 small differences
Duration1,000 small whole numbersCompact integer storageFew bytes per value
Status code1,000 values, mostly identicalRun-length encodingA handful of runs instead of 1,000 entries
Resource and scopeIdentical for all spansStored once and referencedWritten a single time
1,000
Spans in the example batch
5 and 8
Distinct operations and attribute keys
Few bytes
Cost of each repeated name after encoding

The effect grows with scale and repetition

Savings rise with the size of the batch, because the one-off cost of the dictionary is spread over more rows. They also rise with repetition: the more the same names and values appear, the more the dictionaries pay off. And they continue to improve over the life of a stream, because later batches can reuse dictionary entries that were sent earlier.

Simple Analogy

A phone book that prints every person’s full city name on each line is long. A phone book that prints “city 3” next to each name and lists the cities once at the front is far shorter. The more people live in the same few cities, the bigger the saving.

When the saving is small

Conditions that favour large savings

  • Large batches with thousands of records
  • Many repeated names, labels, and values
  • Long-lived streams that reuse dictionaries
  • Data from a few services with consistent attributes
  • Steady timestamps and small numeric values

Conditions that reduce the saving

  • Very small batches with little to share
  • Attributes full of unique values, such as identifiers
  • Large free-text fields, such as long log messages
  • Short-lived streams that keep restarting
  • Data that was already heavily reduced by sampling
!
Measure, Do Not Assume

Published benchmarks show that the size reduction can be large for suitable data, but results depend strongly on your own telemetry. Test with a sample of your real traffic before you plan around any number you read, including those in this guide.

9OTel Arrow in the Collector

In practice, you meet OTel Arrow as a pair of Collector components: one that sends and one that receives.

The two components

Exporter

OTel Arrow exporter

Takes data inside the Collector, converts it to Arrow form, and sends it on streams to a receiver that understands the protocol. It can fall back to plain OTLP when needed.

Receiver

OTel Arrow receiver

Accepts Arrow streams, rebuilds ordinary telemetry, and hands it to the pipeline. It can also accept plain OTLP on the same endpoint.

Both components handle traces, metrics, and logs. They are distributed in the community contributions collection, so they are present in the contrib distribution and can be added to a custom build. Their stability level has been evolving, so check the component documentation for your version.

Where they sit in a pipeline

flowchart LR
  subgraph EDGE["Edge Collector"]
    R1["OTLP receiver"] --> P1["Processors and batching"] --> X1["OTel Arrow exporter"]
  end
  subgraph CENTRAL["Gateway Collector"]
    R2["OTel Arrow receiver"] --> P2["Processors"] --> X2["OTLP exporter"]
  end
  X1 -->|"Arrow streams"| R2
  X2 --> BE["Backend"]
        
FIG 6 — An edge Collector sends Arrow streams that a gateway Collector converts back to OTLP

The settings that matter, in plain words

Setting 1

Number of streams

How many parallel streams the exporter keeps open. More streams spread load and increase throughput, at the cost of more memory on both sides.

Setting 2

Stream lifetime

How long a stream may live before it is closed and replaced. Shorter lifetimes help rebalance across receivers and limit remembered state.

Setting 3

Fallback behaviour

Whether the exporter may fall back to plain OTLP if the receiver does not support Arrow. Allowing it is safer during rollout.

Setting 4

Stream prioritisation

How the exporter chooses which stream receives the next batch, for example the one with least work waiting.

Setting 5

Receiver memory limits

How much memory the receiver may use for stream state and incoming data, so that busy or hostile senders cannot exhaust it.

Setting 6

Admission control

Limits on how much data may be accepted or wait to be accepted at one time, protecting the receiver under load.

Working with the rest of the Collector

The batch processor, placed before the Arrow exporter, decides how large the batches are. Bigger batches give the encoder more repetition to exploit, so tuning batch size is one of the most effective ways to improve the saving. The memory limiter protects the Collector from running out of memory, and works alongside the Arrow receiver’s own limits. If you use a persistent queue on the exporter, the queued items are stored in the Collector’s ordinary form and converted to Arrow as they are sent.

i
Practical Tip

Start with defaults and measure. Change one setting at a time, such as batch size or number of streams, and compare network bytes, processor use, and delay before and after each change.

!
Both Ends Must Be Prepared

The savings only happen when the sender uses the Arrow exporter and the receiver runs the Arrow receiver. If only one end is upgraded, traffic quietly falls back to plain OTLP, and your bill stays the same. Verify with metrics that Arrow streams are really in use.

10Architecture Patterns

The savings appear where data crosses long or expensive links. Choosing the right place for the Arrow hop matters more than anything else.

Pattern A: Edge to gateway over a limited link

Collectors at remote sites, branch offices, or factories send to a central gateway across a slow or costly connection. An Arrow hop on that link reduces the bytes crossing it, leaving more capacity for other traffic and making the telemetry arrive sooner during busy periods.

Pattern B: Across regions or clouds

Cloud providers often charge for data that moves between regions or leaves the cloud. A Collector in each region can compress telemetry with Arrow before sending it to a central region, cutting the charge for the cross-region hop.

flowchart LR
  subgraph R1["Region 1"]
    A1["Services"] --> C1["Regional Collector"]
  end
  subgraph R2["Region 2"]
    A2["Services"] --> C2["Regional Collector"]
  end
  C1 -->|"OTel Arrow across regions"| CEN["Central gateway"]
  C2 -->|"OTel Arrow across regions"| CEN
  CEN -->|"OTLP"| BE["Backend"]
        
FIG 7 — Regional Collectors compress telemetry for the expensive cross-region hop

Pattern C: The last mile to a backend

If your backend or vendor offers an endpoint that speaks OTel Arrow natively, the final hop from your gateway can also use it, saving egress to the outside world. This depends on the backend’s support, which is still uncommon, so check with your vendor before planning around it.

Pattern D: Tiered fan-in

Large estates often have several layers of Collectors, each aggregating many senders. Where the layers are far apart or numerous, Arrow can be used on each long hop, while the short hops near applications remain plain OTLP.

Where not to use it

The hop between an application’s SDK and a Collector on the same machine is short and cheap, and the batches are usually small. Arrow adds encoding effort without saving anything meaningful there. Keep that hop on ordinary OTLP.

HopTypical batch sizeNetwork costBenefit of Arrow
SDK to local agentSmallNegligible, same machineLittle, not recommended
Agent to gateway in the same data centreMediumLowModest, depends on volume
Edge site to central gatewayLargeHigh, limited bandwidthLarge
Region to region or cloud to cloudLargeHigh, often chargedLarge
Gateway to vendor over the internetLargeHigh, often chargedLarge if vendor supports it
flowchart TD
  Q1{"Is the hop long, costly, or bandwidth limited?"} -->|"No"| N["Keep plain OTLP"]
  Q1 -->|"Yes"| Q2{"Are batches large and repetitive?"}
  Q2 -->|"No"| N
  Q2 -->|"Yes"| Q3{"Can both ends run Arrow components?"}
  Q3 -->|"No"| N
  Q3 -->|"Yes"| Y["Use OTel Arrow on that hop"]
        
FIG 8 — A simple test for where to use OTel Arrow
i
Start Where It Hurts

Look at your network bill and your link usage first. Apply Arrow to the one hop that costs the most. A single well-chosen hop often delivers most of the benefit with little change elsewhere.

11Sizing, Performance, and the CPU Trade-off

OTel Arrow trades processor effort for network savings. A little arithmetic tells you whether the trade is good for you.

The trade in one sentence

Converting data to columns, building dictionaries, and encoding them takes more processor time than simply writing out OTLP, and the receiver must do matching work to rebuild the data. In exchange, fewer bytes cross the network. Whether that is a good deal depends on how expensive your bytes are compared with your processor time.

Simple Analogy

Vacuum-packing food takes time and a machine, but it lets you fit more into a small freezer and ship it more cheaply. If shipping is expensive and the freezer is tiny, vacuum-packing is a bargain. If you are carrying food next door, it is a waste of effort.

A worked example of the bandwidth saving

Suppose a regional Collector sends 40 megabytes per second of OTLP traffic, after general compression, across a link where data is charged by volume. Over a day, that is about 3.4 terabytes. Imagine that, for this particular data, OTel Arrow reduces the compressed size by about a third. The same telemetry would then cross the link at roughly 27 megabytes per second, or about 2.3 terabytes per day, saving more than one terabyte every day.

Multiply by thirty days and by several regions, and the saving becomes a significant line on the monthly network bill. Now compare it with the cost of the extra processor time: perhaps a few additional processor cores across the senders and receivers. If a terabyte of cross-region traffic costs more than those cores, the trade is favourable. If your link is free and fast, the trade may not be worth the added complexity.

~3.4 TB
Daily volume at 40 MB per second (illustrative)
~1/3
Assumed reduction for this example
>1 TB
Saved every day on the link
!
Illustrative Numbers

The reduction used here is an assumption to show the arithmetic. Your real figure may be higher or lower. Measure it on a sample of your own traffic before you build a business case.

The knobs that affect the result

KnobEffect on network sizeEffect on processor and memory
Larger batchesSmaller per record, more repetition to exploitMore memory while building a batch, slightly more delay
More streamsLittle direct effect, each stream keeps its own dictionariesMore memory for stream state on both ends
Longer stream lifetimeBetter, dictionaries stay useful for longerMemory for state grows, uneven load across receivers
Extra general compressionSmaller stillMore processor time
High-cardinality attributesLarger, dictionaries growMore memory for dictionaries

Memory for stream state

Each open stream keeps dictionaries and schemas in memory on both the sender and the receiver. With a few streams per sender and thousands of senders, the receiver’s memory can become a real consideration. The receiver’s memory limit setting guards against exhaustion, but you should still estimate the total in advance: number of streams multiplied by the typical state per stream, plus the memory needed for batches in flight.

Latency

Encoding adds a small delay to each batch, and larger batches add the time needed to fill them. For telemetry this delay is usually unimportant, since people look at dashboards and traces after the fact, but if you rely on near-instant alerts from the data, measure the end-to-end delay before and after the change.

i
Measure Four Things

Before and after enabling Arrow on a hop, record network bytes per second, processor use on sender and receiver, memory use on the receiver, and end-to-end delay. Together they tell you the honest cost and benefit.

12Load Balancing, Stream Lifetime, and Reliability

Long-lived streams are the source of most of the savings, and also of most of the operational surprises.

The long connection problem

Traditional load balancers spread work by sending each new request to a different server. With plain OTLP over gRPC, each batch can be a separate request, so the work is spread evenly. With OTel Arrow, a stream is a single long connection. Once it is attached to a receiver, every batch on it goes to that same receiver for as long as the stream lives. If a few streams carry most of the traffic, one receiver can end up with a heavy load while others sit idle.

flowchart LR
  subgraph BAD["Without rotation"]
    S1["Sender A"] -->|"stream stays forever"| RA["Receiver 1: overloaded"]
    S2["Sender B"] -->|"stream stays forever"| RA
    S3["Sender C"] -->|"stream stays forever"| RB["Receiver 2: nearly idle"]
  end
        
FIG 9 — Long streams can pile up on one receiver while others stay idle

Stream lifetime to the rescue

The cure is for senders to close each stream after a chosen lifetime and open a new one. Each new stream is a fresh chance for the load balancer to choose a receiver, so over time the load spreads out. The lifetime is a balancing act: too long and load stays uneven, too short and the senders keep paying the cost of resending schemas and dictionaries, which weakens the compression.

Short lifetime

Seconds to a minute

Excellent balance across receivers, but frequent restarts reduce the benefit of dictionaries.

Medium lifetime

Several minutes

A common compromise between balance and compression, worth testing as a starting point.

Long lifetime

Hours

Best compression, but weak balance and slower recovery after receiver changes.

Use a load balancer that understands gRPC

A basic connection-level balancer sees only a single long connection per sender and cannot spread the batches inside it. A balancer that understands gRPC can sometimes balance at the level of streams or requests. Whichever you use, test the distribution of load across receivers under realistic traffic, and watch for a slow drift toward imbalance after rolling updates.

Reliability when a stream breaks

1

The stream drops

A network blip, a receiver restart, or a load balancer decision closes the stream. The remembered dictionaries on both sides are gone.

2

Unacknowledged batches are retried

Batches that were sent but not acknowledged are not assumed to be delivered. The sender retries them according to its retry rules.

3

A fresh stream starts

The sender opens a new stream and sends the full schema and dictionaries again, so the first batches are larger than later ones.

4

Steady state returns

Dictionaries rebuild, batches shrink again, and the saving returns to its normal level.

Backpressure and queues

The acknowledgement messages carry the receiver’s view of its own load. When the receiver is busy, it can respond with a temporary failure, and the sender slows down and retries. A sending queue in the exporter absorbs short bursts. For longer outages, a persistent queue on the sender holds data on disk until the receiver returns. The behaviour is similar to what you would plan for plain OTLP, with the extra detail that a restarted stream briefly costs more bytes.

!
Rolling Updates

When you restart receivers one by one, every stream attached to them is dropped and reopened. A fast, careless rollout can cause a wave of reconnections and a brief rise in network bytes. Roll updates gradually and watch the stream restart metrics.

What about tail sampling?

If your gateway applies tail sampling, spans of one trace must reach the same Collector instance. Arrow streams do not change that rule. Arrange trace-aware routing in the tier that needs it, and remember that long-lived streams can concentrate load on one instance, so keep an eye on balance at that tier in particular.

13Advantages, Disadvantages, and Trade-offs

OTel Arrow is powerful in the right place and wasteful in the wrong one. A balanced view tells you which is which.

Advantages

  • Much smaller network traffic for large, repetitive batches
  • Lower egress charges on cross-region and cross-cloud hops
  • More headroom on limited links at edge sites
  • Same data model, so nothing changes for users of the data
  • Safe rollout, because it falls back to plain OTLP
  • Built on an open standard with wide tool support

Disadvantages / Trade-offs

  • More processor time to encode and decode
  • Memory used for stream state on both ends
  • Long streams make load balancing harder
  • Few backends accept it natively, so conversion is needed
  • Components and details are still evolving
  • More moving parts to monitor and understand

OTLP with compression versus OTel Arrow

AspectOTLP with general compressionOTel Arrow
Network sizeGoodOften better for large repetitive batches
Processor costLowHigher
Setup effortMinimalModerate, both ends need components
Backend supportUniversalLimited, usually converted at a Collector
Connection styleIndependent requestsLong-lived streams with state
MaturityVery matureNewer and evolving

Other ways to reduce telemetry cost

OTel Arrow is one tool among several, and often the best results come from combining them. The table shows how they differ in what they change.

TechniqueWhat it changesInformation lost?
SamplingKeeps only some tracesYes, by design
Filtering and attribute trimmingRemoves unwanted data and labelsYes, what you choose to drop
Larger batches and compressionPacks the same data more tightlyNo
OTel ArrowRearranges data into columns for better packingNo
Aggregating metrics earlierReduces the number of data pointsSome detail
“Sample to send less. Arrow to send the same, smaller.”

When it is not worth it

If your telemetry volume is small, your network is fast and free, or your biggest costs are in storage and querying rather than transport, the extra complexity of OTel Arrow may not pay off. Likewise, if your data is mostly free-form text or unique identifiers, there is little repetition to exploit. In such cases, plain OTLP with compression and thoughtful sampling is simpler and good enough.

Simple Analogy

A cargo plane is wonderful for moving heavy loads across the ocean, but nobody hires one to carry a letter across town. Match the tool to the distance and the load.

14Security, Compliance, and Monitoring

A new encoding is a new thing to secure and a new thing to watch.

Security considerations

Risk 1

Unencrypted links

Arrow streams travel over gRPC, so the usual protections apply. Use encrypted connections, and prefer mutual authentication between Collectors.

Risk 2

Memory exhaustion

A buggy or hostile sender could open many streams or build huge dictionaries to use up the receiver’s memory. Configure memory and admission limits.

Risk 3

Malformed data

Decoders must handle unexpected or corrupted batches safely. Keep components up to date so that fixes for decoding problems reach you.

Risk 4

Sensitive content is unchanged

Arrow reshapes data but does not hide it. Personal or secret values are still present, so redact them before the data is encoded.

Compliance

Because the meaning and content of the telemetry are unchanged, your obligations are the same as with OTLP. If your rules require encryption in transit, enforce it on the Arrow hop. If your rules forbid certain data from crossing a border, remember that compression does not change what is being sent, only how many bytes it takes.

Monitoring OTel Arrow

1

Bytes on the wire

Compare bytes sent per second before and after. This is your primary proof that the saving is real.

2

Streams opened and restarted

Frequent restarts mean lost dictionaries and weaker compression. Look for patterns that match rolling updates or load balancer behaviour.

3

Fallbacks to plain OTLP

A steady count means one end does not support Arrow, or the connection setup is failing. You may be paying full price without knowing it.

4

Processor use

Watch sender and receiver processor use for the encoding and decoding work, and compare with your baseline.

5

Receiver memory and admissions

Track how close the receiver is to its memory limit and how often it refuses or delays incoming data.

6

Failures and retries

Track failed and retried batches, queue size, and dropped data, just as you would for any exporter.

A troubleshooting guide

SymptomLikely causeFirst thing to check
No drop in network traffic after enablingOne end does not use Arrow, traffic fell back to OTLPFallback counts and receiver configuration
Small saving onlySmall batches, unique attribute values, or short streamsBatch size, attribute cardinality, stream lifetime
One receiver much busier than othersLong streams attached to the same instanceStream lifetime and load balancer behaviour
High memory on the receiverMany streams, large dictionariesNumber of streams and receiver memory limits
Processor use rose sharplyExpected cost of encoding, or tiny batchesBatch size and whether the hop is worth it
Spikes of bytes after deploymentsStreams reopened and dictionaries resentRollout pace and restart metrics
i
Alerting Tip

Alert on a rise in fallbacks and on a drop in the compression ratio. Both are early signs that you are no longer getting the benefit you planned for, long before the bill arrives.

15Design Patterns and Anti-patterns

Teams keep rediscovering the same good habits and the same expensive mistakes. Here they are, named.

Patterns worth copying

Arrow only on the expensive hop

Find the link that costs the most, whether in money or in capacity, and apply Arrow there. Keep every other hop on plain OTLP to avoid needless encoding effort.

Measure with real traffic first

Replay a sample of production telemetry through a test pair of Collectors and record the saving, the processor cost, and the memory use before changing production.

Batch generously before the exporter

Use a batch processor sized so that each batch holds enough records for the encoder to find repetition, while keeping delay acceptable.

Keep fallback on during rollout

Allow the exporter to fall back to plain OTLP while you upgrade the fleet, and track fallbacks until they reach zero.

Rotate streams on purpose

Choose a stream lifetime that balances load and compression, and review it after traffic changes or when you add receivers.

Terminate Arrow at a Collector

Convert back to OTLP at the receiving Collector and send ordinary OTLP onward to backends, unless a backend explicitly supports Arrow.

Anti-patterns to avoid

ANTI-PATTERN-01 Avoid
Problem

Arrow is enabled on every hop, including the short link between applications and the Collector on the same machine.

Why It’s Harmful

Batches there are small and the network is free, so there is little to save. The extra encoding and decoding effort uses processor time and adds delay for no benefit.

Correct Approach

Use Arrow only on long, costly, or bandwidth-limited hops with large batches.

ANTI-PATTERN-02 Avoid
Problem

The exporter is upgraded but nobody confirms that the receiving end runs the Arrow receiver.

Why It’s Harmful

Traffic quietly falls back to plain OTLP. The team believes the saving is happening, while the bill and the bandwidth stay exactly the same.

Correct Approach

Track fallbacks and bytes on the wire, and confirm that Arrow streams are active on both ends.

ANTI-PATTERN-03 Avoid
Problem

Streams are set to live only a few seconds, or batches are tiny, in pursuit of perfect load balance.

Why It’s Harmful

Schemas and dictionaries are resent constantly, so most of the compression benefit disappears and the processor cost remains.

Correct Approach

Find a lifetime and batch size that balance load without destroying the savings, and test with real traffic.

ANTI-PATTERN-04 Avoid
Problem

The receiver runs with no memory or admission limits, exposed to many senders.

Why It’s Harmful

Stream state consumes memory. A burst of new streams or a misbehaving sender can exhaust memory and crash the receiver, taking telemetry for everyone with it.

Correct Approach

Set memory and admission limits, pair them with the memory limiter, and test the behaviour under overload.

ANTI-PATTERN-05 Avoid
Problem

A plain connection-level load balancer fronts the receivers, and nobody checks how load is spread.

Why It’s Harmful

Long streams stick to whichever receiver they first reached, leaving some overloaded and others idle, and making rolling updates unpredictable.

Correct Approach

Use stream rotation and a gRPC-aware balancer, and monitor the load on each receiver.

ANTI-PATTERN-06 Avoid
Problem

A business case is built on benchmark numbers from an article or a synthetic dataset, without testing on real telemetry.

Why It’s Harmful

Synthetic data is usually more repetitive than real data. Real savings may be much smaller, and the project may fail to deliver what was promised.

Correct Approach

Replay a sample of your own traffic and calculate the saving from measurements before committing.

16Best Practices and Common Mistakes

The habits that separate a smooth OTel Arrow rollout from a frustrating one, gathered in one place.

Start with the bill, not the technology

The strongest reason to adopt OTel Arrow is a measurable cost: a cross-region transfer charge, a metered egress link, or a constrained edge connection. Write down the number before you begin. Without it, you cannot tell whether the project succeeded, and you cannot defend the extra complexity when someone asks why the change was made.

Simple Analogy

Nobody buys a freight container to ship a parcel. You first look at what the shipping costs, and only then decide whether a bigger, cleverer way of packing is worth the effort. The cost tells you whether to bother.

Best practices at a glance

Practice 1

Target expensive hops

Apply Arrow where bytes cost real money or time: edge to gateway, region to region, and the final leg to a vendor that supports it. Leave cheap local hops on plain OTLP.

Practice 2

Keep the fallback

Let senders drop back to plain OTLP when a receiver cannot speak Arrow. It protects you during upgrades and mixed environments.

Practice 3

Measure on your own data

Replay a sample of real telemetry, compare bytes and processor time with and without Arrow, and decide using your own figures.

Practice 4

Limit memory and admission

Stream state uses memory. Put sensible limits on receivers and pair them with the memory limiter so a burst cannot take down the gateway.

Practice 5

Rotate streams

Close and reopen streams on a schedule so load spreads across receivers and rolling updates behave predictably.

Practice 6

Watch both ends

Dashboard bytes on the wire, processor use, memory, stream churn, retries, and fallback events on senders and receivers together.

Practice 7

Pin and test versions

Move senders and receivers together, test the pair in staging, and read release notes, because this area is still evolving.

Practice 8

Redact before you encode

Remove or hash sensitive attributes in processors ahead of the exporter. Columnar storage reshapes data but does not hide it.

Common mistakes and their cures

MistakeWhat happensBetter approach
Enabling Arrow everywhere on day oneExtra processor cost on hops that never needed savings, and many places to debug at onceStart with the single most expensive hop and widen only with evidence
Tiny batchesLittle repetition to exploit, so savings shrink while overhead remainsAllow larger, well-formed batches within your delay budget
Ignoring receiver memoryStreams accumulate state until the process is under pressureSet limits and watch memory as a first-class signal
Never rotating streamsUneven load and awkward restartsChoose a lifetime that balances compression and spread
Treating Arrow as a security featureSensitive values travel exactly as beforeKeep redaction and encryption in place
Trusting published ratiosBusiness case built on someone else’s dataReplay your own traffic and calculate from measurements
Upgrading only one sideSilent fallback to plain OTLP and no savingsTrack fallback counters and upgrade pairs together

A short vocabulary cheat sheet

People new to the topic often get lost in words. Here is a compact list you can keep beside you while reading documentation or talking to colleagues.

WordPlain meaning
OTLPThe standard way OpenTelemetry components exchange telemetry, one record after another in nested groups
OTAPThe Arrow-based companion protocol, which carries the same telemetry in columns
ColumnarStoring all the values of one field together instead of storing whole records together
Dictionary encodingReplacing a repeated value with a small number that points into a list
Run-length encodingWriting a repeated value once together with a count
Delta encodingStoring the difference from the previous value instead of the value itself
StreamA long-lived two-way connection that remembers what has already been sent
BatchA group of records sent together and acknowledged together
FallbackSwitching to plain OTLP when the other side cannot use Arrow
!
Check the Current Status

The OTel Arrow components and the protocol around them have been changing. Stability levels, available settings, and supported signals can differ between releases. Before planning a rollout, read the current component documentation and release notes for the exact versions you intend to run.

17Real-World Situations

Four typical situations, described in general terms, showing where OTel Arrow helps, where it does not, and what to ask before you adopt it.

i
About These Examples

These are illustrative composites, not reports from named organisations. Figures are rounded and assumed so that the reasoning is easy to follow.

Situation 1

A retail company with stores across many regions

Context: Each region runs a Collector that gathers telemetry from local services and sends it to a central gateway in another region. Cross-region transfer is billed by volume, and the bill has become one of the larger observability costs.

Decision: Enable Arrow on the regional-Collector to central-gateway hop only. Keep service-to-regional-Collector traffic on plain OTLP.

Outcome: The team replays a day of real traffic, finds a meaningful drop in compressed bytes on that hop, and sees a modest rise in processor use on both ends. The saving exceeds the cost of the extra cores, so the change stays. Fallback counters remain near zero after both sides are upgraded.

Situation 2

A manufacturer with factory sites on constrained links

Context: Each factory has a small Collector sending to headquarters over a narrow, sometimes unreliable link. Telemetry arrives late whenever the link is busy.

Decision: Use Arrow on the factory link, together with a persistent queue on the factory Collector, so short outages do not lose data.

Outcome: Less data crosses the link, so the queue drains faster after outages. The team notes that a dropped link resets the stream state, and accepts a brief dip in compression after every reconnection.

Situation 3

A small startup with one cluster and a hosted backend

Context: All services and a single Collector run in one cluster. Traffic leaves the cluster to a vendor over a modest connection, and the monthly bill is small.

Decision: Stay on plain OTLP with general compression.

Outcome: The saving from Arrow would be small in money terms, while the added complexity would be real. The team sets a reminder to reconsider if volume grows tenfold. This is a perfectly good decision, and it shows that not adopting is sometimes the right answer.

Situation 4

A platform team running a shared gateway for many business units

Context: Dozens of teams send telemetry to a shared gateway fleet. Load is uneven, and rolling updates occasionally cause sudden surges.

Decision: Enable Arrow between the large regional gateways and the central tier, with stream rotation, memory limits, and a gRPC-aware load balancer.

Outcome: After tuning stream lifetime, load spreads evenly and rolling updates stop causing spikes. The team publishes a short internal guide so that other business units can enable Arrow safely on their own hops.

Questions to ask before you adopt

1

How much does this hop cost?

If you cannot name the cost in money or delay, you cannot judge the benefit.

2

Is the data repetitive enough?

Telemetry with many repeated names, labels, and resource details compresses far better than telemetry full of unique values.

3

Can both ends speak Arrow?

The saving exists only when the sender and receiver both support it and neither falls back silently.

4

Can we spare the processor time?

Check headroom on the sender and receiver. If processors are already near their limits, the trade may hurt.

5

Who owns the operation?

Name a team responsible for watching the dashboards, tuning stream settings, and handling upgrades.

18A Practical Adoption Roadmap

A calm, step-by-step path from “this sounds interesting” to “this is running quietly in production”.

Simple Analogy

Switching a delivery route to a new kind of truck is done one route at a time. You try it on the busiest route, watch the fuel use and delivery times, keep the old trucks ready, and only then move the other routes across.

1

Measure the baseline

Record bytes per second, processor use, memory, and the monetary cost on the hop you plan to change. This is the line you will compare against.

2

Replay a sample in a test setup

Run a copy of real traffic through a sender and receiver pair with Arrow enabled. Measure the same numbers and calculate the saving and the cost.

3

Prepare the receivers first

Upgrade and configure the receiving side with memory limits, admission control, and a gRPC-aware load balancer, while senders still use plain OTLP.

4

Enable one sender, then a few

Turn Arrow on for a single sender, watch the dashboards, then widen to a small group. Check fallback events, stream churn, and retries at each step.

5

Tune stream settings

Adjust stream count, lifetime, and batch size using what the dashboards show, aiming for even load and steady savings.

6

Document and hand over

Write down the settings, the reasons behind them, the dashboards, and the roll-back steps, and name the owners.

Maturity levels

LevelDescriptionTypical signs
ExploringReading, discussing, and testing in a labNo production traffic, a sample replay planned
PilotingOne expensive hop uses Arrow with fallback onDashboards exist, savings measured
OperatingSeveral hops use Arrow with limits and rotationAlerts on fallback and memory, documented runbook
OptimisingSettings tuned from data, versions upgraded on a scheduleRegular reviews of savings against cost
i
Always Keep a Way Back

Because senders can fall back to plain OTLP, rolling back is usually a configuration change. Practise it once in a test environment so that the first time you need it is not during an incident.

19Frequently Asked Questions

Short, direct answers to the questions people ask most often.

Q1What is OTel Arrow in one sentence?

It is a way of sending OpenTelemetry data in columns, using the Apache Arrow format over long-lived streams, so that repeated values are stored and sent only once and the data compresses much better than plain record-by-record OTLP.

Q2Does it replace OTLP?

No. It is a companion. Applications and SDKs continue to speak OTLP, and Collectors can translate to Arrow for a hop and back to OTLP at the other end.

Q3What does columnar mean?

Instead of storing each record as a bundle of fields, the data is stored one field at a time. All timestamps sit together, all names sit together, and so on. Similar values placed side by side are easy to shrink.

Q4What is Apache Arrow?

An open, language-neutral format for tabular data held in columns. It is designed so that different programs can share the same data cheaply, and OTel Arrow uses it as its container.

Q5Why does it compress better than OTLP with gzip or zstd?

General compression looks for repetition in a stream of bytes. Columnar layout puts similar values next to each other and uses dictionaries and runs that remember repetition across batches, so there is far more repetition for any compressor to exploit.

Q6How much will I save?

It depends on your data. Highly repetitive telemetry with many shared labels can shrink a lot, while data full of unique values shrinks less. Measure with a replay of your own traffic rather than trusting any quoted figure.

Q7What is the catch?

More processor time to convert and encode, more memory to hold stream state, and more operational care around load balancing and upgrades. You pay in effort and compute to save on network bytes.

Q8Should my applications use it directly?

Usually not. The best fit is between Collectors on expensive hops. The link between an application and a local agent is cheap, so the savings would not justify the added work.

Q9Which signals are covered?

The Collector components have covered traces, metrics, and logs. Check the current documentation for the exact support and stability level in the version you use.

Q10Where do the components live?

In the contrib collection of components. If you use a custom distribution, include the Arrow receiver and exporter in your manifest.

Q11What happens if the receiver does not support Arrow?

With fallback enabled, the sender notices and sends plain OTLP instead. Nothing is lost, but you also do not get the saving, so watch for fallback events.

Q12What happens when a stream breaks?

Both sides lose their remembered schema and dictionaries. Batches that were not acknowledged are retried, a new stream is opened, and compression recovers as dictionaries are rebuilt.

Q13Why do streams make load balancing harder?

Because a stream is long-lived, it stays with whichever receiver it first reached. Without rotation or a gRPC-aware balancer, some receivers end up busy while others sit idle.

Q14Does it make my telemetry more secure?

No. It changes the shape of the data, not who can read it. Keep encryption, authentication, and redaction exactly as you would with OTLP.

Q15How do I know it is working?

Compare bytes sent before and after, check that fallback counters are low, and confirm that stream churn and retries are calm. If the bytes do not fall, one side is probably not using Arrow.

Q16Do I need to change my backend?

Not if you convert back to OTLP at the end of the Arrow section. Many teams use Arrow only between their own Collectors and send OTLP onward to the backend.

Q17Is it production ready?

That depends on the component’s stability level in the release you run, and the answer has changed over time. Read the current documentation, test with your own traffic, and start with one hop.

Q18Does it hurt latency?

It can add a small delay while a batch fills and is encoded. Keep batches large enough to compress well but small enough to meet your freshness needs, and measure end-to-end delay.

Q19Can I use it with a persistent queue?

Yes, and it is a good pairing on unreliable links. The queue protects data during outages, and Arrow helps the queue drain faster when the link returns.

Q20How is it different from simply using a better compression algorithm?

A better algorithm still works on the same record-by-record layout. OTel Arrow changes the layout itself, which exposes patterns that no byte-level compressor can see, and keeps dictionaries across batches.

Q21What is the first thing I should try?

Pick your most expensive hop, replay a sample of its traffic through a test pair with Arrow on, and compare bytes and processor use against plain OTLP.

Q22When should I not use it?

When the hop is cheap, volumes are small, processors are already stretched, or nobody can own the operation. In those cases plain OTLP with general compression is simpler and good enough.

20Summary and Key Takeaways

Everything in this guide, gathered into a few ideas you can carry with you.

Telemetry is repetitive. The same service names, metric names, labels, and resource details appear again and again, and plain OTLP writes them out record after record. OTel Arrow takes the same data, arranges it into columns, replaces repeated values with small references, and sends it over long-lived streams that remember what has already been shared. The result is a much smaller flow of bytes on the hops where bytes are expensive, paid for with some extra processor time and memory.

It is a companion to OTLP and not a replacement. You use it where it pays, usually between Collectors across regions or from the edge to a gateway, and you leave the rest of your pipeline alone. With limits, rotation, fallback, and good dashboards, it can run quietly. Without them, it can surprise you. The wise path is to measure first, start small, and grow from evidence.

Arrow reshapes the telemetry so that repetition becomes visible, and then pays for it only once.

Key Takeaways

  • OTel Arrow is a companion to OTLP — the same telemetry, carried in columns using Apache Arrow, with conversion at the edges of the Arrow section.
  • Columns expose repetition — dictionaries, runs, and deltas turn repeated names and labels into tiny references, which is why it compresses so well.
  • Streams remember — schemas and dictionaries are sent once and reused, with acknowledgements providing backpressure, but a broken stream resets that memory.
  • Use it on expensive hops — cross-region links, metered egress, and constrained edges benefit most, while cheap local hops rarely justify it.
  • You trade compute for bytes — expect more processor time and memory, so measure both sides with your own traffic before deciding.
  • Operate it with care — rotate streams, use a gRPC-aware balancer, set memory and admission limits, watch fallback counters, and upgrade senders and receivers together.
  • It is not a security feature — keep encryption, authentication, and redaction in place, and verify the current component status before you commit.