<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>~kev 🐝</title>
    <link>https://write.mcr.wtf/kev/</link>
    <description></description>
    <pubDate>Tue, 22 Sep 2026 20:05:54 +0000</pubDate>
    <item>
      <title>Red notes become tasks: Jolla GTD goodness.</title>
      <link>https://write.mcr.wtf/kev/red-notes-become-tasks-jolla-gtd-goodness</link>
      <description>&lt;![CDATA[One of the things I was looking forward to about the Jolla was that it’s a proper Linux machine. Small integrations that would be awkward on most phones can be built using entirely ordinary Linux tools.&#xA;&#xA;Today I finally tried it. In a few minutes, I closed a small but persistent gap in my task-management system: red notes on my phone now become Taskwarrior inbox items automatically.&#xA;!--more--&#xA;I use a GTD style system. One of the most important parts of any GTD system is a trusted inbox where you can capture stuff that occurs to you, wherever you are, allowing you to carry on with your day knowing you can process it later. I&#39;ve used a bunch of stuff before: reminders in Slack, Google Keep, but there&#39;s always a manual element.&#xA;&#xA;Notes typed into the Jolla&#39;s stock Notes app now turn into tasks in my inbox, automatically, and sync home. Here&#39;s the setup, in enough detail that you could replicate it if you&#39;ve got a Jolla and a taskwarrior sync server already running.&#xA;&#xA;One honesty note before the code: I described what I wanted and Claude wrote the scripts and systemd units. I tested the code and made the design decisions, but I&#39;m not going to present this as unaided. Without that assistance, this small convenience probably wouldn’t have been worth spending a Sunday morning on, and therefore wouldn’t exist.&#xA;&#xA;The context, briefly&#xA;&#xA;I run GTD in two pieces: taskwarrior holds every actionable item, and a vimwiki-based wiki displays them via taskwiki viewports, so my dashboard is a text file in Neovim. Captured-but-unclarified stuff carries an +in tag. That&#39;s the inbox. Taskwarrior 3 syncs replicas through a self-hosted taskchampion-sync-server, which in my case runs on a machine at home, reachable over Tailscale. That server and a working desktop client are the prerequisites this post assumes.&#xA;&#xA;Step one: make the phone a sync replica&#xA;&#xA;Taskwarrior 3 runs happily on Sailfish. With it installed, the phone just needs the same sync credentials as any other replica, in ~/.taskrc:&#xA;&#xA;sync.server.origin=https://your-server:8088&#xA;sync.server.url=https://your-server:8088&#xA;sync.server.clientid=same uuid as your desktop&#xA;sync.encryptionsecret=same secret as your desktop&#xA;&#xA;Why both origin and url? Version gotcha: taskwarrior 3.0.x only reads sync.server.origin; the key was renamed to sync.server.url in 3.1. My phone has 3.0.2, my desktop is newer. Setting both means it keeps working when the package updates. If task sync says &#34;No sync.* settings are configured&#34; despite your config looking right, this is why.&#xA;&#xA;First task sync on the phone pulled down my whole task list. Same list on the desk and in my pocket. That alone was worth it.&#xA;&#xA;Step two: the Notes app becomes a capture tool&#xA;&#xA;Typing task in &#34;some thought&#34; in a terminal on a phone is friction, and friction kills capture habits. The Jolla&#39;s Notes app, on the other hand, is two taps away. So: a small job watches the Notes database, and any note I&#39;ve coloured red gets drained. Each non-empty line becomes one +in task, the note is deleted and task sync pushes it home.&#xA;&#xA;You can change the colour in the script but it made sense to me to have a specific colour to match rather than just drain everything, so I can keep actual notes and shopping lists in my phone without them disappearing. New notes are assigned different colours automatically, so making something a task is a deliberate step: I change that note to red.&#xA;&#xA;The Notes app stores everything in a single sqlite database with a simple schema: notes (pagenr INTEGER, color TEXT, body TEXT). It&#39;s in ~/.local/share/com.jolla/notes/QML/OfflineStorage/Databases/SOMEHASH.sqlite&#xA;&#xA;The filename hash may differ per install, so check rather than copying mine.&#xA;&#xA;The script&#xA;&#xA;~/bin/notes2inbox.py. Sailfish ships python3 with the sqlite3 module, so there are no dependencies at all:&#xA;&#xA;!/usr/bin/env python3&#xA;&#34;&#34;&#34;notes2inbox -- drain RED Jolla Notes into the taskwarrior inbox (+in).&#xA;&#xA;Triggered by notes2inbox.path (inotify on the Notes sqlite). Only notes&#xA;coloured red (#cc0000) are captures: each non-empty line becomes one +in&#xA;task, then the note is deleted and task sync pushes to home. Other colours&#xA;are durable notes and never touched. Ordering add -  delete -  sync means&#xA;the worst failure is a duplicate inbox item, never a lost capture.&#xA;&#xA;Every run ends with task sync, even when there are no red notes, so the&#xA;daily timer (and the run re-triggered by our own deletes) retries any&#xA;backlog left by a sync that failed offline.&#xA;&#34;&#34;&#34;&#xA;import sqlite3&#xA;import subprocess&#xA;import sys&#xA;&#xA;DB = (&#34;/home/defaultuser/.local/share/com.jolla/notes/QML/&#34;&#xA;      &#34;OfflineStorage/Databases/8b63c31a7656301b3f7bcbbfef8a2b6f.sqlite&#34;)&#xA;TASK = &#34;/usr/bin/task&#34;&#xA;INBOXCOLOR = &#34;#cc0000&#34;&#xA;&#xA;def main():&#xA;    db = sqlite3.connect(DB, timeout=10)&#xA;    rows = db.execute(&#34;SELECT rowid, body FROM notes WHERE lower(color) = ?&#34;,&#xA;                      (INBOXCOLOR,)).fetchall()&#xA;    captured = 0&#xA;    for rowid, body in rows:&#xA;        lines = [l.strip() for l in (body or &#34;&#34;).splitlines() if l.strip()]&#xA;        ok = True&#xA;        for line in lines:&#xA;            r = subprocess.run([TASK, &#34;rc.verbose=nothing&#34;, &#34;add&#34;, &#34;+in&#34;, &#34;--&#34;, line])&#xA;            if r.returncode == 0:&#xA;                captured += 1&#xA;            else:&#xA;                ok = False&#xA;                print(f&#34;task add failed ({r.returncode}): {line!r}&#34;, file=sys.stderr)&#xA;        if ok:&#xA;            db.execute(&#34;DELETE FROM notes WHERE rowid = ?&#34;, (rowid,))&#xA;            db.commit()&#xA;    if rows:&#xA;        print(f&#34;captured {captured} item(s) from {len(rows)} red note(s)&#34;)&#xA;    return subprocess.run([TASK, &#34;rc.verbose=nothing&#34;, &#34;sync&#34;]).returncode&#xA;&#xA;if name == &#34;main&#34;:&#xA;    sys.exit(main())&#xA;&#xA;The trigger: inotify&#xA;&#xA;I didn&#39;t want this to have to keep waking up and polling and the answer is a systemd path unit; an inotify watch on the database file. Nothing runs at all until the file actually changes. The pieces, in ~/.config/systemd/user/:&#xA;&#xA;notes2inbox.path:&#xA;&#xA;[Unit]&#xA;Description=Watch Jolla Notes DB for new captures&#xA;&#xA;[Path]&#xA;PathModified=/home/defaultuser/.local/share/com.jolla/notes/QML/OfflineStorage/Databases/8b63c31a7656301b3f7bcbbfef8a2b6f.sqlite&#xA;Unit=notes2inbox.service&#xA;&#xA;[Install]&#xA;WantedBy=default.target&#xA;&#xA;notes2inbox.service:&#xA;&#xA;[Unit]&#xA;Description=Drain Jolla Notes into taskwarrior inbox&#xA;&#xA;[Service]&#xA;Type=oneshot&#xA;ExecStart=/usr/bin/python3 /home/defaultuser/bin/notes2inbox.py&#xA;&#xA;notes2inbox.timer — a daily catch-up in case a filesystem event is ever missed, or a sync failed while Tailscale was down:&#xA;&#xA;[Unit]&#xA;Description=Daily catch-up for notes2inbox (missed events / failed sync)&#xA;&#xA;[Timer]&#xA;OnCalendar=daily&#xA;Persistent=true&#xA;&#xA;[Install]&#xA;WantedBy=timers.target&#xA;&#xA;Then:&#xA;&#xA;systemctl --user daemon-reload&#xA;systemctl --user enable --now notes2inbox.path notes2inbox.timer&#xA;&#xA;Does it work?&#xA;&#xA;Yes, and satisfyingly fast. Write a red note, and by the time you&#39;ve put the phone back in your pocket the note has vanished from the app and the task exists. The desktop sees it on its next task sync, and my wiki&#39;s inbox viewport picks it up from there without any extra plumbing. Taskwiki is just displaying the +in tag.&#xA;&#xA;Caveats if you copy this:&#xA;&#xA;One task per line, so a red note can batch several captures.&#xA;The -- in task add +in -- line makes taskwarrior treat the whole line as description text. Without it, a captured thought containing due:friday or +something would get parsed as task attributes.&#xA;Ordering is add → delete → sync. If the phone is off-network, task sync fails harmlessly and retries later.&#xA;Red notes get deleted. The app is a capture buffer for red, durable storage for the other eight colours. Don&#39;t colour your shopping list red.&#xA;&#xA;I&#39;ve literally just turned this on, and it&#39;s Sunday, so I&#39;ve not really used it much but I&#39;m looking forward to seeing how useful it becomes the next time I process my inbox at my desk!]]&gt;</description>
      <content:encoded><![CDATA[<p>One of the things I was looking forward to about the Jolla was that it’s a proper Linux machine. Small integrations that would be awkward on most phones can be built using entirely ordinary Linux tools.</p>

<p>Today I finally tried it. In a few minutes, I closed a small but persistent gap in my task-management system: red notes on my phone now become Taskwarrior inbox items automatically.

I use a GTD style system. One of the most important parts of any GTD system is a trusted inbox where you can capture stuff that occurs to you, wherever you are, allowing you to carry on with your day knowing you can process it later. I&#39;ve used a bunch of stuff before: reminders in Slack, Google Keep, but there&#39;s always a manual element.</p>

<p>Notes typed into the Jolla&#39;s stock Notes app now turn into tasks in my inbox, automatically, and sync home. Here&#39;s the setup, in enough detail that you could replicate it if you&#39;ve got a Jolla and a taskwarrior sync server already running.</p>

<p>One honesty note before the code: I described what I wanted and <strong>Claude wrote the scripts and systemd units</strong>. I tested the code and made the design decisions, but I&#39;m not going to present this as unaided. Without that assistance, this small convenience probably wouldn’t have been worth spending a Sunday morning on, and therefore wouldn’t exist.</p>

<h2 id="the-context-briefly">The context, briefly</h2>

<p>I run <a href="https://gettingthingsdone.com/" rel="nofollow">GTD</a> in two pieces: <a href="https://taskwarrior.org/" rel="nofollow">taskwarrior</a> holds every actionable item, and a vimwiki-based wiki displays them via <a href="https://github.com/tools-life/taskwiki" rel="nofollow">taskwiki</a> viewports, so my dashboard is a text file in Neovim. Captured-but-unclarified stuff carries an <code>+in</code> tag. That&#39;s the inbox. Taskwarrior 3 syncs replicas through a self-hosted <a href="https://github.com/GothenburgBitFactory/taskchampion-sync-server" rel="nofollow">taskchampion-sync-server</a>, which in my case runs on a machine at home, reachable over Tailscale. That server and a working desktop client are the prerequisites this post assumes.</p>

<h2 id="step-one-make-the-phone-a-sync-replica">Step one: make the phone a sync replica</h2>

<p>Taskwarrior 3 runs happily on Sailfish. With it installed, the phone just needs the same sync credentials as any other replica, in <code>~/.taskrc</code>:</p>

<pre><code>sync.server.origin=https://your-server:8088
sync.server.url=https://your-server:8088
sync.server.client_id=&lt;same uuid as your desktop&gt;
sync.encryption_secret=&lt;same secret as your desktop&gt;
</code></pre>

<p>Why both <code>origin</code> and <code>url</code>? Version gotcha: taskwarrior 3.0.x only reads <code>sync.server.origin</code>; the key was renamed to <code>sync.server.url</code> in 3.1. My phone has 3.0.2, my desktop is newer. Setting both means it keeps working when the package updates. If <code>task sync</code> says “No sync.* settings are configured” despite your config looking right, this is why.</p>

<p>First <code>task sync</code> on the phone pulled down my whole task list. Same list on the desk and in my pocket. That alone was worth it.</p>

<h2 id="step-two-the-notes-app-becomes-a-capture-tool">Step two: the Notes app becomes a capture tool</h2>

<p>Typing <code>task in &#34;some thought&#34;</code> in a terminal on a phone is friction, and friction kills capture habits. The Jolla&#39;s Notes app, on the other hand, is two taps away. So: a small job watches the Notes database, and any note I&#39;ve coloured <strong>red</strong> gets drained. Each non-empty line becomes one <code>+in</code> task, the note is deleted and <code>task sync</code> pushes it home.</p>

<p>You can change the colour in the script but it made sense to me to have a specific colour to match rather than just drain everything, so I can keep actual notes and shopping lists in my phone without them disappearing. New notes are assigned different colours automatically, so making something a task is a deliberate step: I change that note to red.</p>

<p>The Notes app stores everything in a single sqlite database with a simple schema: <code>notes (pagenr INTEGER, color TEXT, body TEXT)</code>. It&#39;s in <code>~/.local/share/com.jolla/notes/QML/OfflineStorage/Databases/SOMEHASH.sqlite</code></p>

<p>The filename hash may differ per install, so check rather than copying mine.</p>

<h2 id="the-script">The script</h2>

<p><code>~/bin/notes2inbox.py</code>. Sailfish ships python3 with the sqlite3 module, so there are no dependencies at all:</p>

<pre><code class="language-python">#!/usr/bin/env python3
&#34;&#34;&#34;notes2inbox -- drain RED Jolla Notes into the taskwarrior inbox (+in).

Triggered by notes2inbox.path (inotify on the Notes sqlite). Only notes
coloured red (#cc0000) are captures: each non-empty line becomes one +in
task, then the note is deleted and task sync pushes to home. Other colours
are durable notes and never touched. Ordering add -&gt; delete -&gt; sync means
the worst failure is a duplicate inbox item, never a lost capture.

Every run ends with task sync, even when there are no red notes, so the
daily timer (and the run re-triggered by our own deletes) retries any
backlog left by a sync that failed offline.
&#34;&#34;&#34;
import sqlite3
import subprocess
import sys

DB = (&#34;/home/defaultuser/.local/share/com.jolla/notes/QML/&#34;
      &#34;OfflineStorage/Databases/8b63c31a7656301b3f7bcbbfef8a2b6f.sqlite&#34;)
TASK = &#34;/usr/bin/task&#34;
INBOX_COLOR = &#34;#cc0000&#34;


def main():
    db = sqlite3.connect(DB, timeout=10)
    rows = db.execute(&#34;SELECT rowid, body FROM notes WHERE lower(color) = ?&#34;,
                      (INBOX_COLOR,)).fetchall()
    captured = 0
    for rowid, body in rows:
        lines = [l.strip() for l in (body or &#34;&#34;).splitlines() if l.strip()]
        ok = True
        for line in lines:
            r = subprocess.run([TASK, &#34;rc.verbose=nothing&#34;, &#34;add&#34;, &#34;+in&#34;, &#34;--&#34;, line])
            if r.returncode == 0:
                captured += 1
            else:
                ok = False
                print(f&#34;task add failed ({r.returncode}): {line!r}&#34;, file=sys.stderr)
        if ok:
            db.execute(&#34;DELETE FROM notes WHERE rowid = ?&#34;, (rowid,))
            db.commit()
    if rows:
        print(f&#34;captured {captured} item(s) from {len(rows)} red note(s)&#34;)
    return subprocess.run([TASK, &#34;rc.verbose=nothing&#34;, &#34;sync&#34;]).returncode


if __name__ == &#34;__main__&#34;:
    sys.exit(main())
</code></pre>

<h2 id="the-trigger-inotify">The trigger: inotify</h2>

<p>I didn&#39;t want this to have to keep waking up and polling and the answer is a systemd <strong>path unit</strong>; an inotify watch on the database file. Nothing runs at all until the file actually changes. The pieces, in <code>~/.config/systemd/user/</code>:</p>

<p><code>notes2inbox.path</code>:</p>

<pre><code class="language-ini">[Unit]
Description=Watch Jolla Notes DB for new captures

[Path]
PathModified=/home/defaultuser/.local/share/com.jolla/notes/QML/OfflineStorage/Databases/8b63c31a7656301b3f7bcbbfef8a2b6f.sqlite
Unit=notes2inbox.service

[Install]
WantedBy=default.target
</code></pre>

<p><code>notes2inbox.service</code>:</p>

<pre><code class="language-ini">[Unit]
Description=Drain Jolla Notes into taskwarrior inbox

[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /home/defaultuser/bin/notes2inbox.py
</code></pre>

<p><code>notes2inbox.timer</code> — a daily catch-up in case a filesystem event is ever missed, or a sync failed while Tailscale was down:</p>

<pre><code class="language-ini">[Unit]
Description=Daily catch-up for notes2inbox (missed events / failed sync)

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target
</code></pre>

<p>Then:</p>

<pre><code>systemctl --user daemon-reload
systemctl --user enable --now notes2inbox.path notes2inbox.timer
</code></pre>

<h2 id="does-it-work">Does it work?</h2>

<p>Yes, and satisfyingly fast. Write a red note, and by the time you&#39;ve put the phone back in your pocket the note has vanished from the app and the task exists. The desktop sees it on its next <code>task sync</code>, and my wiki&#39;s inbox viewport picks it up from there without any extra plumbing. Taskwiki is just displaying the <code>+in</code> tag.</p>

<h2 id="caveats-if-you-copy-this">Caveats if you copy this:</h2>
<ul><li><strong>One task per line</strong>, so a red note can batch several captures.</li>
<li>The <code>--</code> in <code>task add +in -- &lt;line&gt;</code> makes taskwarrior treat the whole line as description text. Without it, a captured thought containing <code>due:friday</code> or <code>+something</code> would get parsed as task attributes.</li>
<li><strong>Ordering is add → delete → sync.</strong> If the phone is off-network, <code>task sync</code> fails harmlessly and retries later.</li>
<li><strong>Red notes get deleted.</strong> The app is a capture buffer for red, durable storage for the other eight colours. Don&#39;t colour your shopping list red.</li></ul>

<p>I&#39;ve literally just turned this on, and it&#39;s Sunday, so I&#39;ve not really used it much but I&#39;m looking forward to seeing how useful it becomes the next time I process my inbox at my desk!</p>
]]></content:encoded>
      <guid>https://write.mcr.wtf/kev/red-notes-become-tasks-jolla-gtd-goodness</guid>
      <pubDate>Sun, 16 Aug 2026 09:29:42 +0000</pubDate>
    </item>
    <item>
      <title>Bringing mcr.wtf home, part two</title>
      <link>https://write.mcr.wtf/kev/bringing-mcr-wtf-home-part-2</link>
      <description>&lt;![CDATA[mcr.wtf lives at home now.&#xA;&#xA;Back in June I wrote about bringing mcr.wtf home. I was planning to move this instance off a DigitalOcean droplet and onto a machine in my house. I promised an update once it happened.&#xA;!--more--&#xA;&#xA;It happened. This morning, in fact. In a couple hours of downtime I transferred all the data to the new server and switched up the DNS. The new server, by the way, is a reconditioned Dell Optiplex bought with the money I&#39;d collected from donations.&#xA;&#xA;The boring preparation that made it boring&#xA;&#xA;The move itself was rehearsed a week ago against a copy of the database, which is the single best decision in this whole project. By cutover day I had a step-by-step runbook with timings, and every scary unknown had already been met once in a low-stakes setting. All the software was set up, all that needed to be done was move the data and switch the DNS over.&#xA;&#xA;The other prerequisite was backups. The new machine was already shipping nightly encrypted database dumps offsite. Last week I also ran through restoring a backup too. A backup you haven&#39;t tested, isn&#39;t a backup!&#xA;&#xA;Moving day&#xA;&#xA;The short version: stop the old server, take a final database dump, copy it home, restore it, check everything, then point DNS at my house.&#xA;&#xA;Final database dump: 21 minutes&#xA;Copying the dump over: 8 minutes&#xA;Restoring into PostgreSQL: 55 minutes&#xA;Row counts afterwards: identical, every table&#xA;&#xA;Then the DNS flip. Within three minutes, other Mastodon servers were already delivering posts to the machine in my house. The fediverse doesn&#39;t hang about!&#xA;&#xA;I should say, I haven&#39;t moved absolutely everything from the Cloud yet. I&#39;m hosting media and pushing backups to Wasabi. This is something I&#39;ll look at but haven&#39;t any plans to change yet.&#xA;&#xA;The victory lap&#xA;&#xA;Feeling confident, I applied the latest Mastodon bugfix release, a kernel update, and a reboot, to make sure it automatically recovers.&#xA;&#xA;Finally I powered the old droplet off. It gets destroyed for good in a couple of weeks once I&#39;m sure I won&#39;t need to crawl back.&#xA;&#xA;What this actually gets me&#xA;&#xA;The old server: 2 CPU cores, permanently full disk, ~£50 a month.&#xA;The new one: 6 cores, NVMe storage with room to breathe, and it costs me electricity.&#xA;The database came out of the move 37GB smaller.&#xA;Everything is snappier. Noticeably. Cheapo real hardware embarrasses what fifty quid a month can rent.&#xA;&#xA;What it means for you (if you&#39;re on mcr.wtf)&#xA;&#xA;Nothing changed. Your account, posts, follows, timelines, and media are all intact.&#xA;The site is faster.&#xA;Your data now lives in Manchester, with encrypted offsite backups not in a datacentre owned by someone whose name I don&#39;t know. I can point at it.&#xA;&#xA;That&#39;s all for now. If anything seems off, or you just want to tell me this was a terrible idea, I&#39;m at @kev@mcr.wtf, which I can now say is a machine I could go and pat.&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="https://mcr.wtf" rel="nofollow">mcr.wtf</a> lives at home now.</p>

<p>Back in June I wrote about <a href="https://write.mcr.wtf/kev/bringing-mcr-wtf-home" rel="nofollow">bringing mcr.wtf home</a>. I was planning to move this instance off a DigitalOcean droplet and onto a machine in my house. I promised an update once it happened.
</p>

<p>It happened. This morning, in fact. In a couple hours of downtime I transferred all the data to the new server and switched up the DNS. The new server, by the way, is a reconditioned Dell Optiplex bought with the money I&#39;d collected from donations.</p>

<h2 id="the-boring-preparation-that-made-it-boring">The boring preparation that made it boring</h2>

<p>The move itself was rehearsed a week ago against a copy of the database, which is the single best decision in this whole project. By cutover day I had a step-by-step runbook with timings, and every scary unknown had already been met once in a low-stakes setting. All the software was set up, all that needed to be done was move the data and switch the DNS over.</p>

<p>The other prerequisite was backups. The new machine was already shipping nightly encrypted database dumps offsite. Last week I also ran through restoring a backup too. A backup you haven&#39;t tested, isn&#39;t a backup!</p>

<h2 id="moving-day">Moving day</h2>

<p>The short version: stop the old server, take a final database dump, copy it home, restore it, check <em>everything</em>, then point DNS at my house.</p>
<ul><li>Final database dump: <strong>21 minutes</strong></li>
<li>Copying the dump over: <strong>8 minutes</strong></li>
<li>Restoring into PostgreSQL: <strong>55 minutes</strong></li>
<li>Row counts afterwards: <strong>identical, every table</strong></li></ul>

<p>Then the DNS flip. Within three minutes, other Mastodon servers were already delivering posts to the machine in my house. The fediverse doesn&#39;t hang about!</p>

<p>I should say, I haven&#39;t moved absolutely everything from the Cloud yet. I&#39;m hosting media and pushing backups to Wasabi. This is something I&#39;ll look at but haven&#39;t any plans to change <em>yet.</em></p>

<h2 id="the-victory-lap">The victory lap</h2>

<p>Feeling confident, I applied the latest Mastodon bugfix release, a kernel update, and a reboot, to make sure it automatically recovers.</p>

<p>Finally I powered the old droplet off. It gets destroyed for good in a couple of weeks once I&#39;m sure I won&#39;t need to crawl back.</p>

<h2 id="what-this-actually-gets-me">What this actually gets me</h2>
<ul><li>The old server: 2 CPU cores, permanently full disk, ~£50 a month.</li>
<li>The new one: 6 cores, NVMe storage with room to breathe, and it costs me electricity.</li>
<li>The database came out of the move 37GB <em>smaller.</em></li>
<li>Everything is snappier. Noticeably. Cheapo real hardware embarrasses what fifty quid a month can rent.</li></ul>

<h2 id="what-it-means-for-you-if-you-re-on-mcr-wtf">What it means for you (if you&#39;re on mcr.wtf)</h2>
<ul><li>Nothing changed. Your account, posts, follows, timelines, and media are all intact.</li>
<li>The site is faster.</li>
<li>Your data now lives in Manchester, with encrypted offsite backups not in a datacentre owned by someone whose name I don&#39;t know. I can point at it.</li></ul>

<p>That&#39;s all for now. If anything seems off, or you just want to tell me this was a terrible idea, I&#39;m at <a href="https://write.mcr.wtf/@/kev@mcr.wtf" class="u-url mention" rel="nofollow">@<span>kev@mcr.wtf</span></a>, which I can now say is a machine I could go and pat.</p>
]]></content:encoded>
      <guid>https://write.mcr.wtf/kev/bringing-mcr-wtf-home-part-2</guid>
      <pubDate>Sun, 26 Jul 2026 12:00:00 +0000</pubDate>
    </item>
    <item>
      <title>But where&#39;s the engagement?</title>
      <link>https://write.mcr.wtf/kev/but-wheres-the-engagement</link>
      <description>&lt;![CDATA[Over a year ago I wrote the first version of the code for Popquizza. It&#39;s a simple daily music quiz with ten multiple choice questions each day. It was my brother&#39;s idea. He writes the questions and I used it as an excuse to learn Gleam for something useful.&#xA;!--more--&#xA;&#xA;Quite often, if I show it to someone involved in web development, they give me a small piece of advice. They tell me I should have a cookie warning. They remind me it&#39;s a legal requirement. Except it isn&#39;t. Because Popquizza doesn&#39;t set any cookies. It does use local storage but purely for storing the results of your quiz. It doesn&#39;t track you. We don&#39;t do analytics other than occasionally checking the raw number of visitors. This is often followed by a question about how I track engagement. My answer, that I don&#39;t, is met with visible confusion. Like, what&#39;s the point then?&#xA;&#xA;It reminds me of the Reddit page for Mastodon where people regularly come in complaining that they can&#39;t get any traction with their posts. That they get so much more engagement on Instagram, X or even Bluesky. They argue Mastodon needs to add features to help people like them. Again, the idea you might not want to add those features seems to confuse people. I read a post on Mastodon yesterday which was trying to make the case that the Fediverse was actively hostile to people trying to make money from their work.&#xA;&#xA;To be clear, I don&#39;t think people selling things on Mastodon are doing anything wrong. I don&#39;t mind artists promoting their work. I don&#39;t mind people linking to shops, books, music, newsletters or whatever else. I don&#39;t even particularly mind major brands having a presence, which is controversial in some quarters.&#xA;&#xA;What unsettles me is not the disagreement. I disagree with people all the time. It&#39;s the confusion.&#xA;&#xA;What I object to is the idea that every space has to reshape itself around commercial expectations. That every site needs analytics. That every post needs reach. That every community needs growth tools. That every small thing on the web is somehow incomplete until it has been turned into a funnel.&#xA;&#xA;Sometimes a quiz can just be a quiz. A post can just be a post. A website can just be a website.&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>Over a year ago I wrote the first version of the code for <a href="https://popquizza.com" rel="nofollow">Popquizza</a>. It&#39;s a simple daily music quiz with ten multiple choice questions each day. It was my brother&#39;s idea. He writes the questions and I used it as an excuse to learn <a href="https://gleam.run/" rel="nofollow">Gleam</a> for something useful.
</p>

<p>Quite often, if I show it to someone involved in web development, they give me a small piece of advice. They tell me I should have a cookie warning. They remind me it&#39;s a legal requirement. Except it isn&#39;t. Because Popquizza doesn&#39;t set any cookies. It does use local storage but purely for storing the results of your quiz. It doesn&#39;t track you. We don&#39;t do analytics other than occasionally checking the raw number of visitors. This is often followed by a question about how I track engagement. My answer, that I don&#39;t, is met with visible confusion. Like, what&#39;s the point then?</p>

<p>It reminds me of the Reddit page for Mastodon where people regularly come in complaining that they can&#39;t get any traction with their posts. That they get so much more engagement on Instagram, X or even Bluesky. They argue Mastodon needs to add features to help people like them. Again, the idea you might not want to add those features seems to confuse people. I read a post on Mastodon yesterday which was trying to make the case that the Fediverse was actively hostile to people trying to make money from their work.</p>

<p>To be clear, I don&#39;t think people selling things on Mastodon are doing anything wrong. I don&#39;t mind artists promoting their work. I don&#39;t mind people linking to shops, books, music, newsletters or whatever else. I don&#39;t even particularly mind major brands having a presence, which is controversial in some quarters.</p>

<p>What unsettles me is not the disagreement. I disagree with people all the time. It&#39;s the confusion.</p>

<p>What I object to is the idea that every space has to reshape itself around commercial expectations. That every site needs analytics. That every post needs reach. That every community needs growth tools. That every small thing on the web is somehow incomplete until it has been turned into a funnel.</p>

<p>Sometimes a quiz can just be a quiz. A post can just be a post. A website can just be a website.</p>
]]></content:encoded>
      <guid>https://write.mcr.wtf/kev/but-wheres-the-engagement</guid>
      <pubDate>Wed, 01 Jul 2026 12:00:00 +0000</pubDate>
    </item>
    <item>
      <title>Bringing mcr.wtf home</title>
      <link>https://write.mcr.wtf/kev/bringing-mcr-wtf-home</link>
      <description>&lt;![CDATA[I&#39;ve been running mcr.wtf, a public Mastodon server vaguely targeted at people in Greater Manchester, for about three years now.&#xA;!--more--&#xA;&#xA;I started it during the big exodus from Twitter when Musk took it over and I guess I did it because I thought it&#39;d be nice to have a Manchester community on Mastodon, but also just because I wanted somewhere to engage with the Fedi myself.&#xA;&#xA;It never really &#34;took off&#34;. Not that I did anything to encourage it to. It did, however, grow a small group of users who use it a fair amount. In some ways this is the best outcome. It works, and the support and moderation load for me is basically zero.&#xA;&#xA;Over the last year I turned off open registration. Almost every new user was a spambot from India. It seemed more trouble than it&#39;s worth.&#xA;&#xA;The only real problem is the growing cost. I run it on Digital Ocean and, although the small instance and backup I have is pretty cheap, the database keeps on growing and that&#39;s more expensive. It&#39;s reached about £50 a month now, which is fine but seems a lot for me to pay out to keep it going mostly for myself.&#xA;&#xA;I&#39;ve also got more and more annoyed with &#34;the cloud&#34; in general. I don&#39;t really get why I&#39;m paying all that money for a tiny server and storage when the same amount would go into a physical machine which would blow it away. At the start of my career as a software developer, before everyone went to AWS, I used to run my own servers. People have been scared off of it but it&#39;s a far superior experience and it means we keep the data rather than trusting it to Amazon, Google, Microsoft or whoever.&#xA;&#xA;I&#39;ve been reducing a lot of my reliance on the cloud this past few years, bringing media, backups, home assistant, web servers and a whole bunch of stuff into my home network and serving it out the surprisingly good quality internet connection from Hyperoptic.&#xA;&#xA;Whilst thinking about all this, I got a ping from my phone. Someone had donated to the server. I accept donations although I&#39;ve never really promoted it and I only rarely get one. I&#39;m very grateful to those who have donated but I never wanted anyone to feel obliged.  I&#39;ve never touched the money I received and that last ping took it up to £200.&#xA;&#xA;I had a thought. What if I took that £200 and bought a reconditioned physical machine and moved the server onto that?&#xA;&#xA;So that&#39;s what I&#39;m planning. The machine arrives tomorrow. At some point in the next few weeks - probably after I get back from my holiday in July - I intend to move mcr.wtf onto it.&#xA;&#xA;What does this mean for our users?&#xA;&#xA;The important thing is I have every intention to keep this running for all the current users. Nothing should change for them but I&#39;ll summarise some potential issues:&#xA;&#xA;Performance: The new machine will hugely outperform the current one.&#xA;&#xA;Downtime: Expect a couple of hours of downtime in July while I transfer the database.&#xA;&#xA;Reliability: It&#39;s running from my house now. While Hyperoptic is great, if a construction crew digs up my road, the server goes down.&#xA;&#xA;Registrations: Invite only from now on. I will happily generate invite links if you want to bring friends on board.&#xA;&#xA;I&#39;m probably going to change the about page to reflect some of this change in focus. It currently says it&#39;s a server for Greater Manchester. From now on it&#39;s a server in Greater Manchester. And it actually will be!&#xA;&#xA;Finally, I might add extra services for users. I&#39;ve been inspired by the tilde concept and if I thought any users would be interested, I&#39;d love to build something like that.&#xA;&#xA;Anyway. That&#39;s all for now. Nothing&#39;s going to happen for a few weeks but I&#39;d love to hear if anyone has any thoughts!&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>I&#39;ve been running <a href="mcr.wtf" rel="nofollow">mcr.wtf</a>, a public Mastodon server vaguely targeted at people in Greater Manchester, for about three years now.
</p>

<p>I started it during the big exodus from Twitter when Musk took it over and I guess I did it because I thought it&#39;d be nice to have a Manchester community on Mastodon, but also just because I wanted somewhere to engage with the Fedi myself.</p>

<p>It never really “took off”. Not that I did anything to encourage it to. It did, however, grow a small group of users who use it a fair amount. In some ways this is the best outcome. It works, and the support and moderation load for me is basically zero.</p>

<p>Over the last year I turned off open registration. Almost every new user was a spambot from India. It seemed more trouble than it&#39;s worth.</p>

<p>The only real problem is the growing cost. I run it on Digital Ocean and, although the small instance and backup I have is pretty cheap, the database keeps on growing and that&#39;s more expensive. It&#39;s reached about £50 a month now, which is fine but seems a lot for me to pay out to keep it going mostly for myself.</p>

<p>I&#39;ve also got more and more annoyed with “the cloud” in general. I don&#39;t really get why I&#39;m paying all that money for a tiny server and storage when the same amount would go into a physical machine which would blow it away. At the start of my career as a software developer, before everyone went to AWS, I used to run my own servers. People have been scared off of it but it&#39;s a far superior experience and it means <em>we keep the data</em> rather than trusting it to Amazon, Google, Microsoft or whoever.</p>

<p>I&#39;ve been reducing a lot of my reliance on the cloud this past few years, bringing media, backups, home assistant, web servers and a whole bunch of stuff into my home network and serving it out the surprisingly good quality internet connection from Hyperoptic.</p>

<p>Whilst thinking about all this, I got a ping from my phone. Someone had donated to the server. I accept donations although I&#39;ve never really promoted it and I only rarely get one. I&#39;m very grateful to those who have donated but I never wanted anyone to feel obliged.  I&#39;ve never touched the money I received and that last ping took it up to £200.</p>

<p>I had a thought. What if I took that £200 and bought a reconditioned physical machine and moved the server onto that?</p>

<p>So that&#39;s what I&#39;m planning. The machine arrives tomorrow. At some point in the next few weeks – probably after I get back from my holiday in July – I intend to move mcr.wtf onto it.</p>

<h2 id="what-does-this-mean-for-our-users">What does this mean for our users?</h2>

<p>The important thing is I have every intention to keep this running for all the current users. Nothing should change for them but I&#39;ll summarise some potential issues:</p>
<ul><li><p><strong>Performance:</strong> The new machine will hugely outperform the current one.</p></li>

<li><p><strong>Downtime:</strong> Expect a couple of hours of downtime in July while I transfer the database.</p></li>

<li><p><strong>Reliability:</strong> It&#39;s running from my house now. While Hyperoptic is great, if a construction crew digs up my road, the server goes down.</p></li>

<li><p><strong>Registrations:</strong> Invite only from now on. I will happily generate invite links if you want to bring friends on board.</p></li></ul>

<p>I&#39;m probably going to change the about page to reflect some of this change in focus. It currently says it&#39;s a server for Greater Manchester. From now on it&#39;s a server <em>in</em> Greater Manchester. And it actually will be!</p>

<p>Finally, I <em>might</em> add extra services for users. I&#39;ve been inspired by the <a href="https://tilde.club/" rel="nofollow">tilde</a> concept and if I thought any users would be interested, I&#39;d love to build something like that.</p>

<p>Anyway. That&#39;s all for now. Nothing&#39;s going to happen for a few weeks but I&#39;d love to hear if anyone has any thoughts!</p>
]]></content:encoded>
      <guid>https://write.mcr.wtf/kev/bringing-mcr-wtf-home</guid>
      <pubDate>Sun, 14 Jun 2026 12:00:00 +0000</pubDate>
    </item>
  </channel>
</rss>