Blog
Articles on data platforms, ML in production and small open-source tools.
- 13 Nov 2026 loki-alert-lines: the log lines behind Loki and Grafana alerts
A proxy between the Loki ruler or Grafana alerting and Alertmanager that derives a log query from each alert rule and adds the matching log lines to the alert.
- 12 Nov 2026 influx-reshape: renaming and retyping tags and fields in InfluxDB
A command line tool that renames, drops and retypes tags, fields and measurements in a running InfluxDB 1.x or 2.x, with a count check after every step.
- 11 Nov 2026 nc-app-purge: removing what uninstalled Nextcloud apps leave behind
A command line tool that finds the tables, settings, background jobs and appdata of removed Nextcloud apps, attributes them through the apps' own migrations and deletes them with a backup that can be restored.
- 10 Nov 2026 nocodb-transfer: copying NocoDB bases between installations
A command line tool that exports a NocoDB base with its links, lookups, rollups, formulas, attachments and views, rebuilds it on another installation and compares both record by record.
- 9 Nov 2026 es-changefeed: a change feed for Elasticsearch and OpenSearch
A program outside the cluster that turns shard sequence numbers and global checkpoints into a stream of created, updated and deleted documents.
- 9 Nov 2026 mimir-rewrite: deleting series in Grafana Mimir's long-term storage
An operator tool that deletes, relabels or hashes series in the TSDB blocks Grafana Mimir keeps in object storage, and swaps the blocks in an order the compactor and store-gateways handle.
- 6 Nov 2026 k6-fleet: distributed k6 tests without Kubernetes
A controller and agent that run one k6 test across several machines over ssh or Docker and evaluate thresholds, abortOnFail and the summary on the merged data.
- 5 Nov 2026 pgfederate: one PostgreSQL endpoint over many data sources
A gateway that speaks the PostgreSQL protocol and runs joins in an embedded DuckDB, so Metabase and Grafana can query PostgreSQL, MySQL, files and REST APIs through their normal PostgreSQL driver.
- 4 Nov 2026 npm-trust-downgrade: checking npm lockfiles for provenance downgrades
A small tool that reads a package-lock.json, transitive dependencies included, and reports versions published with weaker trust evidence than earlier releases of the same package.
- 3 Nov 2026 uv-lock-merge: a git merge driver for uv.lock
A small tool that merges uv.lock files package by package during git merges and rebases, so both branches' locked versions survive and the result is written in uv's own layout.
- 2 Nov 2026 sandbox-shell: a shell in the sandbox of a systemd service
A small tool that reads a unit file and its drop-ins and starts a shell or command with the same user, environment and sandbox settings, also when the service is not running.
- 1 Nov 2026 shutdown-blame: systemd-analyze blame for shutdown
A small tool that reads the journal of the previous boot and lists the units systemd stopped during shutdown, sorted by how long each stop took.
- 31 Oct 2026 compose-inline: Compose configs and secrets on a remote Docker host
A wrapper around docker compose that passes local config and secret files by value, so that projects using them start on a remote Docker host.
- 30 Oct 2026 docker-cpg: docker cp with wildcards
A wrapper around docker cp that adds wildcards, several sources and excludes, and that also works on stopped containers and images without a shell.
- 29 Oct 2026 ubuntu-latest-check: finding workflow jobs that break on Ubuntu 26.04
A checker that reads GitHub Actions workflows and lists the ubuntu-latest jobs that will fail on Ubuntu 26.04 because of removed apt packages, missing setup-python builds or old Playwright versions.
- 28 Oct 2026 galaxy-uninstall: removing Ansible collections
A command that removes installed Ansible collections, shows which copy Ansible loads, and refuses to delete collections that others still depend on.
- 27 Oct 2026 journalctl-not: NOT matches for journalctl
A wrapper around journalctl that hides entries by unit, identifier, field value or message pattern and keeps the normal journalctl output, including colors, pager, -n and -f.
- 26 Oct 2026 gh-cache-download: download GitHub Actions caches
A gh extension and a composite action that download a GitHub Actions cache entry by key, so its contents can be inspected locally.
- 24 Oct 2026 gitignore-excludes: .gitignore rules for restic and borg
A small tool that asks Git which paths are ignored in every working tree below a directory and writes them as an exclude file for restic or borg.
- 23 Oct 2026 yq-keep: yq edits without reformatting the file
A small tool that applies a yq expression to YAML files in place and changes only the lines the edit touches, keeping blank lines, indentation and comment spacing elsewhere.
- 22 Oct 2026 envfile-compat: one .env file for docker run and Compose
A small tool that shows where docker run --env-file and Docker Compose read the same .env file differently and converts the file into the form docker run expects.
- 21 Oct 2026 claude-rc-keep: keep Remote Control sessions online
A small tool that restarts Claude Code Remote Control sessions after a reboot or a killed process, so the open web session reconnects with the full conversation.
- 21 Oct 2026 lfs-size-track: Git LFS tracking by file size
A pre-commit hook that moves every staged file above a size threshold into Git LFS, using the stock git-lfs client.
- 20 Oct 2026 claude-relocate: move Claude Code sessions with the project folder
A command-line tool that moves Claude Code sessions, project settings and prompt history to a project's new path after the folder was renamed, moved or copied to another machine.
- 20 Oct 2026 pr-rescue: find stalled pull requests in other repositories
A command-line tool that lists your pull requests in repositories you do not own, sorted by who has to act next, and finds the ones a stale bot closed.
- 19 Oct 2026 git-leftovers: finding work that exists only on one machine
A small tool that checks every Git repository under a directory for uncommitted changes, unpushed commits, stashes, missing remotes and credential files in the history.
- 18 Oct 2026 Anki-KaTeX-Markdown: Markdown and KaTeX in Anki cards
An Anki add-on I wrote in 2021 that creates a Basic and a Cloze note type which render Markdown and KaTeX: how the cards render, what users report in the issues, and what changed over the releases.
- 18 Oct 2026 battery-passport-kit: checking EU battery passport data
A command-line tool that turns CSV rows into EU battery passport records, validates them against the BatteryPass-Ready schemas and reports missing required elements per data element group.
- 18 Oct 2026 claude-code-gc: removing old Claude Code versions
A small Linux tool that lists the Claude Code versions that updates leave on disk, shows which ones running processes still use, and removes the rest.
- 18 Oct 2026 diskdelta: which directories grew on the disk
A small tool that records directory sizes on every run and prints the growth since the previous run and since a week ago, with an optional alert for low free space.
- 1 Oct 2026 Reducing the peak memory of secure transformer computation step by step
My master's thesis measured where the peak memory of cryptographically secured transformer computation goes and reduced it one measured change at a time. The harness, every step and the raw logs are public.
- 1 Jun 2026 A battery analytics platform for 100k+ IoT devices
As the sole developer I built a battery analytics platform for 100,000+ IoT thermostats: a tested capacity and runtime estimation library on an internal PyPI, Dagster ingestion, FastAPI services, dashboards, and monitoring.
- 1 Jun 2026 What I worked on in llm-d
My merged pull requests to the llm-d project: mostly CI hardening, tests and observability, plus one flow-control configuration option and a few small bug fixes.
- 27 May 2026 aipreflight: a CI gate for AI applications
aipreflight runs eval, cost, latency, observability and rollback checks against an AI application and returns one verdict and an exit code that a CI step or deploy job can act on.
- 16 May 2026 A readiness gate for LLM endpoints: the inference profile of aipreflight
The inference profile of aipreflight probes an OpenAI-compatible endpoint from the client side with llmprobe, checks the results against SLA thresholds and can compare them with vLLM metrics from Prometheus.
- 8 May 2026 Estimated LLM API cost of the OpenAI cookbook from a static tokentoll scan
A static scan of openai-cookbook with tokentoll found 24 LLM API call sites. At an assumed 1,000 calls per call site and month, the estimate is $1,884 per month, 68% of it from four gpt-5 call sites.
- 8 May 2026 Median time to first token of 15 LLM APIs in an early snapshot of an hourly benchmark
Hourly probes to 15 models from OpenAI, Anthropic, Google, DeepSeek and xAI through OpenRouter. In this snapshot, median TTFT ranged from 321ms to 4,226ms. The raw data is public.
- 7 May 2026 Building a data platform with dbt, Dagster, and ArgoCD
How I built an ELT analytics platform for an IoT thermostat fleet: Dagster for extraction and loading, dbt for transformations, Sqitch for schema migrations, ArgoCD for deployment, and an allowlist for PII.
- 7 May 2026 Evaluating battery prediction algorithms on field data before fleet rollout
An evaluation pipeline for battery prediction algorithms on 100k+ IoT devices: monthly datasets from field data built with Dagster, manual sample review, an isolated virtual environment per algorithm version, MLflow tracking, and a separate service for the fleet-wide rollout.
- 5 May 2026 Latency of six LLM APIs over seven days, measured with llmprobe
60,480 probes to GPT-4o-mini, Claude 3.5 Haiku, Gemini 2.0 Flash, Llama 3.3 70B, DeepSeek Chat and Mistral Small through OpenRouter. Time to first token, total latency, throughput and errors, measured client-side once per minute.
- 3 May 2026 tokentoll: cost changes of LLM API calls in code review
Design of the first version of tokentoll, which estimates the monthly cost of LLM API calls from source code and shows how a git diff changes it.