the media problem: can atproto apps actually do video?
people are building tiktok clones on atproto now. instagram alternatives. livestreaming platforms. photo-sharing apps. the atmosphere is getting media heavy.
the whole premise of atproto is that your data lives on your PDS, not the appâs servers. your posts, your follows, your images, your videos, all stored in your personal data repository. the app is just an interface.
this is beautiful in theory. in practice? media is expensive. storage is cheap, bandwidth is not. and âunlimited storageâ is a subsidy that canât last forever.
iâve been building pollen, a tumblr-style app on atproto. last night i added video uploads. let me tell you about the constraints i hit. or should have hit!!!
the 10mb wall
blueskyâs hosted PDS has a ~10MB limit per blob upload. thatâs the individual file size cap. sounds reasonable until you realize:
- a 30-second 1080p video is easily 50-100MB
- a high-res photo from a modern phone is 5-15MB
- a short screen recording can hit 20MB instantly
so when someone uploads a video to pollen, i canât just pass it through to their PDS. i have to process it first.
ffmpeg to the rescue (sort of)
hereâs what pollen does now:
export async function processVideo(
inputPath: string,
maxSizeMB = 10
): Promise<ProcessVideoResult> {
const info = await getVideoInfo(inputPath);
// already small enough?
const currentSizeMB = info.size / (1024 * 1024);
if (currentSizeMB <= maxSizeMB && info.width <= 720) {
return { outputPath: inputPath, wasProcessed: false, ... };
}
// calculate target bitrate for desired file size
const targetBitrate = calculateTargetBitrate(info.duration, maxSizeMB * 0.9);
// two-pass x264 encoding, max 720p
await runFfmpeg(pass1Args);
await runFfmpeg(pass2Args);
return { outputPath, wasProcessed: true, ... };
}every video gets:
- downscaled to 720p max
- re-encoded with x264
- bitrate calculated to fit under 10MB based on duration
- two-pass encoding for optimal quality at that bitrate
it works! but a 60-second video at 720p with a 10MB cap means ~1.3 Mbps bitrate. thatâs⌠fine. not great. definitely not âiâm building the next tiktokâ quality.
the real constraint: total storage
the per-blob limit is annoying but workable. the bigger question is total storage per user.
right now, blueskyâs hosted PDS offers effectively unlimited storage. your repo can grow and grow. this is a subsidy, bluesky is eating the storage costs to bootstrap the network.
but think about what happens when media-heavy apps take off:
- a flashes creator (tiktok-style) posting short videos: 10GB/month easy
- a grain photographer sharing galleries: 2-5GB/month
- pinksea (classic oekaki / art platform) artist creating daily high-res pieces: 1-2GB/month
- multiply by millions of users
someoneâs going to pay for that storage. the question is who and how.
the bandwidth problem
storage is actually the easy part. bandwidth is where it gets harder.
when you view a pollen post with an image, hereâs what happens:
- your browser requests the image
- pollen proxies the request to the authorâs PDS
- the PDS serves the blob
- pollen passes it through to you
now imagine a post goes viral. 100,000 people want to see that image. thatâs 100,000 requests hitting the authorâs PDS.
if youâre on blueskyâs hosted PDS, bluesky absorbs that. they have CDN infrastructure, caching, the whole deal.
but the dream of atproto is self-hosted PDSes. what happens when your self-hosted PDS on a $5/month VPS suddenly needs to serve 100,000 image requests?
the gap: no community CDN for blobs
microcosm has built amazing community infrastructure for atproto:
- slingshot for identity caching
- constellation for backlink tracking
- spacedust for real-time interactions
thereâs no community CDN layer for media yet.
imagine something like:
- blob caching at the edge
- automatic cache population from the firehose
- bandwidth pooling across indie PDS operators
- âmedia relayâ infrastructure parallel to the existing firehose relays
without it, a self-hosted PDS on a $5/month VPS canât absorb a viral post (someone else build it and iâll pay for it pls)
futures
i see a few possible directions:
1. storage tiers on hosted PDSes
bluesky (or other PDS hosts) introduce paid tiers:
- free: 5GB total storage
- $5/month: 50GB
- $20/month: 500GB
this is the boring but realistic answer. itâs how email works (gmail gives you 15GB free, then you pay). itâs how most cloud storage works.
the nice thing about atproto: you can migrate your PDS. donât like blueskyâs pricing? move to a different host. your data comes with you.
2. self-hosted PDS becomes normal
like running your own mastodon instance, but for data instead of a full social app.
the official PDS repo already has docker images and setup guides. itâs not trivial, but itâs doable for technical users.
the challenge: you need to solve the bandwidth problem yourself. cloudflare in front of your PDS? bunny CDN? this is where most people will give up.
3. app-specific media hosting
apps like pollen could offer to host media on behalf of users, while still maintaining the atproto identity model.
your posts would still be in your PDS, but the blob refs would point to pollenâs CDN instead of your PDS directly. youâd trade some âtrue ownershipâ for practical scalability.
this feels like a compromise, but maybe a reasonable one for media-heavy apps and it makes migration much more difficult.
4. reference counting and garbage collection
delete a post? the blob stays in your repo. orphaned forever. taking up space.
at some point, PDSes will need tooling to:
- identify orphaned blobs
- let users reclaim space
- maybe auto-clean after some period
this is especially important if storage tiers become a thing.
what iâm doing in pollen
for now, pollen works within the constraints:
- aggressive video compression (720p max, calculated bitrate)
- server-side ffmpeg processing before PDS upload
- rejecting uploads over 100MB even before processing
- aggressive cache headers on an image proxy serving media from pollen
itâs not perfect. video quality is acceptable, not great. but it works, and users actually own their content.
the architecture means i donât need massive storage infrastructure. each userâs media lives on their PDS. pollen is just the interface layer plus a read cache.
if pollen somehow goes viral, i donât need 10x the storage, the usersâ PDSes absorb it. thatâs the magic of the model! and maybe the downfall idk.
the optimistic take
i think this is solvable. the architecture allows for solutions:
- CDN layers can be added without changing the protocol (and i bet some PDS hosts are already doing this)
- storage tiers can be introduced by PDS hosts
- community infrastructure can emerge (it already is with microcosm)
- apps can get creative with compression and caching
the question is whether weâll build this infrastructure before the âunlimited storageâ subsidy runs out.
or maybe the answer is simpler: cheap storage + smart caching + users pay for premium. thatâs worked for S3, R2, and B2.
if youâre building media-heavy apps on atproto, iâd love to hear what constraints youâre hitting. find me on bluesky or check out pollen.
links
- pollen - tumblr-style microblogging on atproto
- bluesky-social/pds - self-host your own PDS
- microcosm - community infrastructure for atproto
- pinksea - art platform on atproto
- flashes - short video app
- atproto docs - the protocol spec