> ## Documentation Index
> Fetch the complete documentation index at: https://docs.myme.so/llms.txt
> Use this file to discover all available pages before exploring further.

# Blobs

> Content-addressed binary storage — SHA-256 references, deduplication, and tiered backends

Binary content — images, PDFs, audio, video, arbitrary files — lives outside the item row. Items reference blobs by content hash; the bytes live in a pluggable backend.

## Content addressing

Every blob is identified by a SHA-256 hash of its bytes, serialised as `sha256:<hex>`. The same bytes always produce the same hash; storage deduplicates naturally. Two items carrying identical content share a single stored copy.

An item references blobs in two places:

* **Primary blob** — file types (`core.file`, `core.file.image`, `core.file.audio`, `core.file.video`) require a `blob_ref` on their `properties`. The item *is* the binary.
* **Attachments** — every item has an `attachments[]` array for secondary artefacts (a transcript on a video, a thumbnail, a readable HTML rendering of a bookmark). Each entry carries `blob_ref`, `mime_type`, optional `title`, and an optional `role`. See [Items — attachments](/concepts/items#attachments).

## Backends

Two storage backends, selected via `BLOB_BACKEND`:

* **`filesystem`** — blobs land under `BLOB_PATH` on local disk. Suitable for single-host self-hosts and development.
* **`s3`** — blobs land in an S3-compatible bucket. Required for horizontally-scaled deployments. Works with AWS S3, MinIO, Cloudflare R2, and other S3-compatible services via `S3_ENDPOINT`.

Switching backends is a migration, not a live swap — existing references continue to resolve only if the bytes are present in the active backend. See [Configuration](/self-hosting/configuration) for the full variable set.

## Upload and download

Full request shapes are in the [Blobs API reference](/api-reference/blobs/upload-a-blob). The flow:

1. Upload bytes via `POST /blobs` (multipart or raw octet-stream). Response carries the `hash`.
2. Write an item whose `properties` or `attachments[]` reference that `hash`.
3. Read back via `GET /blobs/{hash}` or follow the URL returned by the SDK's `blobs.url(hash)` helper.

Uploads are idempotent: re-uploading identical bytes returns the existing hash without re-storing. `HEAD /blobs/{hash}` checks existence cheaply.

## CDN rewrites

Setting `CDN_BASE_URL` rewrites blob URLs in API responses to a public CDN prefix — useful for serving images and other static assets without proxying them through the server. The SDK's `blobs.url(hash)` helper honours this automatically.

## Presigned URLs

S3 backends support `GET /blobs/{hash}/url`, which returns a time-limited presigned download URL (`ttl` query parameter, seconds; default 3600). Filesystem backends don't — the endpoint responds with `400` when called against a non-S3 backend.

## Lifecycle

Blobs outlive the items that reference them by default — the content-addressed model assumes reuse. Two admin-only jobs reconcile:

* **`POST /blobs/cleanup`** — removes blobs that no item references (including in trash). Supports `dry_run`.
* **`POST /blobs/reconcile`** — compares the storage backend against the database, surfacing orphans in both directions.

Blob upload limits are set by `MAX_BLOB_SIZE` (default 50 MB). Uploads beyond the limit return `413 blob_too_large`.
