Skip to content

feat(sdk-metrics): add maxExportBatchSize option to PeriodicExportingMetricReader#6655

Open
psx95 wants to merge 17 commits into
open-telemetry:mainfrom
psx95:issue-6641
Open

feat(sdk-metrics): add maxExportBatchSize option to PeriodicExportingMetricReader#6655
psx95 wants to merge 17 commits into
open-telemetry:mainfrom
psx95:issue-6641

Conversation

@psx95
Copy link
Copy Markdown

@psx95 psx95 commented Apr 30, 2026

Which problem is this PR solving?

This PR implements the maxExportBatchSize option for the PeriodicExportingMetricReader in the Metrics SDK, as required by the OpenTelemetry specification. This option allows users to limit the size of batches sent to the exporter, preventing issues with large payloads. It ensures that batches are split correctly without combining data from different Collect() calls, maintains order, and synchronizes calls to Export to prevent concurrency.

Fixes #6641

Short description of the changes

  • Added maxExportBatchSize option to PeriodicExportingMetricReaderOptions.
  • Added validation for maxExportBatchSize in PeriodicExportingMetricReader constructor to ensure it is greater than 0.
  • Created an internal MetricDataSplitter class to handle the logic of splitting ResourceMetrics into smaller batches based on data point count.
  • Updated PeriodicExportingMetricReader to use MetricDataSplitter and handle sequential exporting of split batches.
  • Ensured that timeout is applied to individual batch exports rather than the entire collection.
  • Added comprehensive unit tests for MetricDataSplitter covering GAUGE, SUM, HISTOGRAM, and EXPONENTIAL_HISTOGRAM types with varying batch sizes and multiple scopes.
  • Added tests in PeriodicExportingMetricReader.test.ts for synchronization, timeout behavior, and failure handling.

Type of change

Please delete options that are not relevant.

  • New feature (non-breaking change which adds functionality)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration

  • Ran unit tests for MetricDataSplitter: npx mocha test/export/MetricDataSplitter.test.ts.
  • Ran unit tests for PeriodicExportingMetricReader: npx mocha test/export/PeriodicExportingMetricReader.test.ts.

Checklist:

  • Followed the style guidelines of this project
  • Unit tests have been added
  • Documentation has been updated

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 30, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.85%. Comparing base (abaf418) to head (5158764).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6655      +/-   ##
==========================================
+ Coverage   94.83%   94.85%   +0.02%     
==========================================
  Files         376      377       +1     
  Lines       12711    12781      +70     
  Branches     2888     2904      +16     
==========================================
+ Hits        12054    12124      +70     
  Misses        657      657              
