When a mobile testing platform runs hundreds of automated tests, retrieving the results can become a bottleneck of its own. A test runner may finish executing scenarios across multiple Android devices, but the reporting service still needs to collect session details, identify failures, and correlate the results with a particular build. If the service retrieves each session individually, a large test run can generate hundreds of API requests before the team can produce a complete report.

Google Cloud's Device Run API introduces a way to retrieve up to 500 automation sessions in a single request. The capability is relevant to teams that run mobile application tests at scale and need to collect execution data for dashboards, CI pipelines, failure analysis, or release reporting.

The practical benefit is fewer retrieval requests and a simpler reporting workflow. However, a batch API does not automatically solve every problem associated with large test runs. Developers still need to handle pagination, partial results, API errors, data consistency, and the processing cost of large responses.

What Is the Device Run API?

Google Cloud's Device Run API provides programmatic access to automation session information associated with device testing. A session represents an execution instance that can contain information about a test run, its status, and associated results.

For example, a mobile application team might execute login, checkout, navigation, and payment tests across several device configurations. Each execution can produce a session that needs to be collected and analyzed after the tests finish.

A reporting service may use these sessions to answer questions such as:

Without an appropriate retrieval strategy, gathering these results can create unnecessary network traffic and increase the time required to generate reports.

The new batch capability allows a client to request up to 500 automation sessions at once rather than issuing an individual request for every session. The exact endpoint, request parameters, response schema, and pagination behavior should be confirmed against the API version available to the project before implementation.

Why Batch Retrieval Matters

Consider a test pipeline that executes 1,000 device sessions. If the reporting service retrieves one session per request, it may need approximately 1,000 retrieval calls, excluding retries and other API operations.

If the API supports batches of 500 sessions, the same number of sessions could theoretically be retrieved in two full batches. This is an illustrative calculation, not a benchmark or a guarantee that the service will return all sessions in exactly two requests.

Reducing the number of requests can help in several ways. It decreases request overhead, simplifies orchestration, and may reduce the time spent waiting for individual responses. It can also make downstream reporting more straightforward because the client receives multiple session records together.

However, the number of sessions returned per request is not the same as the amount of data transferred. A batch containing 500 detailed session records may produce a large response. If each session includes substantial metadata or nested results, processing and memory requirements can still be significant.

Batching is therefore a request-efficiency improvement, not a replacement for sound data-processing design.

How to Design a Session Retrieval Workflow

A typical reporting workflow has four stages:

  1. Identify the relevant test run or session collection.

  2. Request sessions in batches within the supported limit.

  3. Process each returned session and record its outcome.

  4. Continue until all relevant sessions have been retrieved.

The most important implementation decision is how the client determines which sessions belong to the reporting job. If the application retrieves every session without a filter, it may repeatedly process historical data or combine results from unrelated builds.

Where the API supports suitable filters, use the narrowest scope that satisfies the reporting requirement. A CI pipeline should normally collect sessions associated with the relevant test execution rather than downloading an entire project's history.

The workflow should also distinguish between retrieving sessions and processing them. A successful API response means that the request succeeded; it does not necessarily mean every session completed successfully or that every result is suitable for the final report.

Implementing Batch Retrieval in C#

The following example demonstrates how to structure a C# client around a batch retrieval operation. It uses an application-defined API contract rather than inventing a Device Run endpoint or response schema. The actual HTTP request must be implemented using the endpoint, authentication mechanism, and request parameters documented for the API version in use.

First, define a model for the information the reporting application needs:

public sealed record AutomationSession(
    string SessionId,
    string Status,
    string? DeviceModel,
    string? ErrorMessage
);

public sealed record SessionBatch(
    IReadOnlyList<AutomationSession> Sessions,
    string? NextPageToken
);

The session model deliberately contains only the fields required by this example. A real integration should map the documented API response into its own application model rather than assume that the service returns these exact properties.

Next, define an abstraction for retrieving a batch:

public interface IDeviceRunClient
{
    Task<SessionBatch> GetSessionsAsync(
        string testRunId,
        string? pageToken,
        int pageSize,
        CancellationToken cancellationToken);
}

This interface separates the reporting workflow from the HTTP implementation. It also makes the workflow easier to unit test without calling the external service.

The batch processor can then retrieve sessions until no further page is available:

