Skip to content

Instantly share code, notes, and snippets.

@pushcx
Last active July 12, 2026 16:06
Show Gist options
  • Select an option

  • Save pushcx/eb7cdf2dc9707dc3ab9e7173d197ddfc to your computer and use it in GitHub Desktop.

Select an option

Save pushcx/eb7cdf2dc9707dc3ab9e7173d197ddfc to your computer and use it in GitHub Desktop.

2026-07-11 Trying the migration to sqlite again; we previously tried on 2026-02-21 but had to revert. Today's PR is #1927. I'm not streaming this because lots of steps make it too easy to flash PII or secrets on the screen.

For all the gory details, we planned this in issue #539.

sqlite migration checklist:

  • link to this gist from app/views/layouts/application.html.erb
  • lobsters-deploy
  • set the site in read-only mode (config/application.rb on prod)
  • take mariadb backup to pushcx's desktop
  • jj f; bump merge commit for notice + td's latest
  • scp lib/tasks/migrate.rake l:lobsters/current/lib/tasks
  • hatchbox panel: pause screensharing, add env vars (below)
  • be rails dump_db
  • scp db to my local dev
  • local: edit config/database.yml from trilogy to sqlite (below)
  • local: rm db/development/primary.sqlite3 and be rails db:create:primary and be rails db:schema:load:primary
  • local: be rails load_db
  • scp db/development/primary.sqlite3 l:lobsters/shared/storage/
  • merge the PR
  • pause streaming, delete DATABASE_URL (can't get relative with sqlite working immediately, tried sqlite://storage/primary.sqlite3 and config/database.yml has the absolute path)
  • hatchbox: stop solid_queue process
  • lobsters-deploy
  • investigate exceptions - they're ok, the mariadb code was live for ~30s with the sqlite database config, so it threw syntax errors
  • build the search indexes (below)
  • inspect the slow query log for scary things
  • take a sqlite backup to local dev
  • run the backup script
  • debug the backup script; it's not running the restic
  • restore the restic backup to local
  • if prod doesn't immediately melt down, rm read-only mode, notice, and trilogy gem
  • hatchbox: start solid_queue process

database.yaml:

primary:
  #    <<: *trilogy
  #    database: lobsters
  <<: *sqlite3
    database: db/primary.sqlite3

ENV vars:

ENABLE_SLOW_QUERY_LOGS = true
SLOW_QUERY_THRESHOLD_MS = 100

build initial search indexes:

insert into comments_fts(rowid, comment) select id, comment from comments;
insert into story_texts_fts(rowid, title, description, body) select id, title, description, body from story_texts;

revert checklist

  • revert the merge commit
  • config/application.rb - set read_only = true
  • hatchbox: stop puma
  • hatchbox: stop background jobs
  • be rails dump_db # sqlite -> dump.yml
  • backup new dump.yaml down to local, move prod copy to ~ (so it's not rotated by deploy)
  • restore DATABASE_URL
  • be rails load_db # dump.yml -> mariadb
  • lobsters-deploy
  • hatchbox: restart puma
  • hatchbox: restart bg jobs
  • remove the layout note
  • config/application.rb: set read_only = true
  • lobsters-deploy
  • prod: mv storage/primary.sqlite3* ~, back it up

followup chores

  • rewrite my 'prod db -> dev' script to fire resticjob and restore from snapshot
  • remove ~/.tmp/2026-07-11-dump.yml
  • tomorrow 2027-07-11: confirm the automated backup script ran
  • 2026-07-14: power off and image mariadb droplet
  • 2026-07-21: delete mariadb droplet
@evrimoztamur

Copy link
Copy Markdown

History being re-written (to SQLite)

@regalialong

regalialong commented Feb 21, 2026

Copy link
Copy Markdown

MariaDB -> SQLite.... seems like a downgrade unless I'm missing something?

Edit: yep i was
image

further reading here seemingly

And from the resulting PR:

Thanks for all this work, what a big project!

Any readers: we're on a call and going to migrate prod now.

@dzwdz

dzwdz commented Feb 21, 2026

Copy link
Copy Markdown

🦀🦀🦀 lobste.rs is gone 🦀🦀🦀

@AngelOnFira

Copy link
Copy Markdown
image

wild to see in 2026, great stuff

@mtmn

mtmn commented Feb 21, 2026

Copy link
Copy Markdown

inspiring move, let's gooo <3

@vlofgren

Copy link
Copy Markdown

Godspeed!

@kapunakap

Copy link
Copy Markdown

is this just fanta sea?

@CounterPillow

Copy link
Copy Markdown

i am a heron. i haev a long neck and i pick fish out of the water w/ my beak. if you dont repost this comment on 10 other pages i will fly into your kitchen tonight and make a mess of your pots and pans

@AquariusDue

Copy link
Copy Markdown

I was here for the SQLite migration!

@kapunakap

Copy link
Copy Markdown

2/22 never forget

btw can someone hire me, im looking for some k8s work, that'd be great, ty ty

@shoenot

shoenot commented Feb 21, 2026

Copy link
Copy Markdown

to sqlite 😮

@kapunakap

Copy link
Copy Markdown

😂

@JaspritBola

Copy link
Copy Markdown

🚀

@otonoton

Copy link
Copy Markdown

What was the rationale for migrating to SQLite in the first place?

@olivia-banks

Copy link
Copy Markdown

What was the rationale for migrating to SQLite in the first place?

lobsters/lobsters#1871

@hugoarnal

Copy link
Copy Markdown

Here we go again!

@jonnii

jonnii commented Jul 11, 2026

Copy link
Copy Markdown

🚀

@regalialong

Copy link
Copy Markdown

One more for good measure

@simonw

simonw commented Jul 11, 2026

Copy link
Copy Markdown

How big is the new sqlite database file?

@BinaryIgor

Copy link
Copy Markdown

Good luck! SQLite is awesome :)

@jammie-jelly

Copy link
Copy Markdown

Fingers crossed.

@pushcx

pushcx commented Jul 11, 2026

Copy link
Copy Markdown
Author

@simonw I just restored from backup to test that end-to-end, so I can conveniently say: 3.8G.

@tmoertel

Copy link
Copy Markdown

Fun experiment for offline analysis: export the database as column-oriented Parquet tables? If you have DuckDB installed, it "should" be a one-liner:

$ duckdb -c "ATTACH 'the_database.db' AS sqlite_db (TYPE SQLITE); EXPORT DATABASE sqlite_db TO 'the_output_directory' (FORMAT PARQUET);"

I wonder what that 3.8GB of sqlite storage would shrink to.

@pushcx

pushcx commented Jul 11, 2026

Copy link
Copy Markdown
Author

@tmoertel I don't know anything about duckdb, but I'd be happy to experiment on the next office hours stream. If you'd like to set up to call in and talk through fun with duckdb we could do that. Seems like a fun extension of the existing queries policy.

@pushcx

pushcx commented Jul 12, 2026

Copy link
Copy Markdown
Author

DigitalOcean has basic activity monitors. These charts cover the last 14 days to give a baseline; the spike on disk I/O near the right is the migration. CPU and load look normal, maybe spikier, and memory is down, which is wonderful.

2026-07-11_21-00

@BinaryIgor

Copy link
Copy Markdown

@pushcx as SQLite is an embedded DB, I would expect CPU to get slightly more load; out of curiosity, how much MEM & CPU do you have on DO for the main Lobsters instance?

@pushcx

pushcx commented Jul 12, 2026

Copy link
Copy Markdown
Author

It's a s-4vcpu-8gb. They don't list the CPU, but /proc/cpuinfo lists 4 identical:

vendor_id	: GenuineIntel
cpu family	: 6
model		: 85
model name	: DO-Premium-Intel
stepping	: 7
microcode	: 0x1
cpu MHz		: 2494.136
cache size	: 4096 KB

After I see how Monday goes I may nudge up the box, but so far, so boring.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment