Working with Rate Limits

As part of Geotab's ongoing commitment to service scalability and reliability, Geotab has implemented API rate limits on the MyGeotab SDK to minimize performance risk and improve overall API call efficiency.

These API rate limits apply to each unique combination of method, entity, username, and database. One User-Agent's rate limiting does not affect another.

If you are an integrator or partner with an active integration it is extremely important that you review your code to ensure that you are aligned with Geotab's best practice.

Understanding the base rate limits

You can see the details of the specific rate limits for each Method and Entity on the Geotab SDK site here.

The X-Rate-Limit-Limit, X-Rate-Limit-Remaining, and X-Rate-Limit-Reset headers are set on every API response so that consumers can monitor their usage.

OverLimitException

When a rate limit is exceeded, an OverLimitException error is returned. A header (Retry-After) is also set with time remaining for the limit to reset.

Header example

Retry-After: 58

Headers

If a rate limit is applied to an API, with a successful JSON-RPC response, headers are set with rate limit information:

  • X-Rate-Limit-Limit: the rate limit period (eg. 1s, 1m, 12h, 1d)
  • X-Rate-Limit-Remaining: number of request remaining
  • X-Rate-Limit-Reset: UTC date time (ISO 8601) when the limit resets
Understanding tiers

Tiers refers to the number of tracked assets managed by a database. This includes only devices that have hardware reporting active data into MyGeotab including the Go Device, Go Anywhere, and Custom Telematics devices.

Tracked Assets on a Database
TierLower BoundUpper BoundMultiplier
101,000x1
21,00110,000x5
310,00125,000x15
425,001∞x25

The following public endpoints are excluded from tiered rate limits, and will always have a fixed base limit:

  • Authenticate
  • CreateDatabase
  • SetUserPassword
  • DeviceShare
Avoiding API rate limits

Use the MyGeotab API Adapter

The MyGeotab API Adapter solution serves as both an example of proper integration via data feeds and the potential foundation for those seeking to develop new integrations with the Geotab platform. Essentially, it uses data feeds to pull the most common data sets from a MyGeotab database and stream the data into tables within a SQL Server, PostgreSQL or Oracle database.

Read more about it here.

Get vs GetFeed

It is preferred to use GetFeed instead of a Get call for an entity which supports it.

Wait logic between calls

A straightforward solution can be introducing wait times between subsequent calls. It is suggested that ensuring at least 1010 milliseconds has elapsed between calls.

Handling rate limits

The general strategy for handling rate limits requires the integrator or partner to implement an error handler in code that recognizes rate limit errors and pauses requests until the limit resets. This will prevent your app from continuously trying to make requests once the rate limit is hit.

Using exponential backoff

Exponential Backoff is an essential error-handling strategy in network applications. In this method, a client will retry a failed request after waiting for an increasing amount of time before each retry.

When a request fails due to rate limiting, the client waits for a predetermined period before retrying the request. If the request fails again, the client waits longer for the next attempt, and this process continues up to a maximum delay limit. This approach helps to prevent frequent hits to the rate limit and reduces the load on the server.

JavaScript example implementation

Below is an example of how you might currently be making API calls:

To handle rate limits effectively, you can wrap your base function with exponential backoff logic. The following steps outline this process:

  1. Set the Maximum Number of Attempts
  2. Calculate the Exponential Delay
  3. Try the Call
  4. Catch the OverLimitException
  5. Wait for the Delay
  6. Repeat steps 1-5 until either the maximum number of attempts is reached, any other error is thrown, or results are successfully returned.

Here is an example implementation:

This function could be used within a try-catch block to handle any resultant errors: