Earth Notes: On Website Technicals (2026-09)

Updated 2026-09-28.
Tech updates: battV chart, internal impedance, Homebrew, Golden Gate, off-grid energy, bot block, voltage drop, new backup drive...
Speeding through the equilux, observing how my anticipatory adjustments to the on- and off- grid energy systems work out...

: New Backup Disc

I switched to a (LaCie) portable backup disk today bought a little while ago for Time Machine for my MBA. (£149.95, 4TB, USB 3.2 5Gbps USB-C, LRD0TUB STLR4000400 3JR9P2-570, EAN 87197060435595, UPC 763649174388.) It seems much faster so far in all regards. If it holds, that will be more convenient and save energy and time.

The last one (also 4TB) covered from , with ~10% space still free.

: Ohmic Loss

It seems as if the cumulative resistance from off-grid battery terminals to the USB-C input of my MBA is ~1Ω resulting in ~10W losses. The battery voltage is reported at the controller as ~12.0V at ~40W load with the MBA seeing ~7.8V as reported by AlDente.

: Greedy RSS Bots

My RSS podcast feed has not changed in many months:

149630 Jan 12  2026 rss/podcast.rss

Yet greedy and stupid bots still pound it, ignoring all pacing/cacheing requests in HTTP headers and the RSS file itself:

# Greedy podcast feed pullers: keys are MD5 hashed User-Agent.
# A non-empty txt map lookup of the %{md5:%{HTTP:User-Agent}} means bad!
# Built: 2026-09-17T12:04+00:00 (UTC)
# MAXHITSPERUAPERDAY: 10
# MAXUAS: 25
#----------------
# request-count User-Agent
# MD5hash approx-hits-per-day
#----------------
# 202 Spotify/1.0
4582d9bdbcef42af27d89da91c6eb804 202
# 137 Google-Podcast
8dea568b39db0451edd6b30f29238eaf 137
# 97 atomstr/0.9.13
fed9820e6b1b919d848e718e0bf49e41 97
# 71 Mozilla/5.0 (Maci
dbb1533fc27ea415389d2e9c70c8e051 71
# 59 iTMS
97f76eb7e02c5ff923e1198ff1c288cd 59
# 53 Amazon Music Podc
d69be2563c9f1929edf2906d41809aea 53
# 35 axios/1.6.8
b534882134248c9a5957e0c011a37037 35
# 34 Mozilla/5.0 Apple
fac378ac3b3d3886829021b3309d4fd1 34
# 31 MuckRackFeedParse
62b46fff1cf5f8af7b4b37a2f783b57a 31
# 22 Mozilla/5.0 (Wind
6b9a00393fb1607b0ada13520f814ab5 22
# 22 itms
2e7f714a929b3f52f3c094710819a99a 22

Any bot in this list is polling far too fast.

A sample of slightly-anonymised log entries for bot number 3...

5.75.X.X - - [17/Sep/2026:14:36:01 +0000] "GET /rss/podcast.rss HTTP/2.0" 304 105 "-" "atomstr/0.9.13"
5.75.X.X - - [17/Sep/2026:14:36:01 +0000] "GET /rss/saving-electricity.rss HTTP/2.0" 304 30 "-" "atomstr/0.9.13"
5.75.X.X - - [17/Sep/2026:14:36:01 +0000] "GET /rss/note-on-site-technicals.rss HTTP/2.0" 200 9472 "-" "atomstr/0.9.13"
5.75.X.X - - [17/Sep/2026:14:51:02 +0000] "GET /rss/saving-electricity.rss HTTP/2.0" 304 93 "-" "atomstr/0.9.13"
5.75.X.X - - [17/Sep/2026:14:51:02 +0000] "GET /rss/podcast.rss HTTP/2.0" 304 42 "-" "atomstr/0.9.13"
5.75.X.X - - [17/Sep/2026:14:51:02 +0000] "GET /rss/note-on-site-technicals.rss HTTP/2.0" 200 9472 "-" "atomstr/0.9.13"
5.75.X.X - - [17/Sep/2026:15:06:02 +0000] "GET /rss/podcast.rss HTTP/2.0" 304 105 "-" "atomstr/0.9.13"
5.75.X.X - - [17/Sep/2026:15:06:02 +0000] "GET /rss/note-on-site-technicals.rss HTTP/2.0" 200 9472 "-" "atomstr/0.9.13"
5.75.X.X - - [17/Sep/2026:15:06:02 +0000] "GET /rss/saving-electricity.rss HTTP/2.0" 304 30 "-" "atomstr/0.9.13"

