Skip to content

Read max-message-batch-size vendor property for batch sizing#48214

Open
EldertGrootenboer wants to merge 21 commits intoAzure:mainfrom
EldertGrootenboer:fix/servicebus-batch-size-cap-ICM51000000793879
Open

Read max-message-batch-size vendor property for batch sizing#48214
EldertGrootenboer wants to merge 21 commits intoAzure:mainfrom
EldertGrootenboer:fix/servicebus-batch-size-cap-ICM51000000793879

Conversation

@EldertGrootenboer
Copy link
Copy Markdown
Contributor

@EldertGrootenboer EldertGrootenboer commented Mar 4, 2026

Description

The Service Bus broker enforces a batch size limit (256 KB on Standard, 1 MB on Premium) that differs from the max-message-size advertised on the AMQP link. On Premium large-message entities, the gateway advertises up to 100 MB for max-message-size, but the batch limit remains 1 MB — causing tryAddMessage() to accept oversized batches that the broker then rejects.

The service now advertises the correct batch limit via the vendor property com.microsoft:max-message-batch-size on the sender link. This PR updates the SDK to read that property instead of hardcoding.

Changes

azure-core-amqp:

  • Add AmqpConstants.MAX_MESSAGE_BATCH_SIZE symbol for com.microsoft:max-message-batch-size
  • Add AmqpSendLink.getMaxBatchSize() default method (backward-compatible — falls back to getLinkSize() for Event Hubs)
  • Override in ReactorSender to read the vendor property from link remote properties, with fallback to max-message-size when absent
  • 6 new ReactorSenderTest tests: vendor property reading, absent/non-numeric/zero fallbacks, caching, asymmetry

azure-messaging-servicebus:

  • ServiceBusSenderAsyncClient.createMessageBatch() now calls getMaxBatchSize() instead of getLinkSize()
  • Single-message paths (sendMessage, scheduleMessage) unchanged — continue using full max-message-size
  • DEFAULT_MAX_BATCH_SIZE_BYTES (1 MB) as last-resort fallback when both properties are unavailable
  • 2 new tests: Premium large-message asymmetry (batch=1MB, single=100MB on same link), iterable/schedule paths
  • CHANGELOG entry added

Behavior by tier

Configuration max-message-size max-message-batch-size Batch cap Single cap
Standard 256 KB 256 KB 256 KB 256 KB
Premium default 1 MB 1 MB 1 MB 1 MB
Premium large-message (100 MB entity) 100 MB 1 MB 1 MB 100 MB

ICM Reference

ICM 51000000793879 — customer on Premium tier partitioned, Java SDK 7.17.14, tryAddMessage() accepted >2 MB batch, broker rejected.

Copilot AI review requested due to automatic review settings March 4, 2026 00:46
Copy link
Copy Markdown
Contributor

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

Updates the Service Bus Java sender batching logic to enforce a hard 1 MB maximum batch size, aligning client-side behavior with broker enforcement when AMQP link max-message-size is overstated (notably Premium partitioned namespaces).

Changes:

  • Introduces a 1 MB cap constant and applies it when computing effective batch sizing across batch creation and send/schedule pathways.
  • Adds parameterized unit tests validating capping behavior when the link reports sizes above/below 1 MB and when user-specified batch options exceed the cap.

Reviewed changes

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

File Description
sdk/servicebus/azure-messaging-servicebus/src/main/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClient.java Adds MAX_BATCH_SIZE_BYTES and caps link-derived sizing in batch creation, scheduling, flux send batching, and the message collector.
sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientTest.java Adds parameterized tests to validate 1 MB cap behavior and option validation under both V1/V2 stacks.

@EldertGrootenboer EldertGrootenboer force-pushed the fix/servicebus-batch-size-cap-ICM51000000793879 branch from 40a0fac to 2cb1714 Compare March 4, 2026 01:02
Copy link
Copy Markdown
Contributor

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

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

@EldertGrootenboer EldertGrootenboer force-pushed the fix/servicebus-batch-size-cap-ICM51000000793879 branch from 2cb1714 to 8de6ada Compare March 4, 2026 16:01
The Service Bus broker enforces a 1 MB batch size limit regardless of the
max-message-size advertised on the AMQP link. Premium partitioned namespaces
advertise 100 MB on the link, causing tryAddMessage() to accept batches the
broker will reject.

Cap batch creation in ServiceBusSenderAsyncClient.createMessageBatch() at
1 MB (MAX_BATCH_SIZE_BYTES). This is the single enforcement point: both
sendMessages(iterable) and scheduleMessages(iterable) call createMessageBatch
internally. Single-message paths (sendMessage, scheduleMessage) are NOT
capped since the 1 MB limit is batch-specific and individual messages on
Premium can validly exceed 1 MB up to the per-entity limit.

When a user requests a batch size exceeding 1 MB via
CreateMessageBatchOptions, throw ServiceBusException.

Tracking: azure-service-bus#708
ICM: 51000000793879
@EldertGrootenboer EldertGrootenboer force-pushed the fix/servicebus-batch-size-cap-ICM51000000793879 branch from 8de6ada to e3b2ef6 Compare March 4, 2026 16:56
Copy link
Copy Markdown
Contributor

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

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@EldertGrootenboer EldertGrootenboer enabled auto-merge (squash) March 16, 2026 20:52
@j7nw4r j7nw4r self-requested a review March 24, 2026 20:24
Copy link
Copy Markdown
Member

@j7nw4r j7nw4r left a comment

Choose a reason for hiding this comment

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

LGTM

- Add AmqpConstants.MAX_MESSAGE_BATCH_SIZE for com.microsoft:max-message-batch-size
- Add AmqpSendLink.getMaxBatchSize() default method (falls back to getLinkSize())
- Override in ReactorSender to read vendor property from link remote properties
- ServiceBusSenderAsyncClient.createMessageBatch() uses getMaxBatchSize() instead
  of getLinkSize(), with 1 MB fallback when vendor property is absent
- Single-message paths (sendMessage, scheduleMessage) continue using getLinkSize()
- 6 new ReactorSenderTest tests for vendor property, fallback, and edge cases
- 2 new ServiceBusSenderAsyncClientTest tests for asymmetry and vendor property
- Bump azure-core-amqp dependency to 2.12.0-beta.1
- Add CHANGELOG entry under Bugs Fixed
@EldertGrootenboer EldertGrootenboer changed the title Cap ServiceBusMessageBatch size at 1 MB to match broker enforcement Read max-message-batch-size vendor property for batch sizing Apr 8, 2026
Copy link
Copy Markdown
Contributor

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

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.

Copy link
Copy Markdown
Contributor

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

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Replace Flux.fromStream(IntStream...) with Flux.range().map() so the publisher remains resubscribable. Stream instances are single-use; if the code under test re-subscribes (retry, tracing instrumentation), the second subscription would fail with 'stream has already been operated upon or closed'.
Copy link
Copy Markdown
Contributor

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

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.

Copy link
Copy Markdown
Contributor

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

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.

Copy link
Copy Markdown
Contributor

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

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.

Copy link
Copy Markdown
Contributor

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

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.

Copy link
Copy Markdown
Contributor

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

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.

Copy link
Copy Markdown
Contributor

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

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.

EldertGrootenboer added a commit to Azure/azure-sdk-for-js that referenced this pull request May 8, 2026
…ch sizing (#38049)

## Problem

On Premium large-message Service Bus entities, the AMQP link's
`max-message-size` can be up to 100 MB, but the broker enforces a 1 MB
limit for batch sends. The JS SDK reads `max-message-size` (via
`this.link.maxMessageSize`) for batch sizing, so `createMessageBatch()`
accepts batches up to 100 MB that the broker then rejects.

Related:
[azure-service-bus#708](Azure/azure-service-bus#708)

## Fix

Read the `com.microsoft:max-message-batch-size` vendor property from the
AMQP sender link attach frame, which correctly reports 256 KB (Standard)
/ 1 MB (Premium) independent of entity-level `max-message-size`. When
the vendor property is absent (older service versions), fall back to
`Math.min(maxMessageSize, defaultMaxBatchSize)` where
`defaultMaxBatchSize` is 1 MB — this caps the batch size to prevent
using the raw `max-message-size` (which can be up to 100 MB on Premium
large-message entities).

### Changes

- **`messageSender.ts`**: Add `defaultMaxBatchSize` constant (1 MB); add
`getMaxBatchSizeFromLink()` that reads the vendor property from
`this.link.properties`, falling back to `Math.min(maxMessageSize,
defaultMaxBatchSize)`; update `createBatch()` to use the new method
- **`messageSender.spec.ts`**: Unit tests for vendor property present,
absent (with 1 MB cap), undefined properties, wrong type, zero value,
user override, rejection of oversized `maxSizeInBytes`, Standard tier

### Cross-SDK alignment

| SDK | Status |
|-----|--------|
| .NET | [PR
#57941](Azure/azure-sdk-for-net#57941) |
| Java | [PR
#48214](Azure/azure-sdk-for-java#48214) |
| Go | [PR #26530](Azure/azure-sdk-for-go#26530)
|
| Python | [PR
#46197](Azure/azure-sdk-for-python#46197) |

---------

Co-authored-by: Eldert Grootenboer (from Dev Box) <egrootenboer@microsoft.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants