Developer Best Practices for Dealing with Rate Limits
Strategies for avoiding common errors
With the addition of rate limits to the Evernote API, we feel it’s important to point out to our developer partners several best practices for using the Evernote API in such a way that exceeding the rate limit is rare and, if they do, the situation is handled properly.
The purpose of this document is to describe common pitfalls that will likely lead to exceeding the rate limit and best practices for avoiding them.
Note: some integrations synchronize all (or most) of a user’s data. These integrations are referred to as “sync clients” and are especially prone to exceeding the Evernote API rate limit. We’ve added a new feature to the API called Initial Sync Boost (more info here) to help sync clients stay under the rate limit.
Rate limits: Developer best practices
Checking for changes appropriately
Before requesting data from a user’s account, it’s a good idea to see if anything has changed since your last API request. This can be done using NoteStore.getSyncState
, which returns a numeric value indicating the total number of transactions that have taken place in a given user’s account:
Each time your integration makes a call to this API, store the value locally and compare it to the last value returned. If the values are the same, no changes have occurred within the user’s account since your last call to getSyncState
. This knowledge will save your application from making unnecessary API calls (assuming you’re caching data appropriately, which we’ll describe in a moment).
Of course, calling NoteStore.getSyncState
too frequently will increase the likelihood of your integration exceeding the rate limit. Avoid calling this API more often than is needed for your integration to function properly. If your integration is a web service, we recommend using webhooks to be notified of account changes rather than calling NoteStore.getSyncState
.
Caching frequently-needed data
Certain types of data within a given Evernote account are less likely to change than others and can be cached in many instances. Data like notebook names and GUIDs, tag names and GUIDs, note thumbnails and even note content can and should be cached locally instead of repeatedly requesting the same data from the API.
Using the Note.tagNames
field when creating or updating notes
When adding tags to a new or existing note, use the Note.tagNames
field instead of calling NoteStore.listTags
to see if a given tag already exists. For each tag included in the tagNames
collection, the Evernote service will automatically create any tags that don’t already exist in the user’s account and apply any existing tags listed in tagNames
.
Handling a rate limit exception
Despite your best efforts to avoid them, situations may arise in which a user of your integration exceeds the API rate limit. When this happens, an exception of type EDAMSystemException
will be thrown by the API containing the RATE_LIMIT_REACHED
error code. Two things must then occur:
- The application should handle the exception gracefully (i.e., not crash). More detail about how to do that can be found here.
- The user must be notified of the situation. Most normal users won’t understand what a “rate limit” is, so it’s important to convey the information clearly so the user understands that the application isn’t irreparably broken and that they’ll be able to retry soon. Some example messages might be:
“{App} has made too many Evernote requests. Your data has been saved on your (device/computer) and will be (sent/received) in (human-readable version of rateLimitDuration).”
“Evernote usage has been temporarily exceeded. Please try again in (human-readable version of rateLimitDuration)”.