The new strategy will be to unconditionally return 429 status to the top few. That may cause the podcast to drop out of Apple (iTMS) in particular.

# VERY BAD BOT hashed UA appears in flags dir and is non-zero size.
RewriteCond expr "-s '%{DOCUMENT_ROOT}/rss/greedybot/%{md5:%{HTTP:User-Agent}}.flag'"
RewriteRule "^/rss/.*\.rss$" - [L,END,R=429,E=RSS_RATE_LIMIT:2]

There are also bots hiding behind "Mozilla/5.0 (Maci..." and "Mozilla/5.0 Apple..." browser-alike User-Agents that may shut out some legitimate human browser users as collateral damage, such as my own 'Brief' RSS reader plugin.

Maybe actually breaking the feed entirely for these bots may get some attention and behaviour change. (Eg issue filed.)

I expect the persistent bad bots to take many days to notice that they have been completely cut off from content, if they do at all. Coming off this perma-429 will take more days, maybe a fortnight, once the behaviour gets fixed, if it ever does!

A sample of slightly-anonymised log entries for bot number 3 after the change...

5.75.X.X - - [17/Sep/2026:15:21:04 +0000] "GET /rss/saving-electricity.rss HTTP/2.0" 429 711 "-" "atomstr/0.9.13"
5.75.X.X - - [17/Sep/2026:15:21:04 +0000] "GET /rss/note-on-site-technicals.rss HTTP/2.0" 429 598 "-" "atomstr/0.9.13"
5.75.X.X - - [17/Sep/2026:15:21:04 +0000] "GET /rss/podcast.rss HTTP/2.0" 429 598 "-" "atomstr/0.9.13"
5.75.X.X - - [17/Sep/2026:15:36:04 +0000] "GET /rss/saving-electricity.rss HTTP/2.0" 429 711 "-" "atomstr/0.9.13"
5.75.X.X - - [17/Sep/2026:15:36:04 +0000] "GET /rss/note-on-site-technicals.rss HTTP/2.0" 429 598 "-" "atomstr/0.9.13"
5.75.X.X - - [17/Sep/2026:15:36:04 +0000] "GET /rss/podcast.rss HTTP/2.0" 429 598 "-" "atomstr/0.9.13"

This is currently rejecting a greedy RSS bot request roughly every 2 minutes.

This change will not halt malicious snow-shoe activity, eg relayed through rotating 'residential proxies'.

: scream if you wanna go faster?

I have often been on the bad end of poor engineering by Google, from its earliest days (there hang other tales), but a 429 status response does not mean "go on, try again, right now", six times instead of one conditional get after an appropriate retry wait:

173.194.X.X - - [19/Sep/2026:08:07:04 +0000] "HEAD /rss/podcast.rss HTTP/1.1" 429 5240 "-" "Google-Podcast"
173.194.X.X - - [19/Sep/2026:08:07:04 +0000] "GET /rss/podcast.rss HTTP/1.1" 429 946 "-" "Google-Podcast"
173.194.X.X - - [19/Sep/2026:08:07:08 +0000] "HEAD /rss/podcast.rss HTTP/1.1" 429 5240 "-" "Google-Podcast"
173.194.X.X - - [19/Sep/2026:08:07:08 +0000] "GET /rss/podcast.rss HTTP/1.1" 429 946 "-" "Google-Podcast"
173.194.X.X - - [19/Sep/2026:08:07:23 +0000] "HEAD /rss/podcast.rss HTTP/1.1" 429 5240 "-" "Google-Podcast"
173.194.X.X - - [19/Sep/2026:08:07:23 +0000] "GET /rss/podcast.rss HTTP/1.1" 429 946 "-" "Google-Podcast"

