Data Limits

For operations that involve batches of entities, Benchling has established limits on the amount of data that you can pull from, or push into, your tenant in a single request. Some common operations that involve data limits are bulk actions (e.g. :bulk-create), as well as list actions. The guidelines here cover the most common use case, but are not comprehensive; be sure to check out the description of the API(s) you're working with in our reference documentation for more details.

Pagination

Benchling paginates the results of all list endpoints, meaning that the response returned by these endpoints includes only a subset of the data that exists in your tenant (i.e. one "page"). Subsequent requests are made to get additional entities (i.e. the next "page"). The pageSize parameter is used to specify the number of entities returned from a specific endpoint; by default, this parameter is set to 50, and the maximum value for this parameter is 100.

Bulk Operations

A number of Benchling services support bulk operations, like :bulk-create and :bulk-update. While these operations are designed to support high throughput use cases, sufficiently large request bodies can result in timeouts or other issues. For bulk create operations specifically, we've imposed limits on the amount of data that can be included in a single request. For most :bulk-create endpoints, the limit is 1000 entities in a single request, though some specific services support larger limit sizes; the Bulk Create Custom Entities endpoint, for example, has a limit of 2500 entities per request. The limits for these endpoints can be found here:

Rate Limits

If you make a lot of API requests in a short amount of time, you may hit the tenant-wide API rate limit. By default, the rate limit is set to 60 requests per 30 seconds per tenant. Once the rate limit has been reached, Benchling will respond to further requests with a 429 โ€œToo Many Requestsโ€ response until the limit resets. Any requests met with this 429 error are not automatically queued for resubmission and must be called again.

Handling Rate Limits

When integrating with a rate-limited API, our recommended best practice is to write your code in a way that handles 429 HTTP status codes in an HTTP response. When the rate limit is exceeded, HTTP response bodies will look like the following:

{
  "error": {
    "message": "Rate limit exceeded.",
    "type": "invalid_request_error",
    "userMessage": "Rate limit exceeded."
  }
}

Additionally, each API response includes the following headers:

HeaderDescriptionExample
x-rate-limit-limitThe total number of requests allowed per period.60
x-rate-limit-remainingThe number of requests remaining per period.57
x-rate-limit-resetThe number of seconds remaining in the period.21

If you receive a 429 HTTP status code from the API, we recommend that you use an exponential backoff strategy to retry requests. This involves repeatedly retrying the request, with a backoff delay that increases exponentially with every retried request, until a maximum delay is reached. A small random constant is also added to the delay time each time in order to avoid situations in which clients are retrying many requests in an exactly synchronized way. In pseudocode, a simplified example to illustrate this strategy might look something like the following:

def safe_api_get(url):
    n = 1
    maximum_delay = 15

    while True:
        try:
            return api_get(url)
        except RateLimitExceededException:
            constant_factor = random_float_between(0, 1)
            delay_time = 2 ** n + constant_factor

            if delay_time > maximum_delay:
                delay_time = maximum_delay

            delay(delay_time)
            n += 1

How to Avoid Rate Limit Errors

As mentioned, Benchling imposes a tenant-wide API rate limit of 60 requests per 30 seconds. Oftentimes, this limit is reached when users try to perform certain types of bulk actions, such as creating hundreds of custom entities at once. When this occurs, users should identify where these calls are repetitively called, such as in various for and while loops. Where possible, these calls should be removed from those loops and a bulk endpoint should be leveraged instead. These differ from singular endpoints as they allow an array of inputs to be passed in a single API request rather than separate requests.

Examples of bulk vs singular endpoints include but are not limited to:

Singular EndpointBulk Endpoint
DNA Seq - CreatecreateDNASequencebulkCreateDNASequences
Custom Entities - CreatecreateCustomEntitybulkCreateCustomEntities
Custom Entities - UpdateupdateCustomEntitybulkUpdateCustomEntities
Container - CreatecreateContainerbulkCreateContainers

Example: Bulk Endpoints

In cases where you are looking to perform certain types of "bulk" actions, such as creating 1000 entities, you should use the bulk-create endpoint which makes 1 API call for an array of entities, rather than individual API calls for each entity.

When performing these types of repetitive actions, you should confirm whether there is an available bulk endpoint that can be leveraged.

def bulk_create(customEntitiesJSONList):
    bulkJSON = {"customEntities":[]}
    for entityJSON in customEntitiesJSONList:
        bulkJSON["customEntities"].append(entityJSON)
        if len(bulkJSON["customEntities"]) >= 100: # transact 100x entity-updates at a time
            bulkUpdateCustomEntity(json.dumps(bulkJSON)) # make the API request with the list of 100 Custom Entities held currently
            bulkJSON = {"customEntities":[]} # clear the Custom Entity array
    if len(bulkJSON["customEntities"]) > 0: 
        patchBulkCustomEntity(json.dumps(bulkJSON)) # make final update for any [1,100) entities leftover
    return

Using the pseudocode above, a user looking to create 1000 entities would only make 10 API calls, each call creating 100 entities at a time. In contrast, if a user used the singular create endpoint, they would make 1000 distinct API calls to accomplish the same task.

Increasing your rate limit

API rate limits are configurable, and can be increased by Benchling support ([email protected]) upon request.