Bluesky just shipped drafts — and if you're building on atproto, so did you.
Unfortunately, you can’t use Bluesky’s drafts infrastructure. But that’s ok, because unlike the bad old days when what we got was the dogs’ breakfast that Twitter or Facebook served us, there’s a lot more agency in the world today.
At Roundabout, we needed drafts, too. But more than that, our community stewards have been practically banging down our door for the ability to schedule posts.
So, we built it. We didn’t just build it for Roundabout, though – we built it for the whole atproto ecosystem, in a protocol-native way.
We call it ALF: the atproto Latency Fabric
ALF is a transparent proxy that sits between a client and a user’s PDS. To the client, it works exactly like a PDS — you write records to it the same way you would to any other PDS. But instead of publishing immediately, ALF stores the record as a draft and, optionally, publishes it at a scheduled time.
As someone using an atproto app right now, it might be a little while before you can use this, but developers of atproto apps can implement this straight away, so hopefully your wait won’t be long. The hard part is doing the in-app design work to expose a drafts interface!
That’s the magic of atproto’s architecture. When Twitter or TikTok shipped something, it benefitted (or, often, harmed) Twitter or TikTok users. When the community builds at the protocol layer, it benefits everyone — Blacksky, Flashes, Anisota, Gander, Grain, Roomy, even Tangled — any client that’s ever been built or will be built.
The community isn’t just keeping up with Bluesky. It’s compounding the ecosystem. As designed.
We built ALF because we needed it for Roundabout, New_ Public’s atproto-based community app. And once we started, it was actually easier to build something that works for any atproto record than to build a bespoke scheduling system just for ourselves.
We’re not going to run it as a SaaS app, but you can run and fork it yourself:
There’s also a live demo at https://alf.fly.dev. Connect your Bluesky account, schedule a post, and see how it works with basic Bluesky posts!
If you’re building an atproto client and want scheduling without reinventing the wheel, take a look. We’re a very small team with a big backlog so we can’t promise to help — but we’re happy to try to answer your questions and point you in the right direction. 💖
It's wonderful to see work like this given back to the community!
Are there any lessons you learned here that might be applicable to other projects that are essentially extensions to ATProto tooling? Maybe there's a pattern here worth exploring and replicating for other projects.
Also, are there other applications you could imagine this architectural approach being a good match for?
Great question!
I think this PDS Proxy approach could work for any "pre-commit" workflow: approvals, conditional embargoes, etc (I'm currently working on adding support for webhook-triggered delivery and scheduled delivery with dynamic content!). We use a similar system for Roundabout's pre-moderation system.
I haven't dug into how "choosing your write PDS" could work at an account level (think: swap out your PDS like you swap feeds or labelers), but this could allow writing to multiple PDSes, or keeping a backup separate from your primary PDS, on every post.
More generally, though, I think atproto just lends itself really nicely to "protocol thinking"; it really is like HTTP that way. As a bit of an annoying koan: "Not all lexicons are programmable, but all lexicons could be programmable." 🧘♂️
I think it'll take some time for us to suss out the patterns, but I'm certainly excited for that future!