Post by @stefano
littleFedi: a Fediverse Server That Doesn't Need a Data Centre
I was fifteen, and there were no BBSes in my city. So every call was long distance, once a day, sometimes twice. I'd start the dialer and wait for that sound - the handshake, the negotiation, the hiss settling into a carrier - and then I was connected to a computer sitting in somebody's bedroom, a few hundred kilometres away. I was a co-sysop of a local board and a national moderator of a FidoNet area. None of my friends understood what I was doing, and they'd stopped asking to avoid an incomprehensible monologue. But I liked it, and that was enough for me.
Here's the thing about that computer in someone's bedroom. There was no data centre. No domain, no certificate authority, no hosting provider, no cloud. Just a machine, a phone line, and a person who'd decided to run it. If you wanted to reach it, you called it.
Now look at what it takes today to put a small server on the network so other people can talk to it. A public address, which most home connections no longer have. A domain, which you rent. A certificate, which somebody has to issue you. And, increasingly, a VPS somewhere, because the software won't fit on the hardware you already own.
We've added a lot of infrastructure between two people who just want to talk. That's what littleFedi is about.
What it is
A single Go binary. No Ruby, no Sidekiq, no Redis, no separate worker processes to babysit. You run init, answer a few questions, and you've got a working instance. It speaks ActivityPub, and it speaks the Mastodon client API well enough that existing apps just work.
It also runs on hardware that would make Mastodon - or even Akkoma - struggle. Most software in this space assumes a VPS with a few gigabytes of RAM and a database server next to it. We assumed a Raspberry Pi Zero W behind a home router. There's a low_power mode that tunes memory use, image decoding and thumbnail generation for exactly that kind of box, and it's tested on that kind of box, not just on a fast dev machine.
In spirit this puts littleFedi close to snac, which I've always liked a lot. Same conviction: a personal server shouldn't need a fleet of services behind it.
Federating without a public address
littleMesh is the part I'm most attached to, and it's the part that goes back to the modem.
Your instance generates an Ed25519 key pair. That key is its identity - the node's address is derived from the public key, so reaching that address means reaching the holder of that key and nobody else. No registrar, no certificate authority, nobody to ask permission from.
A small set of public lighthouse nodes help two instances find each other. Once they're introduced, the traffic runs over a second TLS session pinned to both node IDs. The lighthouse copies encrypted bytes back and forth. It never sees plaintext, and it can't impersonate either side. And if the two nodes can reach each other directly, they drop the relay after the introduction and talk peer to peer.
Which is, more or less, calling the BBS directly. Just without the phone bill.
The gateway into ordinary HTTPS
Mastodon and other regular servers can't resolve a mesh address on their own. There's no domain and no certificate for them to find.
That's what the optional HTTPS gateway is for. A lighthouse operator can run one alongside the relay, and it bridges the mesh into ordinary HTTPS for the rest of the web. The gateway has to terminate TLS to do that, so it can technically see the traffic passing through it. Which is exactly why it's a separate, opt-in piece and not something every node exposes by default.
It has two independent settings: one controls what the gateway lets ordinary internet visitors reach at all, and a second one applies again at the destination node. Left at their defaults, both allow only federation traffic - ActivityPub delivery, discovery, public media. Web login, API and media proxy stay closed unless an operator deliberately opens them.
Mesh peers talking to each other directly never touch the gateway at all. That exposure only applies to the bridge into the wider web. And all of this can be self-hosted.
Chronological timelines
Timelines are chronological. Nothing gets reordered by an engagement model.
If you want something closer to "what did I miss", there's a separate /catchup page you visit on purpose. It ranks posts using signals your own instance already has - how many people you follow boosted something, whether it continues a conversation you took part in. No external popularity score, no telemetry, nothing leaves the machine. You press "mark as read", it moves a divider, and that's the only thing it remembers.
Self-expiring posts
You can set a post to expire, with its own timer, instead of a fixed instance-wide setting.
This isn't a client-side trick that hides the post from view. The expiry goes on the same durable job queue that runs the rest of littleFedi's background work, so the deletion survives restarts and isn't lost if the process happens to be down at the moment the timer fires. When it does fire, the post is deleted and a real Delete activity goes out to everyone who received it - so it actually disappears from remote instances too, not just locally. Editing the post before then can push the timer back or cancel it.
Static blogs, with real threaded replies
littleFedi can take a Fediverse post and publish it as a page on a plain static blog, with its own Atom feed and permalinks that don't move even if you edit the post later. No JavaScript, no database hit on page load.
The part I find more interesting is that the replies aren't left out. If the author turns the option on, littleFedi pulls the public replies that were actually federated to the post, threads them the same way the timeline does, and bakes the whole tree into the generated HTML at build time. So a blog post can show a real comment thread, in the same static file, with the same guarantee as the rest of the page - no JavaScript, no live queries. Only public and unlisted replies qualify, obviously. Anything followers-only or direct never enters the picture.
Why it looks like this
This isn't minimalism for its own sake. It's about how many people simply can't run their own server today, because the requirements are too steep. The hardware, the ops complexity, or just needing a domain and a public address before you can start. We're trying to remove those barriers one at a time, while still shipping a real, federating, reasonably complete server: polls, quotes, scheduled posts, MFA, PostgreSQL and S3 if you want to scale up later.
I've written before about taking a semi-truck to buy salad. Hardware keeps getting more expensive and the software running on it keeps asking for more of it every year. That's backwards. If the machines cost more, the operational cost of what sits on them should go down, not up. Same with complexity: the default direction is to keep adding it, and we'd rather strip it out.
And there's the other half, which is closer to why any of us are doing this at all. It's the same thing that drew me to snac and to the way grunfink works on it, and the same thing that had me dialing a stranger's computer at fifteen. People building tools so that people can talk to each other. Nothing more dressed up than that. We'd rather show the servers running, talk about the Pi sitting in the corner, share a tiramisu photo if it comes up. The joy in this was never about the money it brings in. It's about what we end up building, humanly, because of it.
It's beta software, still short of a first release, and I'd rather say that plainly than oversell it. But it runs, and it federates. That's the part I wanted to write about.
258 likes
Colin@niloc@todon.nl
Joseph@Joseph@pinksheep.org
Norz Tech@norztech@infosec.exchange
Sandro Santilli@strk@infosec.exchange
Sandro@strk@holos.social
Lori M Olson@lorimolson@mstdn.ca
Michael Graaf@michaelgraaf@kolektiva.social
Ugly bag of mostly water@phasorburn@phasorburn.com
subrealz@subrealz@infosec.exchange
Punnamaraju Vinayaka Tejas@PVTejas@mstdn.social
Jack Coates 🐀@puercomal@sfba.social
Joel Parker@joel@maclock.social
aserramonner@aserramonner@mastodont.cat
Joseph Kehoe☑️@josephkehoe@fosstodon.org
Douglas Edwards
@dedicto@zeroes.ca
Jonas R. (er/ihm)@JonasJRichter@pnpde.social
Rob Agar🐀@SaveTheOkapi@mas.to
Raj Patel
@irix@cloudisland.nz
@phil_stevens@mastodon.nz
Fiona Bianchi@fionasboots@tech.lgbt
Chuck Darwin@cdarwin@c.im
Andrej@SholemAlejchem@hessen.social
David J. Atkinson@meltedcheese@c.im
Olivier Forget@teleclimber@social.tchncs.de
Santiago, né ?
👾@santi@gone.lema.org
Kelson@kelson@notes.kvibber.com
Eli the Bearded@elithebearded@fed.qaz.red
calvin 🛋️ @calvin@fedi.sphericalcow.space
Alex Stewart@thealexstewart@mastodon.online
Jackie Plage@jac@social.lol
Darth Osler@autolycos@beige.party
Major Incident 🇪🇺@major@det.social
brot@brot@social.tchncs.de
pejacoby@pejacoby@infosec.exchange
@MonkeyPanic@nerdculture.de
domi@domi@c.im
Morgan@metasomite@aus.social
Georg Weissenbacher@GeorgWeissenbacher@fediscience.org
betabug... Sascha Welter@betabug@mastodon.sdf.org
Kris\Slyka@slyka@pawb.fun
DeltaLima 🐧@DeltaLima@social.la10cy.net
JTI@jti42@infosec.exchange
DeFrisselle ☑️@defrisselle@mastodon.sdf.org
SWAT@swat@fosstodon.org
Dokuminion@doku@mastodon.online
Chewie@chewie@mammut.gogreenit.net
@evgandr@mastodon.bsd.cafe
Henry Krumb@henry@bizzfed.de
Bruno Girin@brunogirin@mastodon.me.uk
yuman@yuman@defcon.social
LindRaupe@lindraupe@troet.cafe
MaineC@mainec@fromm.social
Piiieps & Brummm@PiiiepsBrummm@chaos.social
Jess Robinson@castaway@fosstodon.org
25 boosts
Colin@niloc@todon.nl
Sandro Santilli@strk@infosec.exchange
Sandro@strk@holos.social
Ugly bag of mostly water@phasorburn@phasorburn.com
subrealz@subrealz@infosec.exchange
SteveD@msdaum@mastodon.social
SusanneBonn@SusanneBonn@hessen.social
Joseph Kehoe☑️@josephkehoe@fosstodon.org
Jonas R. (er/ihm)@JonasJRichter@pnpde.social
Meniou@meniou@piaille.fr
Stingray's Badger Friend@StingrayBadger@zirk.us
Raj Patel
@irix@cloudisland.nz
@phil_stevens@mastodon.nz
Fiona Bianchi@fionasboots@tech.lgbt
Chuck Darwin@cdarwin@c.im
David J. Atkinson@meltedcheese@c.im
haraldk@haraldk@defcon.social
Olivier Forget@teleclimber@social.tchncs.de
Santiago, né ?
👾@santi@gone.lema.org
xenotar@xenotar
epn4littlefedi@epn4littlefedi
pepdmin@pepdmin
njrk@njrk
I'm looking forward to release so I can try this out.
I like my current instance but a problem with any instance is the worry that I'll have to move my account if an instance owner decides it's costing them too much money and/or time to run it.
@stefano
Not sure if I understand the concept of littleMesh correctly, but overall I really like the features you implemented already.
Looking forward to get "Reactions" some time in the future, if possible :)
@stefano
One thing I'd prefer is, if the compose-field would be more compact (in height).
There's just so much going on.
On the other hand, I like that all fields are written like "visible labels".
Hm ... 🤔
@stefano this sounds like perfectly fitting to reticulum.network... In this case it probably could one day work over LoRa and many other ways, too. 🤓
@stefano woe, this is awesome! for a second there, I thought you were talking about go to social, until you started describing the keypair stuff. Here's an important question for any such kind of system, can I run such an instance without any centralized authority? for example, would I be able to discover instances without having to use a centralized hub which presumably has to know about every instance that exist in order to be able to connect them?
@esoteric_programmer@social.stealthy.club for now, you need a lighthouse - but you can set different ones and change them
@stefano ah, so the lighthouse is something I can self-host, rather than a centralized public key directory? gotcha
@esoteric_programmer@social.stealthy.club yes, exactly. the entire infrastructure (lighthouse, gateway, etc) lives inside the littlefedi executable and is totally self hostable
@stefano in that sense, little fedi is p2p? which gets the mind to think, as it often does, how hard would it be to make that run on, say, BLE or something like that? from the regular internet to mesh networks :p
@esoteric_programmer@social.stealthy.club it can be p2p. One you've connected to a lighthouse that is showing you the route, you can directly connect other instances, if reachable.
@esoteric_programmer@social.stealthy.club in theory, that's not needed. it should be reachable. but doesn't strictly need a domain. everything is managed via keys.
Lighthouses cannot read the contents, as they will only exchange data, like the Delta Chat relays.
@stefano yo, that's even more awesome! does that mean I could use this over overlay networks such as pinecone, or tor?
@stefano Wonder if it could be possible to migrate a stock Mastodon/Glitch/whatever instance to littleFedi? If so I might just do that over here.
@seedy60@vee.seedy.cc you can move from/to a Mastodon instance, as you can do with most of the other Fediverse implementations. Drop in replacement isn't currently supported.
@stefano I don't mean migrating your account, I mean migrating your instance from running on stock Mastodon to running on littleFedi.
@seedy60@vee.seedy.cc Yes, I know. It could be implemented, but it would still require to mess with the Mastodon database.
I did it from Akkoma, and it worked. From Mastodon, it could be harder. Maybe for single user instances it could be done...we'll think about it...
@stefano is this software written with LLM assistance? was this post written with LLM assistance? fairly straightforward questions but I think it’s fair to ask for disclosure one way or another for a new project that’s not up front about it, these days
@ryan@social.miyaku.media As far as I know, the team behind the project hasn't used LLM assistance.
I didn't use an LLM to write that post. I did use ordinary software tools, including DeepL, to check parts of my English, because English is not my native language.
And, frankly, I don't think I should have to disclose my blood type every time I publish something just to prove that a human was involved.
I've been writing software and publishing things online for around thirty years, long before LLMs existed, and I find this growing assumption that everything must be AI-generated unless explicitly stated otherwise rather depressing.
I'm perfectly happy to answer the question. What makes me uncomfortable is the idea that not proactively listing every tool I may or may not have used somehow amounts to a lack of transparency.
At some point, humans are going to get tired of constantly having to prove they’re human. And then perhaps only the AIs will be left publishing anything.
@stefano I'm not asking you to disclose your blood type, though. I'm asking you to disclose whether or not you used tools many people believe to be unethical to produce software you’re announcing to the world and encouraging people to adopt.
@ryan@social.miyaku.media You're right, and I'm sorry. The comparison was a bad one and the tone was sharper than you deserved. Your question isn't the same thing, and it isn't unreasonable to ask.
The answer, as plainly as I can put it: I don't use LLMs to write this code, and as far as I know none of the others working on it do either. I'm not going to claim more certainty than I have about other people's keyboards, but that's my understanding and nobody has told me otherwise. The post is mine - English isn't my first language, so I used ordinary tools to check parts of it.
What got to me wasn't you. It's that after all these years we've reached a point where a new project is assumed to be AI-generated or AI-assisted until it says otherwise. I don't think that assumption is wrong, exactly. It's just a sad place to have arrived at, and it landed on a day when I was mostly happy about having something to show.
@stefano
Thanks for all the great work you and your team do with littleFedi - much appreciated, really! <3
@stefano Old GenX BBSer here - I ran Toad Hall in Winnipeg on a C64 in the late 80s and a 386 in the early 90s, and I've been looking for something like this. I'm glad Mastodon happened, but now that we've got that API it's time to shed all that horrible stuff they built it on, Rails and all that. 😜
But mostly the reasoning of tight code doing everything with very little. It resonates in my 8-bit heart.
This whole damn Internet could be made to happen with a tiny fraction of what goes into it, if we were doing it as a community rather than as consumers. You are doing god's work, and well, I'm having a look, cause I am way overdue to be self-hosting something.
@stefano jpaskaruk@gmail.com is where I currently do email. I'm afraid to move to a rented email service because I'm broke. :>
@stefano "littleFedi can take a Fediverse post and publish it as a page on a plain static blog, with its own Atom feed and permalinks that don't move even if you edit the post later" Now that's a killer feature for me, as someone self-hosting a Hubzilla instance in part because it supports separate static pages, albeit not fully federating those, and lacking RSS/Atom (which is something I've been requested, so I run a WriteFreely in parallel, although I'm not happy with its editor, yours looks already much better).
I've also found now your post about the four-tier media caching system - due to storage concerns, I run Hubzilla with federated timeline deactivated (and use other people's instances for actually navigating the fediverse, while keeping my Hubzilla for my archive of writings, former Facebook posts...), so the ability to just fetch images from the federated instances might make me consider running littleFedi in stead of Hubzilla, however there's one feature that may still tip the balance in favor of Hubzilla: nomadic identity, which is not yet widely implemented across ActivityPub.
@stefano Thank you, but I'm honestly waiting for the repository release so I can self-host and write about the experience of doing so
@fionescu@bsd.cafe
However, if I understand littlefedi's concept correctly, only the blog posts get rendered as "static pages".
There is no option to generate static pages, as e.g. the standard menu "About Me", "Interests", "Now", and so on?
Or would that be a feature that eventually will come along the roadmap of littlefedi, @stefano@littleone.littlefedi.social ?
That's a feature, Hubzilla, Friendica and the *key-family supports, what I really like.
I ♥ single-binary software with simple deployment.
Like, Forgejo is like that too, and it runs okay on a 20-year-old PC. It wants a database, but that database can be SQLite if you want.
@argv_minus_one@mastodon.sdf.org yes, the approach is similar. Here you can use the sqlite or the PostgreSQL, if you're planning a larger instance.
@stefano Very interesting read. I enjoy projects that want to have as little impact on hardware as possible.
I'm not very well versed in these concepts, but what you described is im quite similar to @HolosSocial, is it?
Of course Holos is focussed on the instance running on your phone while littleFedi is for dedicated low-spec hardware, as I understand it.
@stormii@darmstadt.social @HolosSocial@mastodon.social Holos is more oriented towards storing and forwarding messages to you device. This has a more "traditional" approach, while still being light. But yes, there are some similarities.
@stefano I find especially the infra-less aspect and p2p mediator aspect using the lighthouses interesting.
Is this more along of the way of glorified STUN/TURN or more along the way of full overlay network/overlay dictionary as in the sense of the past kademlia style DHT approaches?
Is there a write-up of protocol and architecture somewhere that isn't just "read the code"?
@jti42@infosec.exchange It's closer to an authenticated circuit/rendezvous relay than either a glorified STUN/TURN setup or a Kademlia-style overlay.
There is deliberately no DHT and no distributed routing/discovery protocol. A node keeps an outbound connection to one or more lighthouses. When another node wants to reach it, the lighthouse establishes a circuit between them, but the actual peer-to-peer session is end-to-end TLS inside that circuit, pinned to the nodes’ Ed25519 identities. The lighthouse therefore relays ciphertext rather than terminating the peer session.
If direct connectivity is available, peers can also discover and use the direct path, bypassing the lighthouse.
There is an optional directory, but it isn’t a DHT either. It holds signed records mapping a stable node identity to its current pinned lighthouse locators, mainly so relays can be replaced without changing the node’s identity, and to support readable aliases.
And yes, there is documentation beyond "read the code" 😉
The littleMesh documentation describes the architecture, circuit establishment, identity model, directory protocol/API, gateway, failover and trust/security model. There's also a separate littleMesh v2 identity study covering the protocol design decisions and threat model in more detail.
@stefano
I have no understanding of the technical aspects discussed 🙈
However, does "littleMesh" relate to or is comparable to "Meshtastic / Meshcore / Reticulum"?
@fasnix @jti42@infosec.exchange there are similarities, but they're currently a little different. Maybe Reticulum is near enough.
@stefano
Ok, thanks, Reticulum is awesome tech, imho :)
So, if littleMesh is near enough, it also must be awesome then ;)
@stefano Thanks for the insight. Can you link the mentioned documentation in your post or below it, as probably more people might be interested in this?
The approach vaguely reminds me of the Matrix approach.
On discovery: Do I understand it correctly that even with the activated directory part the visibility wrt to discoverable accounts would be limited to that specific directory instance and not lead to a full (or encompassing all connected directory nodes knowledge) view of existing (or connected to the respective nodes) accounts?
@jti42@infosec.exchange Absolutely. The documentation I mentioned is actually part of the project itself, so it will be released together with littleFedi/littleMesh once everything is ready. It includes the architecture overview, protocol details, identity model, directory design, threat model, and the reasoning behind some of the choices.
So I cannot link it publicly yet, but I definitely will once the project is released.
And yes, with one important distinction: the directory is not intended to be an account directory or a global discovery mechanism.
It only maps a readable node alias to its stable Ed25519 node ID, and a node ID to its current signed lighthouse locators. It stores no information about the accounts hosted by that node.
So enabling the directory does not create an encompassing view of users across the mesh. Account discovery remains the normal Fediverse/WebFinger/ActivityPub business once you know what you are looking for. The directory only helps you get from a human-readable mesh name to the technical node identity and then to a route to that node.
Also, at the moment directory instances do not federate or exchange their contents with each other. A node publishes to a particular directory, and a gateway/client configured for that directory knows what that directory knows. There is deliberately no DHT-like propagation or global mesh-wide index.
The Matrix comparison is interesting, though. There are certainly some similarities in separating identity, discovery, and routing concerns, although littleMesh is considerably narrower in scope: it is primarily a transport and reachability layer for ActivityPub rather than a new application-level federation protocol.
@stefano Thanks again! What was the rationale against the DHT et al / directory federation / global view approach?
@jti42@infosec.exchange The short version is: scope and threat surface.
littleMesh is trying to solve reachability and stable identity for nodes behind NAT, not to build a global discovery system.
For a DHT, the main objection was that it would introduce a whole new class of problems: replication, bootstrapping, poisoning resistance, abuse handling, consistency/consensus questions, etc. And it still would not remove the need for DNS/HTTPS when interoperating with ordinary ActivityPub servers, so the added complexity did not buy us much for the actual problem we were trying to solve.
The directory was intentionally kept much narrower. It is an authority for human-readable aliases and signed reachability information, not an index of users or content. The node identity remains self-certifying, and the directory cannot impersonate it.
Directory federation or a global view was not so much rejected forever as deliberately left out of scope. Once directories start exchanging knowledge, you need to define cross-directory trust, namespace collisions, propagation rules, conflict handling, replay/rollback semantics, abuse controls, and what exactly a “global view” is supposed to contain.
And since the directory does not contain accounts in the first place, federating directories would still not naturally produce a global account catalogue unless we deliberately added an entirely new discovery layer.
For availability, replication is actually more interesting to us than federation: having multiple directory endpoints serving the same signed state is useful because it removes a single point of failure. That is quite different from having independent directories merge into a globally searchable namespace.
So the design bias has basically been: solve the smallest networking problem necessary, keep identity cryptographically independent of the infrastructure, and leave broader discovery to the existing Fediverse mechanisms unless there is a compelling reason to add something else later.
@stefano
This is getting closer to @ifixcoinops 's notion of a social network. Do you think you could run it *on a smartphone*? Given access to a lighthouse due to roaming mobile data etc. obviously!
@kitten_tech@fosstodon.org @ifixcoinops@retro.social it definitely could. It's already building for Android targets, even if we haven't tested it (yet)
@stefano
Does that mean, it would get similar functionality like "holos" offers ("your fediverse server-client-application on your smartphone")?
@fasnix @kitten_tech@fosstodon.org @ifixcoinops@retro.social not exactly. it will run from a smartphone (maybe an old one, left at home), but won't allow store&fetch from an external node, at least for now.
@fasnix @kitten_tech@fosstodon.org @ifixcoinops@retro.social that would create a lot of complexity. I'm not saying it won't be implemented, but it's too complex to add it now, before even releasing the code 😉
@stefano that sounds lovely. I miss the times where you could offer services and thus create tightly knit communities with the budget of a 14 year old.
I am sharing an server (ivy bridge i7, 64GB RAM, slow spinning rust) with some of my friends but mastodon was too much of a hassle to set up (even though we run our own mail/nextcloud/minecraft…-servers). I will look forward to the release of littlefedi, maybe we can open up a invite based public instance and create a new place to visit on the internet. Or the pi4 I have lying around will serve as a homelab instance.
Thank you for working on software for community building and putting power back in peoples hands to tell their stories 
@stefano This all sounds pretty amazing to me. Nice work! I'll be following your progress with interest. :)
@stefano I was busy with other things and just saw this now. LittleMesh looks particularly interesting to make self hosting easier for everyone.
@stefano
Great initiative, I can't wait to try this out. Will it be ok to be only occasionally online as in BBS times ? And how about only with IPv6?
@strk@mapstodon.space as for all the Fediverse instance solutions, it can be occasionally online, even if it's not optimal. But it's resilient, so it will work.
ipv6 only will be ok, except you won't be able to federate with ipv4 only instances.