public static async Task ProcessSessionsAsync(
    IDeviceRunClient client,
    string testRunId,
    CancellationToken cancellationToken)
{
    const int batchSize = 500;

    string? pageToken = null;

    do
    {
        SessionBatch batch = await client.GetSessionsAsync(
            testRunId,
            pageToken,
            batchSize,
            cancellationToken);

        foreach (AutomationSession session in batch.Sessions)
        {
            Console.WriteLine(
                $"Session: {session.SessionId}, " +
                $"Status: {session.Status}");
        }

        pageToken = batch.NextPageToken;

    } while (pageToken is not null);
}

The example shows the control flow, not a complete production integration. The IDeviceRunClient implementation must validate the supported page size and map the actual API's pagination mechanism to NextPageToken. If the service uses a different pagination contract, adapt the abstraction accordingly.

The important design decision is that the processing logic does not depend on the transport details. The HTTP client is responsible for authentication, request construction, response deserialization, and error handling. The reporting workflow is responsible for iterating through batches and processing the returned sessions.

This separation prevents API-specific details from spreading through the application.

Handling Large Responses Without Exhausting Memory

A batch size of 500 may be appropriate for reducing request overhead, but it should not automatically become the size of every in-memory processing unit.

Suppose a session record contains detailed execution metadata, screenshots, logs, or other large fields. Loading every record into a single collection can consume substantially more memory than expected. The exact impact depends on the response structure and the application's deserialization behavior.

For reporting pipelines, process each batch as it arrives instead of accumulating all sessions in memory unnecessarily. If the results must be retained, persist them to a database or object store and keep only the data needed for the current operation in memory.

For example, a reporting service may extract session identifiers, statuses, device information, and failure summaries while storing larger diagnostic artifacts separately. The report can then query the compact records without repeatedly loading large payloads.

If the API supports field selection or returning summary information, request only the fields the application actually needs. This can reduce network transfer and deserialization overhead, but the available options must be verified in the API documentation.

Error Handling and Retry Strategies

A batch retrieval workflow must account for failures that can occur even when the overall design is correct.

Network interruptions, temporary service errors, authentication problems, invalid filters, and request limits can all prevent a batch from being retrieved. The client should distinguish transient failures from errors that require configuration changes or operator intervention.

For transient failures, use bounded retries with exponential backoff and jitter where appropriate. Respect any retry guidance or rate-limit information returned by the service. Retrying every error indefinitely can turn a temporary problem into a prolonged pipeline failure.

Cancellation also matters. If a CI job is cancelled or exceeds its execution deadline, pass a CancellationToken through the retrieval and processing layers so that unnecessary requests do not continue.

Another concern is partial processing. If the first two batches are persisted successfully and the third request fails, restarting the workflow should not create duplicate records or incorrectly mark the report as complete.

A reliable implementation can use the session identifier as a stable key, apply idempotent upserts, and track whether the full retrieval process has completed. The precise persistence strategy depends on the API's consistency guarantees and the application's reporting requirements.

Testing and Operational Monitoring

Batch retrieval should be tested with more than a single successful response. At a minimum, test empty results, a full batch, multiple batches, an API error, cancellation, malformed data, and a failure that occurs after earlier batches have already been processed.

If the API uses pagination tokens, verify that the client follows them correctly and stops when the service indicates that no additional results are available. Avoid assuming that receiving fewer records than the requested page size always means the result set is complete unless the API contract explicitly guarantees that behavior.

Operational monitoring should capture useful measurements, including:

These metrics help distinguish retrieval problems from actual test failures. A reporting pipeline that fails to fetch session details should not silently classify the missing results as successful tests.

Advantages and Limitations

Advantages

Limitations

Summary

Google Cloud's Device Run API supports retrieving up to 500 automation sessions in a single request, giving developers a more convenient way to collect mobile test execution data for reporting and analysis.

For C# developers integrating this capability into CI pipelines, the main engineering priorities are to use the documented API contract, retrieve only relevant sessions, process batches incrementally, and handle pagination and transient failures correctly.

The batch size should be treated as a maximum supported request size rather than a guarantee of optimal performance for every workload. With appropriate filtering, idempotent processing, cancellation, and monitoring, batch retrieval can simplify large test-reporting workflows without introducing unnecessary memory or reliability problems.