Is it possible to read all documents in a partition in a single round trip?
I have tried CreateDocumentQuery, but that still seems to result in two server trips, which is less than ideal.
var files = _documentClient.CreateDocumentQuery<TDataType>(_documentCollectionUri, new FeedOptions
{
PartitionKey = new PartitionKey(partitionKey.ToString()),
MaxItemCount = 100
}).ToList();
Note that the trips below are from a query which only has 2/3 records, paging should have had no effect.

I'm closing this issue since it's for the v2 SDK. Please create an issue on the v2 repository if you have more questions.
@j82w - Thanks for the advice. With the V3 SDK, would this be a sensible approach to reading a partition efficiently?
public async Task<IList<TDataType>> GetByContainerId(Guid containerId, ILogger logger)
{
var documents = new List<TDataType>();
var feedIterator = _container.GetItemQueryIterator<TDataType>(requestOptions: new QueryRequestOptions()
{
PartitionKey = new PartitionKey(containerId.ToString()),
MaxItemCount = 100
});
while (feedIterator.HasMoreResults)
{
var response = await feedIterator.ReadNextAsync();
documents.AddRange(response);
}
return documents;
}
The above code leads to this graph:

The client is set up like this as a Singleton:
var connectionString = environmentAccessor.GetEnvironmentVariable(connectionStringSetting);
if (string.IsNullOrEmpty(connectionString))
{
throw new ArgumentException($"Unable to access {connectionStringSetting} in the environment", nameof(connectionStringSetting));
}
var cosmosClient = new CosmosClient(connectionString);
_container = cosmosClient.GetContainer(databaseId, containerId);
@a-vishar those additional calls should only happen on the first request. The SDK has some internal caches that get warmed up. That is why it's recommended to use a singleton pattern. Since it's only the first request it does not impact the SLA. Do you still see the additional calls if you run the query again?
I don't see the same calls on subsequent requests, but it's in an Azure Function, which means that the "first call" can happen a lot.
Similar to the DocumentClient.OpenAsync, is there a way to pre-warm the cache on startup?
@a-vishar In Azure Functions the first call should not happen a lot if you are using static or Singleton instance of the DocumentClient (unless your instances are scaling or you have periods of inactivity where instances get deprovisioned)
Yes, I'm talking about the case where there is inactivity, or that the functions need to scale based on load. I would rather not have a "first call" happen for a customer, and instead have it happen during the startup of the function. Is the answer here that you do not have a way of me warming up the caches without making a "fake" call to the db?
No, because the caches are selective. When you do a request, only the cache for the container you are accessing is generated.
V2 SDK had an OpenAsync method that warmed up all the caches but the drawback was that it would get/refresh caches for all the containers in the account, which generated a big network load for accounts that had a large number of containers, and chances where, the code was only accessing 1 or a very small subset of them, so the benefit was little versus the cost.
I presume from what you have said that caches do not get stale, is that correct?
I'm thinking I could make a single call on host start to get a non-existing document, that would warm the cache for the container that is being used, and ensure that customers do not see this issue. Do you know if there would be any issues with this approach?
Additional information for this, using the following code:
public async Task<IList<TDataType>> GetByContainerId(Guid containerId, ILogger logger)
{
var documents = new List<TDataType>();
logger.LogInformation("GetItemQueryIterator: Start");
var feedIterator = _container.GetItemQueryIterator<TDataType>(requestOptions: new QueryRequestOptions
{
PartitionKey = new PartitionKey(containerId.ToString()),
MaxItemCount = 100
});
logger.LogInformation("GetItemQueryIterator: Complete");
while (feedIterator.HasMoreResults)
{
var response = await feedIterator.ReadNextAsync();
documents.AddRange(response);
}
logger.LogInformation("HasMoreResults: Complete");
return documents;
}
The logged times for this are:
GetItemQueryIterator: Complete: 2020-06-05T16:56:49.8946913Z
HasMoreResults: Complete: 2020-06-05T16:56:52.1029825Z
That's a full 2 seconds of lag that customers will see when the function is scaling, or after some period of inactivity.
Is there truly no way to avoid this?
You can avoid it warming up the caches.
The first request on a Client requires the addresses to be resolved for the container you want to interact with, this happens with V2 or V3 SDK, there is no way to get those addresses without doing a request. That request happens on your first ever request to the container, not the rest.
If you do a Read for an item that does not exist on initialization (this could be when the Function App is starting or when you are creating the Singleton client), that would do the required address resolution and not impact the actual list you are doing later.
Thank you so much for taking the time to walk me through this. I have implemented the changes we discussed and it has improved first load for users by 95%!
Most helpful comment
Thank you so much for taking the time to walk me through this. I have implemented the changes we discussed and it has improved first load for users by 95%!