Docs
Get Started

Rate limits

Today

There is currently no rate limit on the Storage Buckets API. A request is not refused because you sent too many in a given time, either per account or per credential.

That does not mean a request cannot fail. Storage can fail to finish a request, and the API answers 502 when that happens. Your code should be ready for it.

What your code should do

Retry only the failures that can go away on their own, and wait a little longer before each try.

Status What to do
502 Wait, then try again. Double the wait each time, for example 1, 2, 4, and 8 seconds, and give up after about five tries.
429 or 503 If you ever get one of these, treat it the same way as 502.
400, 401, 402, 403, 404, or 411 Do not retry. The same request will get the same answer. Fix the request first. See Errors and troubleshooting.

Also retry when the connection fails before you get any answer, with the same growing wait.

Before you repeat a request, know what a repeat does:

  • Reading, getting details, listing, and deleting a file are safe to repeat. Deleting a file that is already gone answers 204 again.
  • Uploading a file again replaces it, and the new file is private. If it was public, make it public again.
  • If you retry Create a bucket and it answers You already have a bucket with this name., the first try may have worked. Call List buckets to find the identifier.

When you upload or delete many files, send them a few at a time rather than all at once.

This code reads your buckets and retries up to five times:

Python
import os
import time
 
import requests
 
AUTH = (os.environ["KUBERNS_ACCESS_KEY_ID"], os.environ["KUBERNS_SECRET"])
RETRY_STATUSES = {429, 502, 503}
 
 
def get_with_retry(url, attempts=5):
    delay = 1
    for attempt in range(1, attempts + 1):
        response = requests.get(url, auth=AUTH)
        if response.status_code not in RETRY_STATUSES or attempt == attempts:
            return response
        time.sleep(delay)
        delay *= 2
 
 
response = get_with_retry("https://gateway.kuberns.cloud/buckets")
response.raise_for_status()
 
print(response.json()["data"]["summary"]["bucket_count"])
JavaScript
const credentials = Buffer.from(
  `${process.env.KUBERNS_ACCESS_KEY_ID}:${process.env.KUBERNS_SECRET}`
).toString("base64");
 
const RETRY_STATUSES = [429, 502, 503];
 
async function getWithRetry(url, attempts = 5) {
  let delay = 1000;
  for (let attempt = 1; ; attempt++) {
    const response = await fetch(url, {
      headers: { Authorization: `Basic ${credentials}` },
    });
    if (!RETRY_STATUSES.includes(response.status) || attempt === attempts) {
      return response;
    }
    await new Promise((resolve) => setTimeout(resolve, delay));
    delay *= 2;
  }
}
 
const response = await getWithRetry("https://gateway.kuberns.cloud/buckets");
if (!response.ok) {
  throw new Error(`List buckets failed with status ${response.status}`);
}
const body = await response.json();
 
console.log(body.data.summary.bucket_count);

If this changes

If a rate limit is introduced, it will be described on this page, and the change will be listed in the Changelog.