Home / Storage
Bluesky / AT Protocol PDS — 5 MiB blob default, GC'd unless referenced
github.com/bluesky-social/atproto/blob/main/packages/pds/srcAtproto pdsstorage/bluesky-at-protocol-pds-5-mib-blob-default-gc-d-unless-rJSONcomparereport an errorprovider JSON
- Free allowance
- BlobUploadLimit defaults to 5 * 1024 * 1024 = 5 MiB per blob, overridable per-PDS via the BLOB_UPLOAD_LIMIT env var.
- Verdict
- fails: quotathe free allowance is too small to matter
- Cost
- free tier
- Identity
- email?placeholder, not evidence; card unknown, phone unknown
- Binding limit
- per-object-cap5 MiB per blob
- Evidence
- reported2 sources; a third party said so
- Freshness
- stale on 2026-11-05checked 2026-10-21 (inherited); stale on 2026-11-05
| Free tier | blobUploadLimit defaults to 5 * 1024 * 1024 = 5 MiB per blob, overridable per-PDS via the BLOB_UPLOAD_LIMIT env var. Per-account: bsky.app's hosted PDS is generous in practice but the protocol layer only guarantees blobs that are REFERENCED by a record. unit mixed; metered on unstated |
|---|
| Price | none stated |
|---|
| Limits | - per-object-cap (binding) 5 MiB per blob source
per-object-cap 5 MiB default (config.ts: blobUploadLimit: env.blobUploadLimit ?? 5 * 1024 * 1024); blobs unreferenced within a time window (minutes) are deleted; account-level repo size limits are enforced by the AppView/PDS separately. |
|---|
| Identity | email (placeholder) not published |
|---|
| Egress | Free on bsky.app's PDS and on any self-hosted PDS (it serves blobs directly from /xrpc/com.atproto.sync.getBlob). No egress meter. |
|---|
| Per-object cap | 5 MiB per blob (5242880 bytes) |
|---|
| Retention | not stated |
|---|
| Interface | cli http-xrpc |
|---|
| Tooling | XRPC: POST /xrpc/com.atproto.repo.uploadBlob (binary body + Content-Type) -> returns a blob ref; must then be referenced by a record (e.g. app.bsky.feed.post embed) or it is garbage-collected. Client libs: @atproto/api, atproto Python SDK, goat CLI. |
|---|
| Composes with | Self-hosting a PDS removes the 5 MiB default (it is a config value), so a self-hosted PDS is bounded by YOUR disk, not Bluesky's — that makes it a hosting product, not free storage. On bsky.app's PDS the 5 MiB cap plus the reference requirement makes it useless for bulk. The usable margin is only the 'unreferenced blobs are deleted within minutes' semantics working in reverse: referenced blobs are retained indefinitely. |
|---|
| Reliability | Blob GC is literal and fast — an upload without a referencing record vanishes. That is the single most important fact about this candidate. |
|---|
| Parsed numbers | - has-free-tier 1
- per-object-cap 5 MiB
|
|---|
Evidence 2
More fields 2
| unit note | free_tier.unit is 'mixed' because the headline is denominated in MiB or KiB, which the schema enum does not carry; the verbatim free_tier.stated keeps the true unit. |
|---|
| dead end | {"failure_class": "quota","why": "blobUploadLimit defaults to 5 * 1024 * 1024 = 5 MiB per blob, overridable per-PDS via the BLOB_UPLOAD_LIMIT env var. Per-account: bsky.app's hosted PDS is generous in practice but the protocol layer only guarantees blobs that are REFERENCED by a record.","retry_when": null,"first_recorded": "2026-10-21"} |
|---|
Unknown values 3
- per object cap notes: the field may be stated in a source that was not read
- retention notes: the field may be stated in a source that was not read
- retention stated: the field may be stated in a source that was not read