Learn more about migrating to the Google Ads API by watching our latest webinar

Advanced usage

This guide outlines how to customize several of the more advanced aspects of the Java client library. A common pattern is that many of these features rely on the underlying Callable rather than the standard methods. The callable is generally a good place to look for other per-RPC features that aren't documented here.

Timeout

The Java library provides a surface for setting timeouts on a per-call level. To use this feature you should use the callable object directly. For example, if calling GoogleAdsService.searchStream(), the timeout would be set as:

try (GoogleAdsServiceClient googleAdsServiceClient =
    googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) {
  // Constructs the SearchGoogleAdsStreamRequest.
  SearchGoogleAdsStreamRequest request = ...

  // Executes the API call, with a timeout of 5 minutes.
  ServerStream<SearchGoogleAdsStreamResponse> result = googleAdsServiceClient
      .searchStreamCallable()
      .call(request,
          GrpcCallContext.createDefault().withTimeout(Duration.of(5, ChronoUnit.MINUTES)));
}

The timeout currently cannot be increased beyond a maximum value of 1 hour. If this becomes an issue, it is usually best to split the query up and execute the chunks in parallel; this avoids the situation where a long running request fails and the only way to recover is to trigger the request again from the start.

Retry Settings

The Java library also provides a surface for configuring retry settings on a per-call level. To use this feature you should use the callable object directly. For example, if calling GoogleAdsService.searchStream(), the retry settings would be configured as follows:

// Creates a context object with the custom retry settings.
GrpcCallContext context = GrpcCallContext.createDefault()
    .withRetrySettings(RetrySettings.newBuilder()
    .setInitialRetryDelay(Duration.ofMillis(10L))
    .setMaxRetryDelay(Duration.ofSeconds(10L))
    .setRetryDelayMultiplier(1.4)
    .setMaxAttempts(10)
    .setLogicalTimeout(Duration.ofSeconds(30L))
    .build());

// Creates and issues a search Google Ads stream request.
ServerStream<SearchGoogleAdsStreamResponse> stream =
    googleAdsServiceClient.searchStreamCallable().call(request, context);

Startup time performance optimization

You may notice a small delay the first time a GoogleAdsClient instance is created. This is due to the fluent interface for services (GoogleAdsClient.getVersionXX()), which loads all the API classes at once in order to provide a more convenient mechanism for constructing service classes.

If the first request performance is in the critical path for your application, you should follow these steps:

  1. Create the GoogleAdsClient on startup, before serving user requests.

  2. Send a few warm-up requests to the Google Ads API when the process first starts. For example:

// Runs some warm-up requests.
try (GoogleAdsServiceClient googleAdsServiceClient =
    googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) {
  // Runs 5 warm-up requests. In our profiling we see that 90% of performance
  // loss is only experienced on the first API call. After 3 subsequent calls we
  // saw a negligible improvement in performance.
  for (int i = 0; i < 5; ++i) {
    // Warm-up queries are run with a nonexistent CID so the calls will fail. If
    // you have a CID that you know will be accessible with the OAuth
    // credentials provided you may want to provide that instead and avoid the
    // try-catch.
    try {
      googleAdsServiceClient.search("-1", "Warm-up query");
    } catch (GoogleAdsException ex) {
      // Do nothing, we're expecting this to fail.
    }
  }
}

The warm-up requests only need to be run once per process. Every subsequent service client creation will automatically reuse the preloaded classes.

Service client reuse

You should reuse service client instances where practical since each call to GoogleAdsClient.getVersionXXX().createYYYServiceClient() will create a new TCP connection.

Additionally, you must make sure that you close the client when it's no longer required. This can be done in a try-with-resources block or by calling ServiceClient.close().

App engine fails to deploy if JAR > 32 MB

App Engine has a quota of 32 MB for each uploaded file. The JAR for google-ads will be considerably bigger than this, even moreso using shade/shadow jar deployments. If you deploy jars by hand, you might get errors like:

ERROR: (gcloud.app.deploy) Cannot upload file [<your-app>/WEB-INF/lib/google-ads-14.0.0.jar],
which has size [66095767] (greater than maximum allowed size of [33554432])

Instead, deploy using the AppEngine Gradle plugin or Maven plugin. Each has an option for enableJarSplitting which will split each jar into 10 MB chunks and upload those instead.