Skip to content

Bundles

Bundles pack many small files into a single Walrus blob (a Walrus Quilt) instead of writing each file separately. One on-chain transaction covers the whole batch — gas drops by up to ~238× and per-byte storage cost drops by up to ~400× on small files. Individual files remain independently readable.

There are two modes. You don’t choose between them directly — they’re selected by plan and upload method.

ModeWho uses itTriggerTiming
PPU batchPay-per-upload users”Bundle files” toggle in the upload UI (or SDK batch endpoints)Quilt built immediately on confirm
Subscription auto-batchingDeveloper / Scale / EnterpriseAutomatic for files under 10 MBFlushed when total pending ≥ 100 MB or oldest pending > 1 hour

Files ≥ 10 MB always go through the single-file Walrus sync path; they get less benefit from batching and don’t have to wait for flush.

When a PPU user selects 2+ files in the web uploader, the Bundle files toggle appears. It defaults to on.

With bundling on:

  • One aggregated cost quote instead of one per file
  • One Sui payment covers all files in the batch
  • Files are uploaded to the hot cache in parallel via presigned URLs
  • A single walrus-quilt-sync job writes the quilt after confirm

With bundling off, each file goes through the normal single-file PPU flow (one quote, one payment, one Walrus write per file).

Bundles work for both public and SEAL-encrypted shared vaults. Each file is SEAL-encrypted client-side with its own nonce before being added to the batch — the quilt just happens to contain ciphertext blobs. Encryption and bundling are independent.

If you’re building your own client, the PPU batch flow uses two endpoints instead of /api/files/upload + /api/files/:id/confirm:

Terminal window
# 1. Request batch quote / presigned URLs
POST /api/files/batch-upload
{
"vaultId": "<vault-uuid>",
"epochs": 5,
"files": [
{ "name": "a.txt", "mimeType": "text/plain", "sizeBytes": 1200 },
{ "name": "b.txt", "mimeType": "text/plain", "sizeBytes": 3400 }
]
}
# First call returns 402 with a single quote covering the whole batch.
# Retry the same request with { quoteId, txDigest } after paying.
# Successful response: { quiltId, files: [{ fileId, uploadUrl, spacesKey, name }, ...] }
# 2. PUT each file to its uploadUrl in parallel.
# 3. Confirm the batch as a whole
POST /api/files/batch-confirm
{ "quiltId": "<quilt-uuid>" }

Subscription users don’t see bundles as a setting. Files under 10 MB are marked as pending quilting when confirmed. A flush job runs every 5 minutes and creates a quilt when either condition holds:

  • total pending size ≥ 100 MB, or
  • oldest pending file > 1 hour old

Files from different users can share a quilt — they’re already encrypted client-side for shared vaults, so there’s no privacy impact. Quilts are grouped by epoch duration so every file in a quilt shares one expiry.

Quilts are a Walrus protocol feature, and inherit its limits:

LimitValue
Max files per quilt666
Max quilt size~100 MB
MutabilityImmutable — individual files can’t be removed, extended, or renewed separately
Per-file identifierQuiltPatchId (not the usual BlobId)

On the files record, quilted files have walrusBlobId / walrusBlobObjectId null. Instead, look at:

  • quiltId — which quilt the file belongs to
  • quiltPatchId — patch identifier within the quilt, used to read the file
  • the parent quilts record — holds the actual walrusBlobId and walrusBlobObjectId used for the whole batch’s epoch renewals

Downloads work the same: the API looks up the patch automatically, so GET /api/files/:id/download and opentusk download <file-id> behave identically to single-blob files.

Epoch renewal is quilt-level, not file-level. At renewal time:

  • All files still active — the quilt is renewed with extendBlob.
  • Some files cancelled or expired — active files are pulled back into the pending pool and re-quilted into a new batch; the old quilt is allowed to expire.
  • All files cancelled — the quilt expires.

Non-quilted files continue to renew individually.

ComponentSingle-fileQuilt batch
Walrus write feeN × per-file1 × on total size
Walrus storageN × per-file overhead1 × aggregate
Sui gasN × ~0.005 SUI1 × ~0.005 SUI
Platform marginper-fileapplied once on batch total

For PPU users, the saving is reflected directly in the 402 quote. For subscription users, there is no user-facing price change — the platform absorbs the Walrus/gas savings.