Sharing credentials across your API requests improves performance and avoids excessive overhead that can result in rate limit errors. This guide explains how to optimize OAuth2 credential management so your app can efficiently interact with the Google Ads API.
Your credential sharing strategy will depend on whether your app is multithreaded or multiprocess (or distributed). An app that is both multiprocess and multithreaded within each process should employ both strategies. These strategies can also be adapted for multiple Google Ads accounts.
Each session or user drawn by a thread should be using the same credential object. Access token refreshes must also be performed synchronously so as to avoid race conditions.
Our client libraries ensure that the credential is a thread-safe object that
refreshes itself synchronously when its access token expires. Each of our client
libraries has a session (or user) object with a credential that it reuses
throughout its lifetime. To share the credential across threads, you just
construct each session using the same credential. For example, in the Java
client library, you would create a
Credential singleton and share it across
Multiprocess or distributed
For multiprocess or distributed processes, you need to persist the credential before you can share it. To ensure that multiple processes or servers don't attempt to refresh the credential at the same time, resulting in excessive refresh requests, you should assign the refresh to a single process.
For example, a separate job or service can be responsible for periodically refreshing the credential and proactively pushing it to a data store that is shared by a pool of servers. Each server can then retrieve the credential from the data store when making an API request.
The refresh job shouldn't wait until the current credential expires before initiating a refresh. Doing so might result in the app stalling out for lack of a valid credential; though, if a credential's access token expires while the API request is being processed, the request will still complete, and results returned.
We recommend keeping track of the time at which your access token was last refreshed, and force a refresh if there's less than 5 minutes until expiration.
If you don't know when an access token was last refreshed, you could attempt to refresh it assuming it has already expired. If the access token is not close to lapsing, the server returns the same access token, along with the milliseconds remaining until the token expires.
You can make use of an existing data store or deploy one specific to the sharing of credentials between servers. Solutions include caching servers, such as Memcached or Infinispan, or NoSQL data stores, such as MongoDB.
The data store should be optimized for fast reading operations since there will be many more read requests than writes. And, credentials must be stored securely.
When storing the credential, you should store the calculated
refresh_token alongside the
expiry_time is calculated as the time of the
access_token refresh request
Each server or process in the pool retrieves the latest credential from the data store before making a request. As long as the refresh job is running properly, the credential will be valid. However, if the refresh job or data store fails, you should have a fallback mechanism.
If a server or process cannot get a credential from the data store, or if the credential is expired, the server should refresh its own credentials to allow the app to continue working with the API until the problem is resolved.
Credential management for multiple accounts
A credential generated for a Google Ads manager account can be used to access all of its child accounts. Thus, for users with a single manager account hierarchy, it's usually sufficient to generate a credential for the top-level manager account to be used for all the Google Ads accounts beneath it.
If your app needs to access Google Ads accounts that aren't related to one another in any manager account hierarchy, you should generate and maintain different credentials for different accounts—such as for each Google Ads client account you access, or each top-level manager account in the independent hierarchies you access.
You can follow the same strategies for multithreaded or
multiprocess / distributed apps with minor modifications. When
using a shared data store, credentials must be indexed by the account identifier
customerId to ensure credentials are associated with the right account.
Additionally, the refresh job should keep all credentials refreshed. If a new
account is linked, the refresh job may need to be triggered.
Finally, in multithreaded apps, you should only share the credential object across threads that are operating on the account with which the credential object is associated.