GrafanaCON 2025

The 10th GrafanaCon was in Seattle last week and it was awesome! It was my first time attending GrafanaCon and really any conference of notable size. The conference was awesome and full of great speakers. The experts booth and Birds of a Feather sessions were helpful too for talking to people working on Grafana’s products. There were lots of interesting announcements and talks. Below is a smorgasbord of what I found interesting and took notes on. ...

May 12, 2025

Streaming the Fox — Replicating Firefox history with Litestream

The following steps walk through how to replicate the Firefox browser history using Litestream, a streaming replication tool for SQLite databases. Follow the Litestream / Getting Started / Prerequisites steps (“Install Litestream & SQLite” and “Setting up MinIO”) Copy the Firefox SQLite database to your dekstop: ❯ cp "$HOME/Library/Application Support/Firefox/Profiles/*release*/places.db" $HOME/places.db Replicate the database to object storage (MinIO) with Litestream: ❯ export LITESTREAM_ACCESS_KEY_ID=minioadmin ❯ export LITESTREAM_SECRET_ACCESS_KEY=minioadmin ❯ litestream replicate places.sqlite s3://mybkt.localhost:9000/places.db 2025/04/08 21:11:53 INFO litestream version=v0.3.13 2025/04/08 21:11:53 INFO initialized db path=/Users/joe/Desktop/places.sqlite 2025/04/08 21:11:53 INFO replicating to name=s3 type=s3 sync-interval=1s bucket=mybkt path=places.db region=us-east-1 endpoint=http://localhost:9000 Restore a copy of the database from object storage with Litestream: ❯ export LITESTREAM_ACCESS_KEY_ID=minioadmin ❯ export LITESTREAM_SECRET_ACCESS_KEY=minioadmin ❯ litestream restore -o places_copy.db s3://mybkt.localhost:9000/places.db 2025/04/08 20:56:17 INFO restoring snapshot replica=s3 generation=bbe87a28733f79e7 index=0 path=places_copy.db.tmp 2025/04/08 20:56:17 INFO restoring wal files replica=s3 generation=bbe87a28733f79e7 index_min=0 index_max=0 2025/04/08 20:56:17 INFO downloaded wal replica=s3 generation=bbe87a28733f79e7 index=0 elapsed=3.611136ms 2025/04/08 20:56:17 INFO applied wal replica=s3 generation=bbe87a28733f79e7 index=0 elapsed=5.923536ms 2025/04/08 20:56:17 INFO renaming database from temporary location replica=s3 List the tables in the copied database: ❯ sqlite3 places_copy.db SQLite version 3.43.2 2023-10-10 13:08:14 Enter ".help" for usage hints. sqlite❯ .tables _litestream_lock moz_items_annos _litestream_seq moz_keywords moz_anno_attributes moz_meta moz_annos moz_origins moz_bookmarks moz_places moz_bookmarks_deleted moz_places_extra moz_historyvisits moz_places_metadata moz_historyvisits_extra moz_places_metadata_search_queries moz_inputhistory moz_previews_tombstones MinIO console showing the bucket ...

April 8, 2025

Searching Changelog.com Transcripts

I’ve found myself becoming an avid listener of the Changelog podcast of late. I enjoy Jerod and Adam’s interview style and the topics. Recently I went poking around in the Changelog’s GitHub repos and found a repo containing transcripts from all episodes. Something else I discovered recently is Typesense, an “open source alternative to Algolia”. Unlike a tool like lunr, which uses JavaScript for client-side searching, Typesense requires running a dedicated server for search, or using their hosted cloud SaaS (Search-as-a-Service). ...

April 7, 2025

Transmogrify arrows on macOS

If you’re like me, you hate the look of a dash and a greater-than symbol as a poor man’s arrow. Here it is in 64pt font, so you can really soak in it’s terribleness: -> Ugh. Disgusting. One alternative is to use an emoji: ➡️. Sometimes that’s okay, a lot of times it’s not. It’s also a pain to type Cmd + Ctrl + Space and wait 30 seconds for the emoji picker to open. There’s gotta be a better way! Enter Text Replacements… Open System Preferences, click on the Keyboard navigation item in, and click Text Replacements… (you may need to scroll down to the Text Input section) Type --> as the Replace value and type → as the With value and click Done el fin Go forth and type –>’s and watch as they automagically transmogrify into ...

February 14, 2025

So you want to run untrusted code?

Congrats, you just purchased a brand new domain name for your enterprising SaaS startup. Overnight you came up with the brilliant idea to start a company that runs other people’s code as a business. I applaud you on your originality. The only problem is… how are you going to do it securely? Fortunately for you, I’ve spent a little bit of time (read: a few hours) over the last couple of days reading about how other people run other other people’s code . Let’s see what your options are in 2025. ...

February 13, 2025

Meshtastic & NATS

Yesterday I attended a local developer user group meetup. The topic was Meshtastic, a self-described open source, off-grid, decentralized, mesh network built to run on affordable, low-power devices. It uses LoRa under the hood. Meshtastic Overview I have never used or heard of Meshtastic or LoRa before. Some interesting bits that stuck stuck out to me: Long range: ~1–205 miles Slow: ~1–10 kbps Open Source It supports MQTT You can use Meshtastic to send group or direct messages. It uses a mesh network (hence the name), meaning that each device will propogate any message it receives, to a certain point. Messages are sent with an integer that is decremented each time it is forwarded. When the integer reaches zero, it is no longer forwarded. ...

February 12, 2025

TIL — SQLite UPSERT with extends

Today I was trying setting up a personal project that uses sqlc, a Go tool that generates code based off defined SQL queries. It’s not an ORM, but looks and feels kind of like one. Generally I prefer using ORMs, but none of Go’s feel great. After some conversations, I wanted to give sqlc a shot. Setting up sqlc is straight forward. You define a SQL schema, SQL queries, and a config file. I set it up using SQLite. This worked fine, until I wrote an UPSERT query. ...

February 11, 2025