Skip to content

Commit b06d428

Browse files
blog: native bucket inventory blog
Co-authored-by: Abhishek Gaikwad <gaikwadabhishek1997@gmail.com> Signed-off-by: Tony Chen <a122774007@gmail.com>
1 parent f2108d8 commit b06d428

2 files changed

Lines changed: 154 additions & 0 deletions

File tree

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
---
2+
layout: post
3+
title: "Native Bucket Inventory: Up to 17x Faster Remote Bucket Listing"
4+
date: Apr 6, 2026
5+
author: Tony Chen, Abhishek Gaikwad
6+
categories: aistore nbi benchmark optimization
7+
---
8+
9+
AIStore 4.3 introduces Native Bucket Inventory (NBI), a new mechanism for accelerating large remote-bucket listings by turning a repeatedly expensive operation into a local, reusable metadata path. Instead of traversing a remote bucket on every `ais ls`, AIS can precompute the bucket inventory once, persist it as compact binary chunks in the cluster, and answer subsequent listing requests directly from that local snapshot.
10+
11+
In our benchmarks, NBI delivers roughly **15x to 17x speedup** for repeated listing of an `s3://` bucket with 3.2 million objects, highlighting how effective a precomputed local snapshot can be for large datasets. In this post, we walk through the design of NBI, the internal create and list workflows, the benchmark results, and how to use it from the AIStore Python SDK and CLI.
12+
13+
### Table of Contents
14+
15+
- [Motivation](#motivation)
16+
- [Workflow](#workflow)
17+
- [Usage](#usage)
18+
- [Benchmark](#benchmark)
19+
- [Current Limitations](#current-limitations)
20+
- [When to Use NBI (and When Not To)](#when-to-use-nbi-and-when-not-to)
21+
- [Conclusion](#conclusion)
22+
- [References](#references)
23+
24+
## Motivation
25+
26+
Remote bucket listing becomes expensive when the bucket is both large and repeatedly accessed. A full listing requires AIS to retrieve and assemble a large volume of object metadata from the backend before it can return a complete result to the client. When that bucket is relatively stable and listed again and again, the system ends up redoing essentially the same work each time, even though the contents change very little between requests.
27+
28+
The core issue is that the object metadata returned by listing is often reusable, but the system keeps rebuilding it from scratch. The larger the bucket, the more bandwidth, latency, and backend API work AIS must spend to reconstruct information it has effectively already seen.
29+
30+
NBI addresses that mismatch by treating the bucket listing results as cacheable metadata. Instead of rebuilding the full listing on every request, AIS captures it once, stores it locally in a compact form, and reuses that snapshot for subsequent listings.
31+
32+
> While our benchmarks use S3, NBI is backend-agnostic and works identically with any remote backend — AWS S3, Google Cloud Storage, Azure Blob, OCI Object Storage, and remote AIS clusters.
33+
34+
## Workflow
35+
36+
NBI runs in two phases: **creation** and **listing**.
37+
38+
### Creation
39+
40+
When the user requests inventory creation, the [proxy](https://github.com/NVIDIA/aistore/blob/main/docs/terminology.md#proxy) distributes the job to all [targets](https://github.com/NVIDIA/aistore/blob/main/docs/terminology.md#target). Each target independently walks the [remote backend](https://github.com/NVIDIA/aistore/blob/main/docs/providers.md), but only keeps the entries whose names hash to that target. The entries are sorted, grouped into chunks of ~20K names each, encoded as compressed `msgpack`, and written to the AIS system bucket `ais://.sys-inventory`. The resulting object path follows the pattern `{provider}/@#/{bucket}/inv-{uuid}`.
41+
42+
43+
### Listing
44+
45+
When a list request carries the inventory flag, the proxy broadcasts to all targets instead of sending the request to the remote backend. Each target reads its local inventory chunks, binary-searches for the continuation token, and returns a page of entries. The proxy merges per-target pages to assemble a globally sorted result. No S3 calls are made.
46+
47+
## Usage
48+
49+
### Python SDK
50+
51+
```python
52+
from aistore import Client
53+
54+
client = Client("http://ais-endpoint:51080")
55+
bck = client.bucket("my-bucket", provider="s3")
56+
57+
# Create the inventory (one time)
58+
job_id = bck.create_inventory(name="trainset-v1", prefix="images/")
59+
client.job(job_id).wait()
60+
61+
# List via inventory — no S3 calls made
62+
page = bck.list_objects(inventory_name="trainset-v1", prefix="images/train/")
63+
for entry in page.entries:
64+
print(entry.name)
65+
66+
# Clean up when no longer needed
67+
bck.destroy_inventory(name="trainset-v1")
68+
```
69+
70+
### CLI
71+
72+
```console
73+
# Create inventory
74+
$ ais nbi create s3://my-bucket
75+
76+
# Monitor creation
77+
$ ais show job create-inventory
78+
79+
# Show inventory metadata
80+
$ ais nbi show s3://my-bucket
81+
82+
# List via inventory
83+
$ ais ls s3://my-bucket --inventory
84+
$ ais ls s3://my-bucket --inventory --prefix images/train/
85+
86+
# Destroy inventory
87+
$ ais nbi rm s3://my-bucket
88+
```
89+
90+
## Benchmark
91+
92+
We measured listing latency across 15 scale points from 1K to 3.2M objects in an `s3://` bucket, with 3 runs per point. The chart below shows p50 latency for AIS regular listing, S3 direct (boto3), NBI creation (one-time), and NBI listing.
93+
94+
![NBI benchmark result](/assets/nbi/nbi_scale.png)
95+
96+
```
97+
==========================================================================================================================
98+
NBI latency-vs-scale (3 runs each)
99+
==========================================================================================================================
100+
Objects Creation Regular NBI S3 Direct Speedup
101+
p50 sd p50 sd p50 sd (R/N)
102+
--------------------------------------------------------------------------
103+
1K 449ms 405ms 144ms 21ms 2ms 676ms 2.9s 19.0x
104+
2K 616ms 596ms 21ms 34ms 4ms 480ms 251ms 17.6x
105+
5K 811ms 1.2s 161ms 51ms 33ms 1.4s 186ms 22.4x
106+
10K 1.8s 1.9s 177ms 147ms 35ms 2.7s 165ms 12.6x
107+
20K 3.5s 3.4s 106ms 248ms 20ms 6.2s 154ms 13.8x
108+
40K 7.2s 7.2s 358ms 550ms 95ms 10.8s 278ms 13.2x
109+
50K 8.6s 8.8s 689ms 631ms 30ms 12.9s 242ms 13.9x
110+
80K 13.9s 13.8s 1.1s 1.0s 22ms 21.4s 995ms 13.2x
111+
100K 17.0s 17.9s 387ms 1.4s 45ms 27.3s 822ms 12.6x
112+
200K 31.8s 37.6s 2.1s 2.9s 225ms 53.8s 6.6s 13.1x
113+
400K 1m 5s 1m 16s 364ms 6.3s 698ms 1m 50s 4.8s 12.3x
114+
600K 1m 43s 2m 0s 1.8s 9.1s 276ms 2m 39s 3.5s 13.3x
115+
800K 2m 10s 2m 46s 2.2s 12.5s 939ms 3m 43s 901ms 13.4x
116+
1M 2m 42s 3m 38s 920ms 16.4s 213ms 4m 42s 10.7s 13.3x
117+
3.2M 8m 34s 16m 55s 4.3s 1m 0s 2.8s 14m 46s 23.1s 16.9x
118+
==========================================================================================================================
119+
```
120+
121+
NBI listing latency still increases with object count because it scans locally stored inventory data, but its absolute latency remains far lower than regular listing. On the chart, the NBI curve appears almost flat compared to a regular AIS list or a direct S3 list. The speedup remains consistent across the entire 1K-3.2M range, reaching up to **16.9x** at 3.2M objects.
122+
123+
## Current Limitations
124+
125+
NBI is **experimental** in AIStore 4.3, and the current implementation keeps inventory management intentionally simple. At the moment, AIStore supports only one inventory per bucket, so concurrent inventories for the same bucket are not supported. Inventories are created manually via CLI or SDK and remain static until they are recreated or removed; if an inventory already exists and you want a new one, you can recreate it with `--force`, or simply remove it first with `ais nbi rm` and then create it again.
126+
127+
The current creation path is also optimized for correctness and simplicity rather than minimum backend work. During inventory creation, all targets walk the remote bucket in parallel and each keeps only its own portion of the results. Automatic refresh and more efficient creation strategies are planned for future releases.
128+
129+
> **Note:** NBI replaces the older S3-specific `--s3-inventory` path, which depended on provider-generated CSV/Parquet inventory files. The new implementation is AIS-native, backend-agnostic, and does not require external tooling.
130+
131+
## When to Use NBI (and When Not To)
132+
133+
**Good fit:**
134+
135+
- Large remote buckets (100K+ objects) that are listed repeatedly
136+
- Training pipelines that enumerate a dataset before each epoch
137+
- Data audits or dashboards that scan bucket contents periodically
138+
- Any workflow where the bucket is relatively stable between listings
139+
140+
**Not a good fit:**
141+
142+
- Small buckets — creation cost exceeds the listing savings
143+
- Rapidly changing buckets — the snapshot goes stale quickly, and frequent recreation negates the benefit
144+
- `ais://` buckets — metadata is already local (to each _listing_ target), so NBI provides no speedup
145+
- One-off listings — if you only list a bucket once, the creation overhead is pure cost
146+
147+
## Conclusion
148+
149+
NBI delivers **15x better listing performance** for large remote buckets, with measured speedups reaching **14-22x** across the range we tested. That makes it a practical solution for repeated listing of multi-million-object `s3://`, `gs://`, and other remote buckets where rebuilding the full result from the backend on every request is too slow and too expensive.
150+
151+
## References
152+
153+
- [NBI documentation](https://github.com/NVIDIA/aistore/blob/main/docs/nbi.md)
154+
- [NBI benchmark script](https://github.com/NVIDIA/aistore/blob/main/python/tests/perf/nbi/bench.py)

docs/assets/nbi/nbi_scale.png

-41.7 KB
Loading

0 commit comments

Comments
 (0)