From 682331bb3b27a4b085572515312b969b1ad0e922 Mon Sep 17 00:00:00 2001 From: Eldert Grootenboer Date: Wed, 5 Aug 2026 16:20:15 -0700 Subject: [PATCH 1/3] [Service Bus] Clarify prefetch_count versus max_message_count docstrings The prefetch_count docstring described the setting as the maximum number of messages to cache, while a following sentence said that at a prefetch_count of 0 receive_messages caches max_message_count within its request. Reusing cache for both a standing buffer and a per-call request made the two settings read as one. prefetch_count is now described as what the receiver requests ahead of a receive call, and each site states that it is separate from the max_message_count argument. receive_messages explains how the two interact at and above the default, and documents that passing None falls back to prefetch_count and so returns an empty list at the default. Fixes #42697. --- .../azure/servicebus/_servicebus_client.py | 22 +++++----- .../azure/servicebus/_servicebus_receiver.py | 44 +++++++++++-------- .../aio/_servicebus_client_async.py | 22 +++++----- .../aio/_servicebus_receiver_async.py | 44 +++++++++++-------- 4 files changed, 76 insertions(+), 56 deletions(-) diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py index f28eba0ff2b3..627d29762291 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_client.py @@ -402,13 +402,14 @@ def get_queue_receiver( :keyword Optional[~azure.servicebus.AutoLockRenewer] auto_lock_renewer: An ~azure.servicebus.AutoLockRenewer can be provided such that messages are automatically registered on receipt. If the receiver is a session receiver, it will apply to the session instead. - :keyword int prefetch_count: The maximum number of messages to cache with each request to the service. + :keyword int prefetch_count: The number of messages the receiver requests ahead of a + receive call, so that receive calls can be served from the buffer instead of waiting on a + service request. This is separate from the `max_message_count` argument to + `receive_messages`, which bounds a single call rather than the buffer. This setting is only for advanced performance tuning. Increasing this value will improve message throughput - performance but increase the chance that messages will expire while they are cached if they're not + performance but increase the chance that messages will expire while they are buffered if they're not processed fast enough. - The default value is 0, meaning messages will be received from the service and processed one at a time. - In the case of prefetch_count being 0, `ServiceBusReceiver.receive_messages` would try to cache - `max_message_count` (if provided) within its request to the service. + The default value is 0, meaning prefetch is turned off. WARNING: If prefetch_count > 0 and RECEIVE_AND_DELETE mode is used, all prefetched messages will stay in the in-memory prefetch buffer until they're received into the application. If the application ends before the messages are received into the application, those messages will be lost and unable to be recovered. @@ -593,13 +594,14 @@ def get_subscription_receiver( :keyword Optional[~azure.servicebus.AutoLockRenewer] auto_lock_renewer: An ~azure.servicebus.AutoLockRenewer can be provided such that messages are automatically registered on receipt. If the receiver is a session receiver, it will apply to the session instead. - :keyword int prefetch_count: The maximum number of messages to cache with each request to the service. + :keyword int prefetch_count: The number of messages the receiver requests ahead of a + receive call, so that receive calls can be served from the buffer instead of waiting on a + service request. This is separate from the `max_message_count` argument to + `receive_messages`, which bounds a single call rather than the buffer. This setting is only for advanced performance tuning. Increasing this value will improve message throughput - performance but increase the chance that messages will expire while they are cached if they're not + performance but increase the chance that messages will expire while they are buffered if they're not processed fast enough. - The default value is 0, meaning messages will be received from the service and processed one at a time. - In the case of prefetch_count being 0, `ServiceBusReceiver.receive_messages` would try to cache - `max_message_count` (if provided) within its request to the service. + The default value is 0, meaning prefetch is turned off. WARNING: If prefetch_count > 0 and RECEIVE_AND_DELETE mode is used, all prefetched messages will stay in the in-memory prefetch buffer until they're received into the application. If the application ends before the messages are received into the application, those messages will be lost and unable to be recovered. diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py index 496aa79330ec..cead66f7743d 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py @@ -125,13 +125,14 @@ class ServiceBusReceiver(BaseHandler, ReceiverMixin): # pylint: disable=too-many :keyword Optional[~azure.servicebus.AutoLockRenewer] auto_lock_renewer: An ~azure.servicebus.AutoLockRenewer can be provided such that messages are automatically registered on receipt. If the receiver is a session receiver, it will apply to the session instead. - :keyword int prefetch_count: The maximum number of messages to cache with each request to the service. + :keyword int prefetch_count: The number of messages the receiver requests ahead of a + receive call, so that receive calls can be served from the buffer instead of waiting on a + service request. This is separate from the `max_message_count` argument to + `receive_messages`, which bounds a single call rather than the buffer. This setting is only for advanced performance tuning. Increasing this value will improve message throughput - performance but increase the chance that messages will expire while they are cached if they're not + performance but increase the chance that messages will expire while they are buffered if they're not processed fast enough. - The default value is 0, meaning messages will be received from the service and processed one at a time. - In the case of prefetch_count being 0, `ServiceBusReceiver.receive_messages` would try to cache - `max_message_count` (if provided) within its request to the service. + The default value is 0, meaning prefetch is turned off. WARNING: If prefetch_count > 0 and RECEIVE_AND_DELETE mode is used, all prefetched messages will stay in the in-memory prefetch buffer until they're received into the application. If the application ends before the messages are received into the application, those messages will be lost and unable to be recovered. @@ -284,13 +285,14 @@ def _from_connection_string(cls, conn_str: str, **kwargs: Any) -> "ServiceBusRec keys: `'proxy_hostname'` (str value) and `'proxy_port'` (int value). Additionally the following keys may also be present: `'username', 'password'`. :keyword str user_agent: If specified, this will be added in front of the built-in user agent string. - :keyword int prefetch_count: The maximum number of messages to cache with each request to the service. + :keyword int prefetch_count: The number of messages the receiver requests ahead of a + receive call, so that receive calls can be served from the buffer instead of waiting on a + service request. This is separate from the `max_message_count` argument to + `receive_messages`, which bounds a single call rather than the buffer. This setting is only for advanced performance tuning. Increasing this value will improve message throughput - performance but increase the chance that messages will expire while they are cached if they're not + performance but increase the chance that messages will expire while they are buffered if they're not processed fast enough. - The default value is 0, meaning messages will be received from the service and processed one at a time. - In the case of prefetch_count being 0, `ServiceBusReceiver.receive_messages` would try to cache - `max_message_count` (if provided) within its request to the service. + The default value is 0, meaning prefetch is turned off. WARNING: If prefetch_count > 0 and RECEIVE_AND_DELETE mode is used, all prefetched messages will stay in the in-memory prefetch buffer until they're received into the application. If the application ends before the messages are received into the application, those messages will be lost and unable to be recovered. @@ -610,20 +612,26 @@ def receive_messages( This approach is optimal if you wish to process multiple messages simultaneously, or perform an ad-hoc receive as a single call. - Note that the number of messages retrieved in a single batch will be dependent on - whether `prefetch_count` was set for the receiver. If `prefetch_count` is not set for the receiver, - the receiver would try to cache max_message_count (if provided) messages within the request to the service. + `max_message_count` bounds what this call returns, while `prefetch_count` governs what the + receiver holds ahead of the call, so they are separate settings rather than two names for + the same one. When `prefetch_count` is 0, the receiver requests `max_message_count` (if + provided) messages from the service on this call. When `prefetch_count` is greater than 0, + the call is served first from what the receiver already holds, and if that is fewer than + `max_message_count` it continues receiving on the receiver's standing prefetch credit until + the count is met or the wait time elapses. This call will prioritize returning quickly over meeting a specified batch size, and so will return as soon as at least one message is received and there is a gap in incoming messages regardless of the specified batch size. - :param Optional[int] max_message_count: Maximum number of messages in the batch. Actual number - returned will depend on prefetch_count and incoming stream rate. - Setting to None will fully depend on the prefetch config. The default value is 1. + :param Optional[int] max_message_count: Maximum number of messages in the batch. This is an upper + bound: the call returns fewer messages when fewer are available, when the wait time elapses, or + when a gap in incoming messages ends the batch early. Setting to None falls back to + `prefetch_count`, so at the default `prefetch_count` of 0 the call returns an empty list + immediately. The default value is 1. :param Optional[float] max_wait_time: Maximum time to wait in seconds for the first message to arrive. - If no messages arrive, and no timeout is specified, this call will not return - until the connection is closed. If specified, and no messages arrive within the + If messages are requested, no messages arrive, and no timeout is specified, this call will not + return until the connection is closed. If specified, and no messages arrive within the timeout period, an empty list will be returned. NOTE: Setting max_wait_time on receive_messages when NEXT_AVAILABLE_SESSION is specified will not impact the timeout for connecting to a session. Please use max_wait_time on the constructor to set the timeout for connecting to a session. diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_client_async.py b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_client_async.py index 687f98d5a504..bf5b2968f75c 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_client_async.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_client_async.py @@ -389,13 +389,14 @@ def get_queue_receiver( :keyword Optional[~azure.servicebus.aio.AutoLockRenewer] auto_lock_renewer: An ~azure.servicebus.aio.AutoLockRenewer can be provided such that messages are automatically registered on receipt. If the receiver is a session receiver, it will apply to the session instead. - :keyword int prefetch_count: The maximum number of messages to cache with each request to the service. + :keyword int prefetch_count: The number of messages the receiver requests ahead of a + receive call, so that receive calls can be served from the buffer instead of waiting on a + service request. This is separate from the `max_message_count` argument to + `receive_messages`, which bounds a single call rather than the buffer. This setting is only for advanced performance tuning. Increasing this value will improve message throughput - performance but increase the chance that messages will expire while they are cached if they're not + performance but increase the chance that messages will expire while they are buffered if they're not processed fast enough. - The default value is 0, meaning messages will be received from the service and processed one at a time. - In the case of prefetch_count being 0, `ServiceBusReceiver.receive_messages` would try to cache - `max_message_count` (if provided) within its request to the service. + The default value is 0, meaning prefetch is turned off. WARNING: If prefetch_count > 0 and RECEIVE_AND_DELETE mode is used, all prefetched messages will stay in the in-memory prefetch buffer until they're received into the application. If the application ends before the messages are received into the application, those messages will be lost and unable to be recovered. @@ -580,13 +581,14 @@ def get_subscription_receiver( :keyword Optional[~azure.servicebus.aio.AutoLockRenewer] auto_lock_renewer: An ~azure.servicebus.aio.AutoLockRenewer can be provided such that messages are automatically registered on receipt. If the receiver is a session receiver, it will apply to the session instead. - :keyword int prefetch_count: The maximum number of messages to cache with each request to the service. + :keyword int prefetch_count: The number of messages the receiver requests ahead of a + receive call, so that receive calls can be served from the buffer instead of waiting on a + service request. This is separate from the `max_message_count` argument to + `receive_messages`, which bounds a single call rather than the buffer. This setting is only for advanced performance tuning. Increasing this value will improve message throughput - performance but increase the chance that messages will expire while they are cached if they're not + performance but increase the chance that messages will expire while they are buffered if they're not processed fast enough. - The default value is 0, meaning messages will be received from the service and processed one at a time. - In the case of prefetch_count being 0, `ServiceBusReceiver.receive_messages` would try to cache - `max_message_count` (if provided) within its request to the service. + The default value is 0, meaning prefetch is turned off. WARNING: If prefetch_count > 0 and RECEIVE_AND_DELETE mode is used, all prefetched messages will stay in the in-memory prefetch buffer until they're received into the application. If the application ends before the messages are received into the application, those messages will be lost and unable to be recovered. diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_receiver_async.py b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_receiver_async.py index 314384af6c7d..5a23b8b2fce4 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_receiver_async.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_receiver_async.py @@ -123,13 +123,14 @@ class ServiceBusReceiver(AsyncIterator, BaseHandler, ReceiverMixin): :keyword Optional[~azure.servicebus.aio.AutoLockRenewer] auto_lock_renewer: An ~azure.servicebus.aio.AutoLockRenewer can be provided such that messages are automatically registered on receipt. If the receiver is a session receiver, it will apply to the session instead. - :keyword int prefetch_count: The maximum number of messages to cache with each request to the service. + :keyword int prefetch_count: The number of messages the receiver requests ahead of a + receive call, so that receive calls can be served from the buffer instead of waiting on a + service request. This is separate from the `max_message_count` argument to + `receive_messages`, which bounds a single call rather than the buffer. This setting is only for advanced performance tuning. Increasing this value will improve message throughput - performance but increase the chance that messages will expire while they are cached if they're not + performance but increase the chance that messages will expire while they are buffered if they're not processed fast enough. - The default value is 0, meaning messages will be received from the service and processed one at a time. - In the case of prefetch_count being 0, `ServiceBusReceiver.receive_messages` would try to cache - `max_message_count` (if provided) within its request to the service. + The default value is 0, meaning prefetch is turned off. WARNING: If prefetch_count > 0 and RECEIVE_AND_DELETE mode is used, all prefetched messages will stay in the in-memory prefetch buffer until they're received into the application. If the application ends before the messages are received into the application, those messages will be lost and unable to be recovered. @@ -279,13 +280,14 @@ def _from_connection_string(cls, conn_str: str, **kwargs: Any) -> "ServiceBusRec keys: `'proxy_hostname'` (str value) and `'proxy_port'` (int value). Additionally the following keys may also be present: `'username', 'password'`. :keyword str user_agent: If specified, this will be added in front of the built-in user agent string. - :keyword int prefetch_count: The maximum number of messages to cache with each request to the service. + :keyword int prefetch_count: The number of messages the receiver requests ahead of a + receive call, so that receive calls can be served from the buffer instead of waiting on a + service request. This is separate from the `max_message_count` argument to + `receive_messages`, which bounds a single call rather than the buffer. This setting is only for advanced performance tuning. Increasing this value will improve message throughput - performance but increase the chance that messages will expire while they are cached if they're not + performance but increase the chance that messages will expire while they are buffered if they're not processed fast enough. - The default value is 0, meaning messages will be received from the service and processed one at a time. - In the case of prefetch_count being 0, `ServiceBusReceiver.receive_messages` would try to cache - `max_message_count` (if provided) within its request to the service. + The default value is 0, meaning prefetch is turned off. WARNING: If prefetch_count > 0 and RECEIVE_AND_DELETE mode is used, all prefetched messages will stay in the in-memory prefetch buffer until they're received into the application. If the application ends before the messages are received into the application, those messages will be lost and unable to be recovered. @@ -599,20 +601,26 @@ async def receive_messages( This approach is optimal if you wish to process multiple messages simultaneously, or perform an ad-hoc receive as a single call. - Note that the number of messages retrieved in a single batch will be dependent on - whether `prefetch_count` was set for the receiver. If `prefetch_count` is not set for the receiver, - the receiver would try to cache max_message_count (if provided) messages within the request to the service. + `max_message_count` bounds what this call returns, while `prefetch_count` governs what the + receiver holds ahead of the call, so they are separate settings rather than two names for + the same one. When `prefetch_count` is 0, the receiver requests `max_message_count` (if + provided) messages from the service on this call. When `prefetch_count` is greater than 0, + the call is served first from what the receiver already holds, and if that is fewer than + `max_message_count` it continues receiving on the receiver's standing prefetch credit until + the count is met or the wait time elapses. This call will prioritize returning quickly over meeting a specified batch size, and so will return as soon as at least one message is received and there is a gap in incoming messages regardless of the specified batch size. - :param Optional[int] max_message_count: Maximum number of messages in the batch. Actual number - returned will depend on prefetch_count size and incoming stream rate. - Setting to None will fully depend on the prefetch config. The default value is 1. + :param Optional[int] max_message_count: Maximum number of messages in the batch. This is an upper + bound: the call returns fewer messages when fewer are available, when the wait time elapses, or + when a gap in incoming messages ends the batch early. Setting to None falls back to + `prefetch_count`, so at the default `prefetch_count` of 0 the call returns an empty list + immediately. The default value is 1. :param Optional[float] max_wait_time: Maximum time to wait in seconds for the first message to arrive. - If no messages arrive, and no timeout is specified, this call will not return - until the connection is closed. If specified, and no messages arrive within the + If messages are requested, no messages arrive, and no timeout is specified, this call will not + return until the connection is closed. If specified, and no messages arrive within the timeout period, an empty list will be returned. NOTE: Setting max_wait_time on receive_messages when NEXT_AVAILABLE_SESSION is specified will not impact the timeout for connecting to a session. Please use max_wait_time on the constructor to set the timeout for connecting to a session. From cbb1542713de25d1fbf39f66ec7eae2a7a7956da Mon Sep 17 00:00:00 2001 From: Eldert Grootenboer Date: Wed, 5 Aug 2026 16:42:45 -0700 Subject: [PATCH 2/3] Address review: do not claim an immediate return _receive opens the AMQP receiver before resolving None to a zero count, so a first call on an unopened receiver connects and authenticates before returning. Say the call returns without waiting for messages rather than immediately, which read as a latency guarantee. --- .../azure-servicebus/azure/servicebus/_servicebus_receiver.py | 2 +- .../azure/servicebus/aio/_servicebus_receiver_async.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py index cead66f7743d..5b737862a466 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py @@ -628,7 +628,7 @@ def receive_messages( bound: the call returns fewer messages when fewer are available, when the wait time elapses, or when a gap in incoming messages ends the batch early. Setting to None falls back to `prefetch_count`, so at the default `prefetch_count` of 0 the call returns an empty list - immediately. The default value is 1. + without waiting for messages. The default value is 1. :param Optional[float] max_wait_time: Maximum time to wait in seconds for the first message to arrive. If messages are requested, no messages arrive, and no timeout is specified, this call will not return until the connection is closed. If specified, and no messages arrive within the diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_receiver_async.py b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_receiver_async.py index 5a23b8b2fce4..7822ca8ebeb7 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_receiver_async.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_receiver_async.py @@ -617,7 +617,7 @@ async def receive_messages( bound: the call returns fewer messages when fewer are available, when the wait time elapses, or when a gap in incoming messages ends the batch early. Setting to None falls back to `prefetch_count`, so at the default `prefetch_count` of 0 the call returns an empty list - immediately. The default value is 1. + without waiting for messages. The default value is 1. :param Optional[float] max_wait_time: Maximum time to wait in seconds for the first message to arrive. If messages are requested, no messages arrive, and no timeout is specified, this call will not return until the connection is closed. If specified, and no messages arrive within the From 778d05c8a67c5499544e5834d861067f7b45ba50 Mon Sep 17 00:00:00 2001 From: Eldert Grootenboer Date: Wed, 5 Aug 2026 21:03:46 -0700 Subject: [PATCH 3/3] Scope the prefetch_count fallback wording to the call Addresses review feedback on the receive_messages docstring. Scopes the requests claim to the call, since the link holds one standing credit even at prefetch_count 0, and uses one vocabulary for the None condition. --- .../azure/servicebus/_servicebus_receiver.py | 18 +++++++++--------- .../aio/_servicebus_receiver_async.py | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py index 5b737862a466..0bfb508db77f 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/_servicebus_receiver.py @@ -613,12 +613,11 @@ def receive_messages( perform an ad-hoc receive as a single call. `max_message_count` bounds what this call returns, while `prefetch_count` governs what the - receiver holds ahead of the call, so they are separate settings rather than two names for - the same one. When `prefetch_count` is 0, the receiver requests `max_message_count` (if - provided) messages from the service on this call. When `prefetch_count` is greater than 0, - the call is served first from what the receiver already holds, and if that is fewer than - `max_message_count` it continues receiving on the receiver's standing prefetch credit until - the count is met or the wait time elapses. + receiver holds ahead of the call. When `prefetch_count` is 0, the receiver requests + `max_message_count` (unless it is None) messages from the service on this call. When + `prefetch_count` is greater than 0, the call is served first from what the receiver already + holds, and if that is fewer than `max_message_count` it keeps receiving until the count is + met or the wait time elapses. This call will prioritize returning quickly over meeting a specified batch size, and so will return as soon as at least one message is received and there is a gap in incoming messages regardless @@ -626,9 +625,10 @@ def receive_messages( :param Optional[int] max_message_count: Maximum number of messages in the batch. This is an upper bound: the call returns fewer messages when fewer are available, when the wait time elapses, or - when a gap in incoming messages ends the batch early. Setting to None falls back to - `prefetch_count`, so at the default `prefetch_count` of 0 the call returns an empty list - without waiting for messages. The default value is 1. + when a gap in incoming messages ends the batch early. Setting to None uses `prefetch_count` + as the bound instead, so at the default `prefetch_count` of 0 the call requests no messages + and returns an empty list without waiting, even when `max_wait_time` is set. The default + value is 1. :param Optional[float] max_wait_time: Maximum time to wait in seconds for the first message to arrive. If messages are requested, no messages arrive, and no timeout is specified, this call will not return until the connection is closed. If specified, and no messages arrive within the diff --git a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_receiver_async.py b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_receiver_async.py index 7822ca8ebeb7..0d7ea3b134a1 100644 --- a/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_receiver_async.py +++ b/sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_receiver_async.py @@ -602,12 +602,11 @@ async def receive_messages( perform an ad-hoc receive as a single call. `max_message_count` bounds what this call returns, while `prefetch_count` governs what the - receiver holds ahead of the call, so they are separate settings rather than two names for - the same one. When `prefetch_count` is 0, the receiver requests `max_message_count` (if - provided) messages from the service on this call. When `prefetch_count` is greater than 0, - the call is served first from what the receiver already holds, and if that is fewer than - `max_message_count` it continues receiving on the receiver's standing prefetch credit until - the count is met or the wait time elapses. + receiver holds ahead of the call. When `prefetch_count` is 0, the receiver requests + `max_message_count` (unless it is None) messages from the service on this call. When + `prefetch_count` is greater than 0, the call is served first from what the receiver already + holds, and if that is fewer than `max_message_count` it keeps receiving until the count is + met or the wait time elapses. This call will prioritize returning quickly over meeting a specified batch size, and so will return as soon as at least one message is received and there is a gap in incoming messages regardless @@ -615,9 +614,10 @@ async def receive_messages( :param Optional[int] max_message_count: Maximum number of messages in the batch. This is an upper bound: the call returns fewer messages when fewer are available, when the wait time elapses, or - when a gap in incoming messages ends the batch early. Setting to None falls back to - `prefetch_count`, so at the default `prefetch_count` of 0 the call returns an empty list - without waiting for messages. The default value is 1. + when a gap in incoming messages ends the batch early. Setting to None uses `prefetch_count` + as the bound instead, so at the default `prefetch_count` of 0 the call requests no messages + and returns an empty list without waiting, even when `max_wait_time` is set. The default + value is 1. :param Optional[float] max_wait_time: Maximum time to wait in seconds for the first message to arrive. If messages are requested, no messages arrive, and no timeout is specified, this call will not return until the connection is closed. If specified, and no messages arrive within the