I spent a couple of days migrating our monitoring stack from self-hosted kube-prometheus-stack (KPS) to GKE’s native Google Managed …
22 Why VPA ignores single-replica podsTLDR: VPA’s updater defaults to requiring 2 replicas before it will evict a pod. Single-replica deployments are silently excluded from …
21 Getting my Apple Watch workout history into GarminTL;DR — I switched from an Apple Watch to a Garmin and wanted to bring my workout history with me. Apple’s data export turned out to be …
17 Fixing Spotlight Search for Applications on macOSTL;DR: If Spotlight can’t find your apps, rebuild the Launch Services database with lsregister. It takes a few seconds and doesn’t require a …
8 jj for Git Users: A Practical WalkthroughTL;DR: jj (Jujutsu) is a Git-compatible version control system with some interesting ideas — automatic change tracking, universal undo, and …
6 Why Jetson Nano Still Matters in 2026TL;DR: Jetson Nano is old and stuck on Ubuntu 18.04-era software, but it’s still a great always-on host for bounded edge workloads like …
6 Mutating webhooks and ghost affinity on StatefulSetsTLDR: Mutating admission webhooks that inject scheduling rules (nodeSelector, tolerations, affinity) persist on StatefulSet pods even after …
6 Bulk cleaning stale git worktrees and branchesI use git worktrees heavily for parallel development. One worktree per ticket, across dozens of repositories. They’re especially useful if …
2 Rewriting Git History with an LLM for Conventional CommitsTL;DR: Feed your entire git log + file lists into a single LLM call to generate a bash hash map of conventional commit messages, then apply …
2 Upgrading OpenClaw to Latest on Jetson Nano with Node 22This is a follow-up to my original post, Installing OpenClaw on a Jetson Nano, where I got things working with Bun on Ubuntu 18.04. That …
TLDR: Go doesn’t auto-detect container memory limits. Without GOMEMLIMIT, the GC lets the heap double freely until the OOM killer strikes. …
23 Stop re-running BigQuery queries when paginatingI recently learnt something about BigQuery pagination that I wish I’d known sooner. If you’re paginating BQ results with LIMIT/OFFSET in the …
18 Happy — controlling Claude Code from your phoneHappy lets you control Claude Code sessions from your phone. You run happy instead of claude, scan a QR code, and your session shows up on …
16 How Cloudflare proxy mode silently breaks SendGrid email deliveryTLDR: If you manage SendGrid DNS records in Cloudflare, make sure PTR-related records are set to DNS-only. Proxying them silently breaks …
15 Switching from Poetry to uvI migrated a few Python projects from Poetry to uv. The conversion is mostly mechanical, so this focuses on what changed and why it was …
13 Kubernetes health probes for stateful Python servicesTLDR: If your entrypoint script doesn’t use exec, SIGTERM never reaches your Python app and graceful shutdown silently does nothing. Docker …
12 Fixing slow Docker builds on ephemeral CI runnersTLDR: --mount=type=cache makes RUN layers non-deterministic. On ephemeral runners the mount is always empty, so BuildKit can’t match layers …
9 SSH fallback hosts with ProxyCommandI have a Jetson Nano at home that I SSH into from my laptop. At home it’s on a local IP, but when I’m out I reach it via a public IP. I got …
8 Installing OpenClaw on a Jetson NanoThe idea of messaging an AI assistant from my phone while I’m out walking and having it write code that I can steer — “try this approach …
8 Fixing HDMI resolution on a Jetson NanoI connected my Jetson Nano to an external projector and the console text was microscopic. The framebuffer was running at 3840x2160 (4K) on a …
7 Running HPA and VPA together on KubernetesTLDR: HPA handles horizontal scaling on CPU, VPA right-sizes memory. Split their concerns with controlledResources: ["memory"] so they don’t …
6 Batch updating files across GitHub repos without cloningI needed to roll out the same GitHub Actions workflow change across a bunch of repositories. Doing it repo by repo via …
4 Pulling Twilio Usage Data into Google SheetsI needed to track daily Twilio costs in a spreadsheet. The Twilio console has usage data but no easy export, and I wanted it updating …
4 Using Google Sheets API with gcloud ADCI wanted to pull data from a Google Sheet using curl and my existing gcloud credentials. Should be simple, right? The naive approach …
1 Getting VPA resourcePolicy right in Helm chartsTLDR: Templating VPA minAllowed from deployment resource requests prevents VPA from reducing resources. Popular charts make these fields …
For four years I thought kubectl required gcloud auth login. But I also needed ADC for scripts and apps, so every time my tokens expired I’d …
22 Pruning Claude Code conversation historyA few days ago I cleaned up 200GB from my Mac and deliberately kept my Claude Code history at 2.3GB. Four days later it had grown to 9.5GB. …
18 Extracting Travel Data from macOS Photos LibraryI was updating my about page and wanted to add a timeline of places I’ve travelled to. I’ve got thousands of geotagged photos in my Photos …
18 Using Claude to free 200GB from a nearly full diskMy Mac was close to 100% full. macOS was complaining and I couldn’t install updates. Here’s how I used Claude to analyse my disk usage and …
14 Making bumpver play nice with uvI was setting up automated version bumps for a Python project using bumpver and uv. The problem: when bumpver updates the version in …
6 Migrating from a GitHub bot user to a GitHub AppWe had a dedicated “bot” user account for GitHub automation - creating PRs, pushing commits, merging branches. It worked, but it always felt …
5 CCS: Search for Claude Code conversationsI’ve accumulated hundreds of Claude Code sessions and kept losing track of where I solved specific problems. The built-in /resume shows …
I’ve been using Neovim full-time for a couple of years now. Here’s my current setup - built on LazyVim with a focus on Python development …
27 Python tools I used in 2025I’ve overhauled my Python development setup over the past year. The ecosystem has improved dramatically - faster tools, better defaults, and …
27 Kubernetes debugging in 2025My Kubernetes workflow changed a lot this year. The biggest shift: I started using LLMs as a debugging partner. Combined with a few CLI …
22 Developing Magento plugins on Kubernetes with git-syncThis is Part 2 covering plugin development. Part 1 covers setting up Magento on Kubernetes. With Magento running on Kubernetes, you can use …
18 Deploying Magento to KubernetesThis guide covers deploying Magento 2.4.8 to Kubernetes with MariaDB and OpenSearch as sidecars. The key benefit: disposable environments. …
17 Git worktree helper with fzfI use git worktrees constantly for parallel development, but typing git worktree list, copying the path, and cd-ing got tedious. So I wrote …
16 Cleaning up DockerMy disk was filling up with old Docker images. I got a low disk space warning and traced 80GB back to Docker. Here’s how to reclaim space. …
14 Deploying to Cloudflare Pages with wranglerI was deploying a SvelteKit app to Cloudflare Pages and wanted to do it from the command line rather than connecting to GitHub. Wrangler …
10 Silencing alerts properly in AlertmanagerI was doing planned maintenance on a Kubernetes cluster. Within seconds of starting the work, my phone was buzzing with PagerDuty alerts. I …
9 Fix gcloud PATH in shellAfter installing gcloud, the gcloud command wasn’t found. The PATH wasn’t set up properly. This happened after I upgraded macOS and my shell …
4 OpenSSL certificate testing with SNII was debugging why HTTPS requests to app.example.com were failing with certificate errors. The certificate on the server was valid, but …
1 GitHub PR commands with ghUsing gh for PR work is much faster than the web UI, and allows staying in the terminal. It eliminates the need to constantly reach for the …
1 Advent of Code tipsI started Advent of Code 2025. Here are some tips I’ve picked up. My solving workflow Link to heading Read the problem twice - I often miss …
I needed to check what was in a GCP secret to debug why an application wasn’t starting. Here’s how we inject secrets into GKE workloads, …
27 Viewing Docker container logsI left a container running over a long weekend and came back to find it had consumed 50GB of disk space with logs. The application was …
26 Getting your public IP with curlI needed to find my public IP to add it to a firewall allowlist. curl ifconfig.me That’s it. Returns just your IP address. Why you need to …
25 PostgreSQL WAL monitoringAt 2am, I got an alert: database disk usage at 85%. Logged in, checked the usual suspects (tables, indexes, temp files), and everything …
25 Connecting to Cloud SQL with gcloudI needed to connect to a Cloud SQL instance to debug a data issue. Here’s the quick way to get a psql session without fiddling with IP …
24 Running local stacks with Docker ComposeI use Docker Compose for local multi-service environments because it keeps runtime config in one file and makes startup/teardown repeatable. …
24 Searching code across GitHub with ghI needed to find all the places in our GitHub org that were using a deprecated GitHub Actions runner label. We were migrating from runs-on: …
20 Troubleshoot stuck ArgoCD syncsI was debugging why a Kubernetes deployment wasn’t updating after merging a PR. The manifest was in git, but the cluster was still running …
19 Web scraping with Selenium: quick setupI needed to scrape property listings from a real estate site that heavily relied on JavaScript to load content. The page source was empty …
19 Cost-optimising GKE with ComputeClassTLDR: I built gkecc to generate cost-optimised GKE ComputeClass specs from live pricing data. It sorts by total cost (CPU + RAM), not just …
19 direnv Python path issuesI was setting up a new Python project with direnv to manage environment variables. Suddenly python wasn’t found, even though it was …
18 Content Security Policy headersTLDR: Start with default-src 'self' and add exceptions as needed. Use report-only mode first to avoid breaking your site. I added CSP to a …
17 pytest-asyncio mode configurationI was getting warnings about pytest-asyncio decorators. Here’s the fix. Why async tests are tricky Link to heading Async tests need an event …
17 Pydantic v2 migration tipsPydantic v2 is a ground-up rewrite with a Rust core, and it shows - validation is noticeably faster. But the migration isn’t trivial. I …
12 Migrating from Redocly to DocusaurusI was evaluating Docusaurus as a replacement for our Redocly docs site. We had around 200 documentation pages and needed more flexibility …
8 FastAPI patterns for production APIsFastAPI has a few defaults that make API services easier to maintain: request validation, typed contracts, and built-in docs. These are the …
GKE has four layers of autoscaling that work together: HPA, VPA, cluster autoscaler, and NAP. Understanding how they interact saves a lot of …
21 Sentry DSN configurationI was setting up Sentry for a new Python service. The first time I ran it locally without a DSN configured, the app crashed at startup. …
17 Debug Helm charts before deploy with helm templateI was trying to figure out why my Helm chart wasn’t rendering correctly. A missing if condition meant a ConfigMap wasn’t being created in …
15 Debugging Kubernetes HPA scalingI’d been using HPAs for a while without really understanding them. They worked, so I never looked closely. Then I noticed a service was …
12 Kubernetes tolerations and node selectorsPods were stuck in Pending and I couldn’t figure out why. kubectl describe showed “0/12 nodes are available: 12 node(s) had taint that the …
11 Querying GCP logs with gcloudI needed to search Cloud Logging for specific events from the command line. The CLI is much faster than clicking through the Console when …
10 Keeping Homebrew packages up to dateI hadn’t run brew upgrade in a couple of months and suddenly gh started failing with cryptic errors. Turned out I was three major versions …
10 Moving commits between branches with cherry-pickI’d been working on a feature branch and accidentally committed a bug fix to it instead of main. The fix needed to go out now, but the …
10 Replacing venv script workflows with uv runWhen sharing quick Python scripts, the old workflow is usually: create a venv, install dependencies, and document setup steps. uv run …
TLDR: Certificate not ready? Check resources in this order: Certificate → CertificateRequest → Order → Challenge. The issue is usually at …
15 Setting up Dependabot for uv projectsAfter migrating a project to uv, I noticed Dependabot PRs were still being created but CI was failing. Dependabot was updating …
12 Psql connection patterns I use for debuggingI needed to connect to a PostgreSQL database for debugging production issues. After years of copying connection commands from Slack, I …
8 Shelving changes with git stashTLDR: git stash to save, git stash pop to restore. Use -m "message" if you’ll have multiple stashes. I was halfway through a refactor when …
5 Debugging APIs with curl and jqI was debugging why a webhook wasn’t firing. The API was returning something, but staring at a wall of minified JSON in the terminal wasn’t …
4 Undoing commits with git revertI once pushed a commit that broke production. The fix was already in progress but would take an hour. git revert let me undo the damage …
2 Setting up Claude CLI with MCPI wanted Claude to help me manage Linear tickets without leaving my terminal. The Model Context Protocol (MCP) makes this possible. Here’s …
2 Tmux session and pane commandsI started using tmux to keep terminal sessions running after disconnecting from SSH. Here’s what I use most. Quick session workflow Link to …
I spend too much time switching between my terminal and Linear’s web app. The Linear CLI lets me manage tickets without leaving my editor. …
7 Syncing files from GCS with gcloud storageI needed to download a bunch of files from a GCS bucket to process them locally. gcloud storage rsync does the job, and it’s noticeably …
7 Alembic migration historyI was investigating a production issue where a table column was missing. Turned out someone had merged a migration that dropped it without …
6 DNS lookups with digWhen an endpoint times out, I check DNS early to rule it in or out quickly. dig gives a fast sanity check before digging into app or network …
4 Monitoring Kubernetes with watch and topI was watching a deployment roll out and kept running kubectl get pods over and over like a nervous habit. Then I discovered watch and felt …
1 Viewing Kubernetes pod logsI spent 20 minutes staring at empty kubectl logs output wondering why a crashing pod had no errors. The container was restarting before I …
TLDR: My order is describe → logs -p → events → exec. Most failures show up in events or previous logs. When a pod is in CrashLoopBackOff, …
26 Rsync file sync patternsRsync is reliable for repeat syncs, but small flag mistakes can be destructive. I use a dry-run-first workflow, especially with --delete. …
25 Managing Kubernetes deploymentsI once deployed a config change that crashed pods on startup. The rollout was halfway through before I noticed - half the replicas were …
23 Analysing Svelte build chunksI was working on a SvelteKit dashboard application and noticed the initial page load was sluggish. After investigating, I found we had over …
23 Formatting PHP with php-cs-fixerI was working on a legacy PHP WooCommerce plugin that had inconsistent formatting - some files used tabs, others spaces, brace styles were …
23 Setting up pre-commit hooksI was tired of catching trivial issues in PR reviews - trailing whitespace, missing newlines, formatting inconsistencies. Pre-commit hooks …
21 Pytest tips: last failed and specific testsI run pytest a lot. Here are the flags I use most. My development workflow Link to heading When I’m writing code, I typically: Write the …
21 GCloud workload identity for GitHub ActionsI was setting up GitHub Actions to deploy to GCP and needed to use workload identity instead of service account keys. Here’s how to manage …
21 Ruff, the fast Python linterI switched to Ruff because it’s ridiculously fast. On a ~50k line Python codebase, Flake8 + isort + pylint took about 45 seconds. Ruff does …
21 Import existing resources into Terraform without downtimeI migrated manually created GCP workload identity pools and GitHub repositories into Terraform so they could be managed consistently in …
21 Git worktrees for parallel developmentI was constantly stashing changes to review PRs or fix urgent bugs on other branches. Stash, switch, fix, commit, switch back, pop stash, …
21 Modern CLI tools: fd and ripgrepI stopped using find and grep ages ago. fd and rg (ripgrep) are faster and have better defaults. Switching to these was probably one of the …
20 Publishing Python packages to Artifact Registry with uvI spent way too long trying to get uv publish to work with Google Artifact Registry. The docs suggest using keyring, but that led me down a …
I have been working on an Ethereum lottery Dapp with folks attending a meetup hosted by Strange Labs (Gloucester Road, Bristol - NOW CLOSED) …
I often log into a remote SSH terminal to use an ipython shell. In doing so, it is necessary for me look at figures invoked by matplotlib as …
8 Enabling MathJax on a Jekyll server when offlineI like MathJax. It does a great job displaying equations on web pages written using $\rm\LaTeX$. However, I recently wrote a Jekyll blog …
3 File/text was not valid utf8 encodedIn the process of writing my thesis, I had to frequently check that I was not exceeding the word limit by running the following command: …
After installing TSS’s Aimsun 8.1.3 on Ubuntu 16.04 (x64 build) on my machine, I tried to launch the program. However, the icon would appear …
My presentation for Geomob in London:
Sometimes, the mundane assumes a surreal form and takes one by surprise. I had the pleasure of this encounter this morning and I felt the …
18 What me eat by Macka BI love this song. Vegan solidarity! Here is the lyrics borrowed from this site: [Intro] Selamta (Greetings in Amharic) Ital (natural) we …
17 Use crontab to log CPU temperature on OSX!I have just set up a way to automatically log temperature using OSX terminal because my computer was frequently overheating and I wanted to …
Finding and deleting files and folders in OSX is simple. Open your terminal. In order to just find your files/folders (non destructive): For …
I had to convert lots of OSGB EPSG:27700 raster files to LonLat EPSG:4326 format and here is how I did it on my OSX terminal. I also wanted …
6 Fastest way to access a list that is a subset of an even bigger listSay I have a list of objects called agents with 100,000 objects. I have a second list called agents_per_step which refers to 39,393 objects …
On 11 May, Bristol Green Party hosted a forum to discuss housing and energy at The Station in central Bristol. The meeting was chaired by …
12 Bristol People’s Question TimeOn 10th March, Bristol People’s Assembly hosted People’s Question Time at City Road Baptist Church in Stokes Croft. In the panel were Rufus …
11 Another Angry VoiceAnother Angry Voice (AAV) aka Tom paid a visit to Bristol on 5th March. AAV introduced himself as a regular guy and emphasized that if he …
10 How well does population distribution predict evacuation time?Previously, we tried to predict 90th percentile evacuation time $T{90}$ determined from ABM simulation using 90th percentile free flow …
4 First post!I have just updated the website and finally acquired brtkwr.com for good which is now hosted on Github pages too which is an excellent free …