Well according to the azure samples the number you pass in is a upper bound, not an exact match. So you can only rely on it returning that number of messages or fewer.
https://github.com/Azure-Samples/azure-servicebus-messaging-samples/tree/master/MessageBrowse#using-peekbatch
"The count of 20 we pass into PeekBatchAsync for how many messages we'd like to obtain is an upper bound. The service may return any number of messages, up to 20 in this case, but will return at least one message if messages are available past the latest read sequence number"
Batching for azure service bus is normally only used as performance enhancement to avoid the overhead of returning messages one at a time. Internally it may
have worked out that returning smaller but more batches is more performant. Batching using exact amounts is not something your program logic should rely upon,
I only really use it to improve application performance since allows more throughput over individual peeks.
There also seems to limit in the amount of data returned in one batch which may be applicable to you.
"At most 256 kByte of cumulative message size will be returned in one batch call."