i math|

Supabase → SQLite

I built the most recent version of this site with Supabase. PostgreSQL for the database, GoTrue for auth, PGMQ for job queues, PostgREST for the API. I liked the results. It was everything I needed, managed by someone else (well, by me, but with nice tooling).

Then I tried to deploy it.

I have been self-hosting this site on a 1GB Linode for years. I wanted blue-green deployment — two instances side-by-side, zero-downtime deploys, instant rollback. The full Supabase stack would not even start. There was not enough RAM.

I tried to optimize, excluded unused services, and kept only the essentials. One instance could boot, but two was not possible.

What are my options?

  • Upgrade the Linode. 2GB for $12/month, 4GB for $24/month. But I did not know which would even be enough.
  • Use Supabase as a hosted service. I could leverage the free tier or upgrade to $25/month. But that meant abandoning self-hosting.
  • Rethink the stack entirely.

Rethinking the stack

I did not plan the migration top-down. I have a solid unit test suite, and integrations exercising the core micropub API. I needed to find the next safe change. What can I replace without breaking everything else?

Build the foundation

Before I could replace PostgreSQL, I needed a migration runner — something like supabase migrate, but for SQLite. This was a tool I had been wanting for other projects anyway.

I built stig: forward-only migrations, filesystem snapshots for local rollback, and schema-aware codegen so I could maintain the types I had previously generated. I collapsed the existing PostgreSQL migrations into a single SQLite schema, with support for moving forward as I had been.

Rewrite data access

With the foundation in place, I rewrote the data access layers: posts, references, syndications, OAuth grants. Sync FFI calls instead of async queries. When the tests passed, and the data was intact, PostgreSQL was essentially gone.

Replace the queue

PGMQ is a PostgreSQL extension. Now that the database was SQLite, a PostgreSQL queue made no sense. I swapped to Honker, a SQLite extension for in-process job queues. It uses commit-wake instead of polling, and no separate service is needed.

Swap authentication

GoTrue is a full-featured auth service — OAuth providers, magic links, session management, user invitations. For a production SaaS, it is great; but for a personal site with one admin user, it is overkill.

But I was not starting from scratch. I had already built an IndieAuth translation layer on top of GoTrue — the application was already speaking IndieAuth; GoTrue was just the backend. So replacing it with a users table, bcrypt, and JWTs was straightforward. The IndieAuth interface stayed the same. I just swapped what was underneath. When auth tests passed, the cascade was complete.

Remove Supabase

Each replacement made the next one obvious. Each test gate made the next one safe.

shgit rm -rf supabase/

Deleted the migrations, the env vars, the Docker config, and updated the docs. The satisfaction of that commit was disproportionate to the effort. It felt like closing a chapter.


The new stack:

  • SQLite 3.46.0 with JSONB (via @db/sqlite FFI)
  • Honker (in-process job queue, SQLite extension)
  • Local users + bcrypt + JWT
  • stig (Rust-based migration tool)
  • Everything in-process with Deno

The result:

  • Staging and production running side-by-side under 1GB
  • Zero-downtime promotes and rollbacks
  • Additional services: 0

Why Bitcasa is Too Much, Too Late

I was recently invited to join the private beta for Bitcasa, a Dropbox competitor in the online storage space. By invited, I mean I put my email address into a form and waited a day to get an activation email.

Bitcasa is really pushing the infinte storage line in it's marketing, which I found humorous when the post sign up message let me know that I would have to wait for access since "space is limited".

Here's how Bitcasa describes itself:

Bitcasa is revolutionizing personal cloud storage! Store all your music, photos, movies, and documents using Bitcasa and never run out of space again.

And here is the Dropbox sales pitch:

Any file you save to Dropbox also instantly saves to your computers, phones, and the Dropbox website.

Why Dropbox Wins

I'm pretty sure it was Merlin Mann that described the dropbox process this succinctly: Dropbox works because it's a folder on your Desktop, and it syncs. That's it. The entire process for keeping your files in sync is hard to even list.

  1. Install dropbox on your computer
  2. Put files in your Dropbox folder and never think about syncing again
  3. There is no step 3

Why Bitcasa Fails

With Bitcasa, I will not even attempt to describe all the ways it works. Instead, here are a few of the interactions I had during the brief time it was installed on my macbook.

I installed the Bitcasa app, which manifests itself as some kind of web-app launcher. I was honestly confused as to what was going on when I launched the app. A window appeared that looked something like an icon-view in finder, but with a Bitcasa patterned background. What made it stranger was that my menu bar reported that I was running Chrome.

I decided to try something simple first, so I moved my /notes folder of text files into this window using drag-and-drop. I can't remember what the UI was, but I am sure there was some indication that files were being uploaded.

And then…nothing?

Where is that folder now? On my Mac? In the "cloud"? I tried double-clicking on the folder and it opened as if it was a remote volume. There were my .txt files, so I decided to edit one, and this is where things got weird.

The file I edited ALSO updated my original local copy!! Seriously, this was unexpected, and brought on a wave of doubt:

  • Did I move that file into the cloud, or just tell it to keep a folder in sync?
  • If it's syncing with my local version, why does it mount instead of opening my local copy?
  • How do I have infinite storage if the files are also on my local machine?
  • What would happen if I deleted my local copy?

I never doubt how dropbox is going to work, and this single experience had me deleting1 Bitcasa from my mac within 10 minutes of installing it. Try again, please.

Footnotes

  1. The uninstall process is equally confusing. Here's some shell commands to help root out the cache files.


Init

Starting a new site, on a new server. So much to do and no time to start writing anything here yet…