ttl.sh
ttl.sh · Storage · 1 record · JSON
ttl.sh (anonymous ephemeral OCI registry) Storage
caveatanonymousno cardRper-ip-shaping
| Free tier | No account, no quota. "Free forever. Zero sign-up. Push any OCI artifact with a TTL." Storage is bounded only by the TTL, max advertised 24 hours. unit unlimited; metered on stored-bytes |
|---|---|
| Price | none stated |
| Per-object cap | not stated |
| Retention | not stated |
| Egress | Unmetered and anonymous: blobs are 307-redirected to a presigned S3 URL (s3.us-east-1.storage.sh, X-Amz-Expires=1200), so bytes come off object storage, not the registry host. Range requests work. |
| Identity | anonymous derived from the record's prose, not from an identity field, and no signup was executed: No account, no quota. "Free forever. Zero sign-up. Push any OCI artifact with a TTL." Storage is bounded only by the TTL, max adve |
| Limits |
TTL max 24h advertised (:5m/:1h/:6h/:24h), default 1h. No per-blob size cap found: I pushed 256MB and then 1.5GB monolithically with zero chunking and both were accepted (202 then 201). Upload is slow (~11 MB/s observed: 1.5GB in 2m11s), so throughput is the practical per-connection cap. _catalog is blocked by nginx (401), tags/list is open. |
| Binding | per-ip-shaping one stream is shaped, and a user's throughput is the shaped rate times the number of streams |
| Interface | s3-compatible, oci oci |
| Tooling | Any distribution-spec client: oras, docker, skopeo, crane, regctl. Built on zot (per the repo: 'Zot runs an off-the-shelf image ghcr.io/project-zot/zot-linux-amd64 ... points zot at an S3-compatible bucket'). |
| Composes with | Unlimited anonymous identities x unlimited repos x unlimited blobs. Because there is no account at all, repo names are the only namespace; rate-limiting is per-IP only, so N egress IPs = N x throughput. Effectively an unlimited free write/read buffer that garbage-collects itself. |
| Reliability | Expiry is best-effort: the deployment repo states 'Tag expiry is handled separately and is not yet wired up in this repo', and open issue #151 reports images not expiring. Data WILL vanish at TTL; do not treat as durable. Intermittent connect timeouts observed from this network. |
| Notes | No account, no quota. "Free forever. Zero sign-up. Push any OCI artifact with a TTL." Storage is bounded only by the TTL, max advertised 24 hours. |
| Evidence rung | reported One page read moves it to documented. |
| Checked | 2026-10-21 (inherited); stale on 2026-11-04 |
| Parsed numbers |
|
Evidence (6)
| date | source | what it proved |
|---|---|---|
| 2026-10-21 | ttl.sh/ | read live: 'Free forever. Zero sign-up. Push any OCI artifact with a TTL. No auth, no config, no account.'; 'Choose your TTL. Default is 1 hour, max is 24 hours.' |
| 2026-10-21 | ttl.sh/v2/probe<rand>/blobs/uploads/ | probe: POST -> 202 Accepted with Location header, no credentials of any kind |
| 2026-10-21 | withheld | probe: PATCH .../blobs/uploads/<uuid> with 256MiB random -> 202, Range: 0-1048575; then PUT ?digest=sha256:... -> 201 Created; PUT /v2/probe4941/manifests/24h -> 201; GET /v2/probe4941/manifests/24h -> 200 returning the exact manifest |
| 2026-10-21 | withheld | probe: 1.5GB anonymous upload -> HTTP/1.1 202 Accepted, Range: 0-1499999999, then commit PUT -> 201 Created, digest sha256:1c5954e1c91f... (no 413, no chunking needed) |
| 2026-10-21 | s3.us-east-1.storage.sh/ttlsh-registry-data/...?X-Amz-Expire | probe: GET blob -> 307 to (presigned, CF/S3-edge served); ranged GET -r 0-1048575 -> 206, 1048576 bytes |
| 2026-10-21 | github.com/replicatedhq/ttl.sh | read live: 'Tag expiry is handled separately and is not yet wired up in this repo'; zot-config.json.j2 confirms S3 driver, dedupe:false, retention delay 1h with deleteUntagged |
Unknown or withheld values (7)
$.evidence[2].urlprivate-url$.evidence[3].urlprivate-url$.free_tier.notesprocess$.per_object_cap.notesnot-extracted$.per_object_cap.statednot-extracted$.retention.notesnot-extracted$.retention.statednot-extracted