Especially given that I am sending a Retry-After header of between ~1h and ~14h, in fact ~4h (ie 14720) as of this writing...

: no Keep-Alive for you!

To minimise resources wasted on bad bots, and stop them immediately re-issuing a bad request on a still-open connection, I am attempting to kill off Keep-Alive on 406 and 429 responses, with (probably not optimal overall):

SetEnvIfExpr "resp('Status') =~ /^429/" nokeepalive=1
SetEnvIfExpr "resp('Status') =~ /^406/" nokeepalive=1

But I do not think that it worked.

Instead I will try directly setting the nokeepalive=1 where I force the 406/429, though that is many more places to maintain, eg:

RewriteRule "^/rss/.*\.rss$" - [L,END,R=429,E=RSS_RATE_LIMIT:2,E=nokeepalive:1]

But I do not think that this worked either.

Success! This set of sample changes closes the connection for bad bots only:

<If "-n reqenv('REDIRECT_nokeepalive')">
SetEnv nokeepalive ${REDIRECT_nokeepalive}
</If>
...
RewriteRule "^/rss/.*\.rss$" - [L,END,R=429,E=RSS_RATE_LIMIT:2,E=nokeepalive:1]

: movement?

There may be some movement: number 4 seems to have dropped two places already. So Amazon is now getting the full cold shoulder instead...

: Off-grid Energy

Energy drawn from the off-grid system (eg to run the router and my laptop) via the solar controller was ~12kWh in August, or ~£4 at grid retail prices. Monitored (via the solar controller) off-grid energy is ~5kWh so far this month.

% cat /var/log/powermng/202608??.log | awk '$8=="P" && $9>=0 {++n; mWh += $9/6; } END {print mWh/1000}'
11896.4
% cat /var/log/powermng/202609??.log | awk '$8=="P" && $9>=0 {++n; mWh += $9/6; } END {print mWh/1000}'
5432.97

The off-grid battery is now regularly not carrying the router at night, but the grid-tried Enphase battery has not yet fully emptied.

: macOS Upgrade

I upgraded (unexpectedly, in two steps) to macOS Tahoe 26.7, then Golden Gate 27. Seems broadly OK.

: Homebrew Troubles

Homebrew sometimes tries to summon x86 parts on my MacBook Air M1 and fails. Even a full upgrade to 7.0.0 still seems to leave it confused.

So, knowing that this is likely to cause me lots of pain later, I am doing an uninstall of the x86 parts.

: MIA

% brew install coreutils

was needed to bring back nproc and tac.

: Battery Impedance Tweak

Dropped back to 128mΩ internal impedance estimate as more realistic, given that other anti-oscillation measures (mainly greater dump depth) have been taken.

This should improve the USoC% estimate significantly. It may still need better correction (increase) for lower temperatures.

20260913 battV
Better behaviour and less USoC% flailing the next morning with nominal `e' threshold at 39%.

: Updated Off-grid Battery Chart

I added a USoC% (grey) line on y2 (W) scale to the battV chart.

20260901 battV
New version of chart after all changes today (V3).

Rolling 12M Carbon

Net electricity utility energy kgCO2e over last 12 calendar months (before 2026-09): -64

Net kgCO2e for each of the last 12 full calendar months: -8 11 27 42 52 28 -2 -22 -40 -52 -60 -40

uptime

 07:34:50 up 369 days, 19:05,  1 user,  load average: 0.54, 0.51, 0.47