Trillium Updates: Choosing to self-host
Following up from my previous post about the lessons I learned steering Claude and building on its API, this one is on what I learned in choosing to run Trillium entirely on my laptop, rather than deploy it to the cloud.
How this started
To start with - I didn't go into this planning to host the project on a laptop.
This actually started because I was interested in trying out Forgejo given the reliability issues Github has been dealing with for the past several months, and because I'd developed a desire to exercise more control and ownership of my code.
There'd been a lot of positive comments about Forgejo within the developer community, including how easy it was to configure and set up for a basic installation, so I thought I'd give it a shot.
My main concern in all of this though was having backups of my code. On the recommendation of a friend, I decided to try the managed repositories offering from a tool called Bupstash.
It's currently advertised as being in beta and recommended for redundant (not primary) backups, so for really critical things I can't afford to lose, my stuff is duplicated/mirrored elsewhere.
It's also worth calling out for those wanting to go all-in on self-hosting that Bupstash also has a self-hosting option, but it wasn't something I wanted to wrangle with at this time (and the $3 USD/month is worth it to me in terms of supporting continued development on the project).
After getting this up and running, I started investigating costs for running Trillium with a small cloud server and database.
"The Cheapest Server is the One You Don't Rent"
It'd been a while since I looked at the cost of small cloud servers and databases.
DigitalOcean Droplets weren't terrible price-wise (starting at around $4 USD/month). PlanetScale, which I've used in the past when they had a free tier, was estimated to be ~$5 USD for a single database.
So let's say $10 USD/month to round things up and factor in taxes. Not the worst, but still a decent chunk of change for what is basically a weekly cron job that's not serving traffic to users.
There's also the environmental factor of this that sits in the back of my mind. I originally wanted to run this app on a Green Compute Cloudflare Worker, but the size of the application was too large to run on the Worker free tier.
So what did I end up doing after a bunch of research and exploring different alternatives?
Hopping on my computer every week and manually running the job on Friday nights/Saturday mornings. Environmental and cost-efficient! 🙌🌳
Learning about Property Lists
Jokes aside, this wasn't sustainable for me, and I was actively looking into how I could run the cron automatically on my laptop during those weeks. There were a couple of hurdles to deal with in choosing to run this on a personal laptop:
- restarting the computer meant needing to ensure the application is started up again; and
- battery saving features put the laptop to sleep unpredictably throughout the day, potentially missing the window for when the cron is supposed to run even with a sane but generous grace period (think an hour) set.
The same friend I mentioned in my previous article — the one who pointed me toward Bupstash — also suggested I look into property lists ('plists') when we were chatting about how I had decided to run the application entirely locally.
For those less familiar with them - plist files store configuration data. When you place one within MacOS's LaunchAgents folder and load it with launchd, it can create an agent or daemon that runs in the background. They can perform tasks at regular intervals, or run scripts when a computer starts up. Apple's docs for these can be found here if you want to dig in a bit further.
Plists are really finicky, and if you run into an error, the message doesn't always tell you what went wrong.
For example: I ended up in an hour-long rabbit hole because I was getting a "Load 5: input/output error" message due to having a .plist name starting with com. at the beginning.
Why was this an issue? Still no idea - I'm hoping someone reads this, knows the answer, and will tell me (drop me a line at hey@ericapisani.dev if that's you!).
My advice: use an LLM to help you create one. While I still had a couple of issues such as what I described above, it was otherwise relatively quick to set up.
With a couple of plist files, I was able to:
- launch Trillium on the startup of my laptop;
- run regular backups of the local database for Trillium to make sure the bill information wasn't lost; and
- run regular backups of my Forgejo data.
Wrapping up
There's a lot of infrastructural plumbing that deploying to cloud services takes care of for you.
Fortunately for me, my setup doesn't require my application to be exposed to the internet, but if it did, I imagine there would be a lot more work for me to get set up properly beyond what I've described here.
That being said, if you're someone who has a simple application that doesn't need to handle external traffic and are comfortable with setting something like Tailscale up so that you can access your code/services only via your connected devices, then you can save a bit of 💰running small projects on older personal computers/laptops.
Happy coding! 👩💻
Erica Pisani Newsletter
Join the newsletter to receive the latest updates in your inbox.