API
Blobs
Blobs store opaque bytes in Layer’s S3 bucket and serve them through the
gateway with Aerospike as a pull-through hot cache. A row never stores the
bytes themselves. It stores an ordinary string attribute such as
image_blob: "blob://products/<sha256>".
Use blobs for media or other binary payloads that must have a durable home outside the vector engine while still riding the gateway read path.
Routes
| Route | Method | Behavior |
|---|---|---|
PUT /v1/namespaces/{ns}/blobs | PUT | Store raw bytes by sha256 and return a blob:// reference. |
GET /v1/namespaces/{ns}/blobs/{sha256} | GET | Serve bytes from Aerospike raw cache, falling back to S3 and backfilling cache. |
Store
with open("image.jpg", "rb") as f:
stored = await client.put_blob("products", f.read())
print(stored.ref)body, _ := os.ReadFile("image.jpg")
stored, err := client.PutBlob(ctx, "products", body, nil)import fs from "node:fs/promises";
const bytes = await fs.readFile("image.jpg");
const stored = await client.putBlob("products", bytes);curl -X PUT "$LAYER_GATEWAY_URL/v1/namespaces/products/blobs" \
-H "Authorization: Bearer $LAYER_GATEWAY_API_KEY" \
-H "Content-Type: application/octet-stream" \
--data-binary @image.jpg Response:
{
"ref": "blob://products/9f86d081884c7d659a2feaa0c55ad015...",
"sha256": "9f86d081884c7d659a2feaa0c55ad015...",
"size": 48213
}
The same bytes always return the same reference. The route rejects empty bodies and bodies over the gateway’s blob size cap.
Write the returned ref as a normal row attribute:
{
"id": "B0123",
"vector": [0.1, 0.2],
"image_blob": "blob://products/9f86d081884c7d659a2feaa0c55ad015..."
}
The removed document blobs payload shape is still rejected. Binary bytes
do not traverse /v2/namespaces/{ns} writes.
Fetch
image = await client.get_blob("products", stored.sha256)image, err := client.GetBlob(ctx, "products", stored.Sha256)const image = await client.getBlob("products", stored.sha256);curl "$LAYER_GATEWAY_URL/v1/namespaces/products/blobs/$SHA256" \
-H "Authorization: Bearer $LAYER_GATEWAY_API_KEY" \
-o image.jpg Successful responses include immutable cache headers:
Cache-Control: public, max-age=31536000, immutable
ETag: "<sha256>"
The gateway sniffs common image types (jpeg, png, gif, webp) for
Content-Type; otherwise it returns application/octet-stream.
Warm Policy
Blob reads pull through from S3 on a cache miss, then backfill Aerospike
best-effort. PUT ...?warm=true writes one object through to cache.
For bulk warming, declare the row attributes containing blob references in the
Index’s spec.blobs.referenceAttributes, then call hint_cache_warm with
blobs=true and a positive blob_budget_bytes:
spec:
blobs:
referenceAttributes: [image_blob]
curl "$LAYER_GATEWAY_URL/v1/namespaces/products/hint_cache_warm?turbopuffer=false&documents=false&snapshots=false&blobs=true&blob_budget_bytes=104857600" \
-H "Authorization: Bearer $LAYER_GATEWAY_API_KEY"
This example warms only blobs, up to 100 MiB of cached bytes. The gateway scans
origin rows, follows same-namespace references in the declared attributes
(strings or arrays), and deduplicates objects. It stops before caching the first
object that would exceed the budget; the response reports blobs.budget_exhausted.
The budget bounds bytes written to cache, not S3 transfer: concurrent reads may
fetch beyond the cutoff. Missing objects and invalid references are counted and
skipped. See Warm cache for SDK examples and
response fields.