Files with missing lines Coverage Δ
...kages/sdk-metrics/src/export/MetricDataSplitter.ts 100.00% <100.00%> (ø)
...etrics/src/export/PeriodicExportingMetricReader.ts 99.06% <100.00%> (+0.33%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@psx95 psx95 changed the title Issue 6641 feat(sdk-metrics): add maxExportBatchSize option to PeriodicExportingMetricReader Apr 30, 2026
@psx95 psx95 force-pushed the issue-6641 branch 2 times, most recently from 127cbe1 to 566dc6a Compare April 30, 2026 18:21
@psx95 psx95 marked this pull request as ready for review April 30, 2026 18:30
@psx95 psx95 requested a review from a team as a code owner April 30, 2026 18:30
Comment thread packages/sdk-metrics/src/export/MetricDataSplitter.ts Outdated
Comment thread packages/sdk-metrics/src/export/MetricDataSplitter.ts Outdated
Comment thread packages/sdk-metrics/src/export/PeriodicExportingMetricReader.ts Outdated
Comment thread packages/sdk-metrics/src/export/PeriodicExportingMetricReader.ts Outdated
Comment on lines +190 to +192
for (const batch of batches) {
try {
const result = await callWithTimeout(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the spec say if the batches must run serially in order or are they allowed to execute the batches in parallel?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The related part of the spec states:

The reader MUST ensure all metric data points from a single Collect() are provided to Export before metric data points from a subsequent Collect() so that metric points are sent in-order.

So the points need to be sent in-order, would sending batches out-of-order (in case of parallel export) cause the points to be sent out-of-order?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah that's right. It makes sense but it's unfortunate because a single collect call would only ever return one point per timeseries, so you know there is no risk of out-of-order points.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for the OpenTelemetry spec’s maxExportBatchSize option to the Metrics SDK’s PeriodicExportingMetricReader, enabling large Collect() results to be split into smaller export batches and exported sequentially.

Changes:

  • Added maxExportBatchSize to PeriodicExportingMetricReaderOptions with constructor validation and export-path integration.
  • Introduced splitMetricData() utility to split ResourceMetrics into multiple batches based on total data point count.
  • Expanded unit test coverage for batching/splitting behavior, export synchronization, and timeout handling; added a changelog entry.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
packages/sdk-metrics/src/export/PeriodicExportingMetricReader.ts Adds maxExportBatchSize, uses splitMetricData(), and serializes export calls.
packages/sdk-metrics/src/export/MetricDataSplitter.ts New helper to split ResourceMetrics into multiple ResourceMetrics export batches.
packages/sdk-metrics/test/export/PeriodicExportingMetricReader.test.ts Adds reader tests for validation, batching, export synchronization, and timeout logging behavior.
packages/sdk-metrics/test/export/MetricDataSplitter.test.ts New comprehensive unit tests for splitMetricData() across metric types and scopes.
CHANGELOG.md Documents the new feature in the changelog.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/sdk-metrics/src/export/MetricDataSplitter.ts Outdated
Comment thread packages/sdk-metrics/src/export/MetricDataSplitter.ts Outdated
Comment thread packages/sdk-metrics/src/export/PeriodicExportingMetricReader.ts Outdated
Comment thread packages/sdk-metrics/src/export/PeriodicExportingMetricReader.ts
Comment on lines +190 to +209
for (const batch of batches) {
try {
const result = await callWithTimeout(
internal._export(this._exporter, batch),
this._exportTimeout
);
if (result.code !== ExportResultCode.SUCCESS) {
const err = new Error(
`PeriodicExportingMetricReader: metrics export failed (error ${result.error})`
);
api.diag.error(err.message);
anyErr = err;
}
} catch (e) {
if (e instanceof TimeoutError) {
// We do not report TimeoutError to the globalErrorHandler in _runOnce().
api.diag.error(
`PeriodicExportingMetricReader: metrics export timed out after ${this._exportTimeout}ms`
);
} else {
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense, I missed the documentation in callWithTimeout that states:

NOTE: this operation will continue even after it throws a {@link TimeoutError}.

If this is the case, I can modify the loop in _doRun to stop processing further batches if a TimeoutError occurs. This prevents starting new exports while the previous one might still be active in the background.

Important

Breaking the loop on timeout means that if one batch fails due to timeout, subsequent batches in the same export cycle will be skipped. This prioritizes safety (no concurrent exports) over data delivery (trying to send remaining batches)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did the existing code already have this issue if there was a previous export still running?

Copy link
Copy Markdown
Author

@psx95 psx95 May 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existing code also had the same issue (concurrent exports).

I don't see any check before invoking _runOnce() that would verify if the operation in the runOnce function (i.e., export) is still working.

This means that _runOnce() could technically be invoked again while the underlying export operation from previous await callWithTimeout(this._doRun(), this._exportTimeout) is still being run.

};
/**
* The maximum batch size for exports. If configured, the reader will split
* batches larger than this size into smaller batches.
Comment thread CHANGELOG.md Outdated
@pichlermarc pichlermarc self-assigned this May 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement support for maxExportBatchSize for PeriodicExportingMetricReader

5 participants