Writing

Thinking in public

Essays on being a CTO, on AI in practice and on engineering leadership, plus the technical notes I wrote so I would not have to solve the same problem twice. RSS feed.


2026

  1. mdread: a Markdown reader with 10% of the features, built for speed and a 4K screen

    I wanted a Markdown reader with 10% of the features of every other reader and editor, as fast as possible, and using all of my 4K screen. So I built one in Rust.

    4 min readCodeRustLinux
  2. A whole replay in a URL: how Flappycar's ghost links work without a backend server

    How Flappycar sends a friend your entire run as a ghost to race, with no backend server: a fixed physics step, a seeded course, and every tap packed into a couple of hundred bytes of URL.

    6 min readAICodeJavaScriptGame development

2025

  1. The Gotcha Game That Drives Great Engineers Away

    Most tech interviews are a game of gotcha that makes the interviewer feel clever and loses solid builders. The best interviewers are great conversationalists who listen.

    1 min readCTO
  2. How will we train junior developers in a world of generative AI?

    Generative AI is delegation, not just abstraction. How do juniors build the judgement to use it well, and what should teams and employers change?

    2 min readCTOAICareer
  3. The Illusion of Democratized AI — And Why It Should Worry You

    Training frontier models is structurally out of reach for all but a few hyperscalers. Why that concentration of compute is a strategic risk for everyone building on top.

    1 min readCTOAILeadership
  4. Your real team as CTO

    One of the biggest mistakes new CTOs make is thinking their team is still the tech team. Your real team is the executive team, and that changes how you spend your week.

    1 min readCTOCareer

2023

  1. Easy async function execution in Python/Django using a queue and consumer Thread

    Run API calls and tracking writes off the request thread in Django without Celery or django-q: a queue and a consumer thread are enough.

    1 min readCodePython

2021

  1. How to work for an international software company from SA and maximise your earnings

    A practical guide for South African developers on landing remote work with European companies, running as a sole proprietor, invoicing, forex and provisional tax.

    3 min readCareer

2016

  1. How to timeout a thread in Java / Limiting a threads execution time

    Limit how long a piece of Java code may run using thread interruption and a timeout, and the catch that stops it working on arbitrary code.

    1 min readJava
  2. How to communicate between your Chrome extension and your SPA web app

    Two-way messaging between a Chrome extension and a single-page app using Chrome's external messaging API, with the background script, manifest and web app code.

    1 min readJavaScript

2015

  1. I get NoNodeAvailableException on long-running processes using SSL TransportClient with Found.no

    A hosted Elasticsearch hostname resolves to several IPs. Add only the first to a TransportClient and long-running processes eventually fail with NoNodeAvailableException.

    1 min readJavaElasticsearch
  2. When I index something in Elasticsearch, why doesn't it show in my search straight after?

    Elasticsearch is near-real-time: new documents appear after the next refresh. What that means and how to force it when you must.

    1 min readDevOpsJavaElasticsearch
  3. Why does Apache Nutch sometimes get stuck using a single thread and crawling slowly?

    Why an Apache Nutch crawl collapses to a single fetch queue, and the generate.max.count setting that keeps it spread across sites.

    1 min readDevOps

2014

  1. Centralising Clojure/Java logging with Logback, LogStash, ElasticSearch, and Kibana

    Shipping Clojure and Java logs from Logback through Logstash into Elasticsearch, and reading them in Kibana.

    1 min readDevOpsJavaClojureElasticsearchLinux

2013

  1. Keybinding for emacs helm to recursively grep certain file extensions in your src directories

    A short Emacs Lisp function that binds a key to a recursive Helm grep over your source directories, limited to the file extensions you care about.

    1 min readEmacs

2012

  1. Deploying Datomic free on EC2 or any Ubuntu system

    Installing Datomic Free on Ubuntu or EC2 with an Upstart script, a symlinked runtime for painless upgrades, and rdiff-backup for backups.

    1 min readDevOpsLinux
  2. Integrating Logback with Clojure

    Getting Logback working as the logging backend for a Clojure project.

    1 min readJavaClojure