
The AIOZ Storage rate limit is 100 requests per second, and one line on the Usage Limit page is all AIOZ publishes about it. The docs do not say what the limit is measured against, which calls count toward it, or what a rejected request looks like. Below I mark what is documented and what is not, work out what 100 requests per second means for a real upload job, and show two client-side measures that do not depend on the unknown parts: boto3 retries, and a small limiter I tested locally.
TL;DR:
legacy retry mode with 5 attempts. It retries HTTP 429, 500, 502, 503, 504 and 509. standard mode retries SlowDown and 500, 502, 503 and 504, but not 429, so switching modes can lose coverage.AIOZ Storage's Usage Limit page lists three defaults: 100 buckets per account, 100 sub-users per account, and a rate limit of 100 requests per second. The page gives one reason for them, a uniform quality of service across all customers on AIOZ Storage.

The documented part is short. Two of the three bullets say "per account". The third, the request limit, has no scope attached. I searched the full AIOZ Storage docs set (all 46 pages in llms-full.txt) and found no other mention of the rate limit, so these details are unknown:
Retry-After header is sent.If every object is one request and the limit applies to your whole account, 10,000 small uploads take at least 100 seconds, and 1,000,000 take at least 10,000 seconds, about 2 hours and 47 minutes. Adding threads does not shorten that. It only gets you to the cap faster.
AWS documents a different shape. Amazon S3 can achieve at least 3,500 PUT, COPY, POST or DELETE requests, or 5,500 GET or HEAD requests, per second per partitioned prefix, scales gradually, and may return 503 (Slow Down) errors while it scales. AWS's figure is per prefix and grows. AIOZ's is a single number with its scope unstated, so size your jobs against 100 until AIOZ says more. If you control how files are laid out, fewer, larger objects mean fewer requests. Splitting a big file with multipart upload goes the other way, because each part is a separate upload call. AIOZ does not say whether parts count toward the limit the same way as whole-object uploads.
By default a boto3 client uses legacy retry mode with 5 attempts, counting the first request. The boto3 guide lists what each mode retries, and the two lists differ in a way that matters here:
legacy (default) | standard | |
|---|---|---|
| Default attempts | 5, including the first request | 3, including the first request |
| HTTP status codes retried | 429, 500, 502, 503, 504, 509 | 500, 502, 503, 504 |
| Throttling error codes retried | Throttling, ThrottlingException, ThrottledException, RequestThrottledException, ProvisionedThroughputExceededException | Those, plus TooManyRequestsException, RequestLimitExceeded, BandwidthLimitExceeded, LimitExceededException, RequestThrottled, SlowDown and others |
| Backoff | Exponential, base factor 2 | Exponential, base factor 2, capped at 20 seconds |
So standard is not a strict upgrade. It recognizes SlowDown, which is what Amazon S3 sends, but it drops 429 and 509 from the status list. If AIOZ answers an over-limit request with a bare HTTP 429 and an error code botocore does not know, legacy retries it and standard may not. If AIOZ sends SlowDown or a 503, standard retries it, and legacy retries the 503 only. I cannot tell you which case applies, because AIOZ does not document the response.
Set the mode and attempt count on purpose, and keep it simple:
import boto3
from botocore.config import Config
s3 = boto3.client(
"s3",
region_name="us-east-1",
aws_access_key_id="YOUR_ACCESS_KEY_ID",
aws_secret_access_key="YOUR_SECRET_ACCESS_KEY",
endpoint_url="AIOZ_STORAGE_ENDPOINT_URL",
config=Config(
retries={"mode": "legacy", "total_max_attempts": 5},
request_checksum_calculation="when_required",
response_checksum_validation="when_required",
s3={"addressing_style": "path"},
),
)The two when_required settings are there because AIOZ Storage needs a Content-Length header on uploads. Since 1.36.0, boto3 otherwise sends uploads chunked without one (see AWS's data integrity settings and the botocore Config reference). Path-style URLs are required too, because bucket subdomains don't resolve. We confirmed both on Oct 19, 2026; a full upload with real keys is not tested yet.
The region and path-style addressing follow AIOZ's own Python SDK example. total_max_attempts includes the first request, while max_attempts in a Config object counts retries only, so the two names are not interchangeable. Swap "legacy" for "standard" only after your logs (see below) show a code that standard handles and legacy does not. The adaptive mode adds client-side rate limiting, but the boto3 guide calls it experimental and subject to change.
Retries react after a request is rejected. A limiter stops you from sending too many in the first place, and it works whatever AIOZ returns. This one allows at most rate calls in any rolling second and is safe to share between threads:
import threading
import time
from collections import deque
class RateLimiter:
"""Allow at most `rate` calls in any rolling one-second window."""
def __init__(self, rate):
self.rate = rate
self.calls = deque()
self.lock = threading.Lock()
def wait(self):
while True:
with self.lock:
now = time.monotonic()
while self.calls and now - self.calls[0] >= 1.0:
self.calls.popleft()
if len(self.calls) < self.rate:
self.calls.append(now)
return
pause = 1.0 - (now - self.calls[0])
time.sleep(pause)
limiter = RateLimiter(80)
def upload(key):
limiter.wait()
s3.put_object(Bucket="YOUR_BUCKET_NAME", Key=key, Body=b"example")Call upload from a ThreadPoolExecutor and the limiter spaces the calls out. I chose 80 as a margin, not because AIOZ says so. Two things make a margin necessary. The limiter cannot see boto3's own retries, and every retry is another request on top of your count. And there is a gap between admitting a call and the request reaching the network.
I tested the limiter with 400 no-op calls at a limit of 80 per second. Measured on the limiter's own admission times, the busiest rolling second held exactly 80 calls with 1, 8 and 32 threads. Measured from timestamps taken by the callers afterwards, the 32-thread run once showed 81, which is that scheduling gap. This was a local test, not a test against AIOZ.
When you retry yourself, add jitter. Marc Brooker's post on the AWS Architecture Blog (4 March 2015) shows that plain exponential backoff still leaves clusters of calls, and that adding random jitter to the sleep spreads them out. He calls jittered backoff "a standard approach for remote clients". If boto3's built-in retries already cover the errors you see, you do not need your own loop. For comparison, AIOZ Stream documents its limits and response headers in Handling API Rate Limits in Production.
Since the response to an over-limit request is undocumented, record it when it happens. Do not try to overload the service on purpose. Just log any throttling-like failure you meet:
from botocore.exceptions import ClientError
try:
s3.put_object(Bucket="YOUR_BUCKET_NAME", Key="a.txt", Body=b"data")
except ClientError as error:
meta = error.response["ResponseMetadata"]
retry_after = meta.get("HTTPHeaders", {}).get("retry-after")
print(meta["HTTPStatusCode"], error.response["Error"]["Code"], retry_after)If you see a consistent status, error code or Retry-After value, send it to AIOZ and ask for it to be documented. That answer tells you which retry mode, if either, covers it.
What is the AIOZ Storage rate limit?
The Usage Limit page states a default rate limit of 100 requests per second, alongside 100 buckets and 100 sub-users per account.
Is the 100 requests per second limit per account?
The docs do not say. The bucket and sub-user limits are stated per account, but the request limit has no scope attached.
What error does AIOZ Storage return when I exceed the limit?
It is not documented. Log the HTTP status, the error code and any Retry-After header you see, and do not assume a 503 or a 429.
Does boto3 retry throttled requests automatically?
Yes, in both modes, but for different signals. The default legacy mode retries HTTP 429, 500, 502, 503, 504 and 509. standard retries SlowDown and other throttling codes plus 500, 502, 503 and 504. Whether either covers AIOZ's over-limit response is unknown.
Can I raise the limit?
The docs say the values are set by default and describe no way to change them. Ask AIOZ if your workload needs more.
How long does it take to upload a million small files?
At least 10,000 seconds, about 2 hours and 47 minutes, if each file is one request and the limit covers your whole account.

Create a bucket and upload a file on AIOZ Storage in five steps: sign up, set a passphrase, add credits, and upload. Plus what the passphrase cannot recover.

The AIOZ Storage rate limit is 100 requests per second. See what the docs do and don't say, and how to stay under it with boto3 retries and a limiter.

AIOZ Storage erasure coding splits each object into pieces on DePIN nodes, so it survives node loss. See what it covers, what it doesn't, and what to back up.

Rename a file in an S3 bucket on AIOZ Storage from the dashboard, then move, delete and download files, and see which actions the docs say are not supported.

AIOZ Storage publishes llms.txt, a 46-link docs index, and llms-full.txt, all docs in one 164 KB file. See what each file contains and when to use which.

Vector database vs agent memory on AIOZ Storage: use the vector database for control over embeddings and metadata, Memory for simple Record and Recall calls.