Sign up

Jakob Külzer's Blog

Not verified No WebSub updates No webmention support Valid

Recent content in Welcome on ilikeorangutans

Generator
Hugo
Rights
© 2026 Jakob Külzer
Public lists
I ♥ RSS
Fetched

Jakob Külzer's Blog Valid
Text

3D Printing Speaker Mounting Plates

After years of having a 3D printer I finally put it to use to fix something like I said I would. Long story short, the tweeters in the car burnt out and I ordered replacements but the mounting plate the replacements came with required me to drill a hole into the plate to fit the speakers, and though this would have been an excuse to buy a holesaw, I opted to just spend at least 4 times the amount of time to model the correct part in FreeCAD and print the part.

Jakob Külzer's Blog Valid
Text

journald Volatile Storage

I’m in the process of moving my homelab servers to NixOS. I moved a few machines over and was monitoring them when I noticed that one of the machines was constantly writing 400-500 kB/s to disk. After some digging I found that journald was the culprit for the IO; well, technically the culprit is another service that was spamming the logs, but that’s not important right now. I didn’t want the constant writes for logs to add to the wear and tear of the storage because with the current prices for anything memory that’s just wasting money. I now collect logs centrally via alloy/loki, so there’s not really a reason to keep them on the machine’s disk itself. After some research I found that journald can write logs to a in-memory location instead of disk: Setting Storage to volatile will enable that behaviour. By default it’s set to persistent in nixos meaning

Jakob Külzer's Blog Valid
Text

Exploring Neural Networks -- The first Layer

I’ve taken an interest in neural networks and am currently trying to build one from ground up. Synthesizing some of the things I’ve learned so far because that’s how my brain absorbs.

Jakob Külzer's Blog Valid
Text

Building this Blog on Push with Forgejo and Woodpecker

You might or might not know that this blog is hosted on a small single board computer in my basement and until recently I’d write or edit my posts, rebuild it locally and then push the built files up to the server hosting the static files. Works, but cumbersome and I’d frequently push drafts by accident. Not a big deal since drafts are also in Git, but still, unprofessional. But the beauty of a homelab is that you can automate things with as much or as little effort as you want. And automate I did.

Jakob Külzer's Blog Valid
Text

Code Generation in Go as an Accelerator

So recently, against my best judgement, I’ve started working on a new project. The classic “how hard can it be?” kind of thing. What that actually is is not important right now. More important are the tech choices and how I shifted my opinion on generated code.

The tech stack I went with is what I usually pick; go for backend, pgx and sqlc for database access, htmx for frontend matters. I found managing Go’s template/html always a bit fiddly and wanted a better way of dealing with nested components and being able to render them individually. I have seen templ recommended many times and because it was a new project, I gave it a try. Initially I felt having yet another tool that generates go was weird, but after a few components I was sold.

Jakob Külzer's Blog Valid
Text

Automatically Create Thumbnails with Hugo Render Hooks

Hugo has a really way of hooking into the rendering process that I’m using to automatically generate scaled down thumbnails of referenced images. I structure each blog post as a page bundle and render images via ![](image-name.jpg) in the markdown files. By default, hugo will render an image tag with the full sized image which can be rather heavy if it’s a large image. So instead, I set up a render hook for images in layouts/_markup/render-image.html:

Jakob Külzer's Blog Valid
Text

Postgres Structure and Query Deep Dive

In an effort to understand Postgres better I’ve worked my way through how a Postgres database is structured and executes queries.

Process Model

Postgres uses a process-per-worker model. That means every connection is handled by a separate operating system process forked off the initial process.

Subsystem Overview

Postgres consists of several components that all work together to process data and ensure it’s reliably written and can be looked up efficiently. The following are the most important components, but there more, other components that are beyond the scope of this post.

Jakob Külzer's Blog Valid
Text

Verify Your Backups

Let me tell you how I was an idiot, ignored best practices, and luckily didn’t lose anything of value. And yes, this is a story about backups.

Jakob Külzer's Blog Valid
Text

Passwordless sudo with remote `nixos-rebuild` and SSH keys

In my homelab I now have a few machines that run NixOS. This came to be because I wanted the ability to quickly rebuild machines from scratch without having to fiddle with individual settings. Thanks to NixOS I now have a repository that holds a flake that can build bootable images and perform remote nixos-rebuild switch.

Jakob Külzer's Blog Valid
Text

Moving My Blog

It’s this time of the year again. I’ve recently set up this little page, and I really didn’t want it to be on Github or hosted by Github Pages.

Jakob Külzer's Blog Valid
Text

Senior Software Developer, Datastores

Jakob Külzer's Blog Valid
Text

Building NixOS images for aarch64 from a x86 Build Platform

In my homelab I run many different single board computers, among them Odroid M1s. However, there’s various versions of Raspbian, Armbian, and Debian, each of them using some custom tweaks. And that’s a lot of time to maintain them. So I really like the idea of NixOS and read that it can be used to build bootable images for computers. I haven’t fully built intuition for all parts in this so it took me a while to get this working. Here’s my notes.

Jakob Külzer's Blog Valid
Text

A Love Letter to KOReader

I enjoy reading books. I very much enjoy reading printed books, but they’re heavy, you can’t read them in the dark, and unlike my phone or ereader, I don’t have them on me all the time. So, I read a lot of ebooks. And with most ereaders, reading novels is fine, at least if you read reflowable document types like epubs. But as soon as you start reading PDFs, all bets are off. At least, until I discovered KOReader

Jakob Külzer's Blog Valid
Text

Zig, Memory, and the mysterious `170`

I’m hacking on a small Zig application with a GTK frontend, and part of using GTK is passing around ?*anyopaque pointers and you never quite know if it’s working. In my app I’m passing around a struct that holds a string []const u8 to various GTK callbacks. However the string was empty. This led me down a rabbit hole of trying to figure out if my pointers were correctly passed, even going as far as stepping through it with a debugger. Turns out, the pointers are all correct. Even my string []const u8 was there with the correct length, except every single byte was set to 170 and I realized I was looking at undefined memory. Zig in debug mode sets undefined memory to 0xaa which is 170.

Jakob Külzer's Blog Valid
Text

Hugo --cleanDestinationDir and Git Submodules

Recently I’ve been working on updating my blog a bit (you might have noticed?). I keep the hugo sources in a git repository and the built site in a separate repository. That repository is added as a submodule to the sources repo and during the build, the generated HTML is written into the submodule. Except the submodule kept getting messed up; git would be unable to track the changes or they’d be added to the parent repository. It was truly maddening, but as it is so often, the problem was not git but me.

Jakob Külzer's Blog Valid
Text

Zig Fetch

Zig’s package manager is still a bit rough. It only supports fetching tarballs, but many github projects don’t have them unless they have a release. There’s a trick to fetch any commit as a tarball though:

Jakob Külzer's Blog Valid
Text

One Billion Row Challenge in Zig

I finally got around to looking into The One Billion Row Challenge. If you’re unfamiliar, it’s a challenge to how fast a program can read and process one billion rows. It’s fascinating because it’s all about raw performance including algorithms, CPU instructions, and profiling and benchmarking. All things I enjoy dabbling with.

Jakob Külzer's Blog Valid
Text

mkdocs

I recently realized the docker container for my toy project books has over 2k downloads so I finally decided to write some proper docs for it. There’s not much to document, but it deserves a nice webpage. Picked up mkdocs because I saw it used by some other projects and I’m positively surprised. You initialize a project and throw some markdown files at it. Then you run build and it gives you a nice webpage for your docs, nothing more, nothing less. Great little tool, highly recommend it.

Jakob Külzer's Blog Valid
Text

Zig - First Impressions

I’ve been following the zig language for a while ever since I saw Andrew Kelly’s talk on Corecursive. The way Andrew describes the design of zig was very engrossing and who doesn’t like a language build for speed. But I have struggled with picking it up; time is in short supply and so were docs for zig when I first looked at it.

But that has changed; I finally found some motivation and ziglearn.org which is a good introduction to zig. I have only managed to read the first two chapters, much less understand them but it’s enough to be dangerous (to myself?).

Jakob Külzer's Blog Valid
Text

Senior Software Engineer, Database Platform

Jakob Külzer's Blog Valid
Text

Migrating Raspberry Pi From Sd Card to Usb

I’ve been running my Kubernetes cluster on Raspberry Pis for about a year now. Overall the cluster is stable and needs little attention and by now many useful and important services are now running on it. With more reliance on these services I need to ensure that the cluster doesn’t fail from preventable errors. One of the common failure modes for Raspberry Pis are sdcards. They are not very fast, they are of limited size, and worst, they tend to fail.

Jakob Külzer's Blog Valid
Text

Vim Digraph

Was writing a few posts for my food blog and needed to type some some “special” characters like é. When on a Mac that’s really simple because the keymap supports typing compound keys. But I’m on Linux and switching between keyboard layouts is annoying. So I figured vim must have a way for typing these characters, and behold, I learned about Vim’s digraph support. The documentation is quite good but I’ll cherry pick some combos because otherwise I’ll forget.

Jakob Külzer's Blog Valid
Text

Senior Software Engineer, Data

Jakob Külzer's Blog Valid
Text

Building Docker Containers for ARM with buildx

I’ve spent some time over the holidays building a Kubernetes cluster running on raspberry pis. One issue I ran into was that not all docker images I wanted to run were available for arm/linux. Luckily there’s a useful tool called buildx that extends Docker to build containers for different platforms and architectures using quemu and binfmt. ARM has a blog post that details the steps needed to build images.

The steps are:

Jakob Külzer's Blog Valid
Text

zsh Autocompletion Caveat

I spent a good hour trying to get a custom completion script working while porting my app Harbormaster to Cobra. It would and would not work. I retried writing the file, restarting the shell and it would just not offer any completions. Eventually I stumbled upon a innocent looking post on Github that held the solution: remove the .zcompdump file which holds the cached completions. So I ran rm ~/.zcompdump && compinit and everything works as expected.

Jakob Külzer's Blog Valid
Text

awk Cheat Sheet

I needed to crunch some data quickly and decided awk was the right tool to do so. But every time I use awk, I have to go read the manual, so I decided it’s time for a cheat sheet.

Structure of an awk script

# Comments begin with a pound sign
BEGIN {
 # Instructions run before the main loop
 FS = ";" # Set a Field Separator
}

# Each line of input is applied against all the following
# regular expressions and runs the instructions in the
# block:

/^$/ { print "An empty line" }

END {
 # Instructions run after the main loop
}

Invoke awk with a script like so:

Jakob Külzer's Blog Valid
Text

Book Arrival: The Ray Tracer Challenge

I was browsing the Pragmatic Bookshelf and this book caught my eye: writing a ray tracer from ground up with a test driven approach? This sounds like a fantastic challenge to me. I always was interested in ray tracers but always thought it too complicated a topic to do it myself. However, test driven development has helped me work on some complex and terrible code bases, so this feels reassuring to me.

Jakob Külzer's Blog Valid
Text

Slow Ruby Syntax Highlighting in Vim

I recently switched back from MacVim to terminal (alacritty) Vim because I’m trying to step up my tmux game after reading the excellent tmux 2 book from the Pragmatic Bookshelf. But anyways, I noticed incredibly slow syntax highlighting for larger ruby files, so slow that editing code was almost impossible. After lots of searching and debugging I found it was the regular expression engine Vim uses by default in combination with the Ruby syntax highlighter.

Jakob Külzer's Blog Valid
Text

gnuplot - My New Favorite Tool

I recently had the need to quickly visualize some data and none of the systems I usually work with had the data. Initially I dumped the data in Google Sheets and created a chart there, but that was slow and didn’t really scale well. The data had to be cleaned, brought into the right format, columns had to be selected and charts created. At this point I faintly recalled reading about gnuplot which, despite its name, has no affiliation with the GNU project.

Jakob Külzer's Blog Valid
Text

Notes on Working Effectively With Legacy Code

I recently received my copy of Working Effectivly With Legacy Code and have been busy reading it. The book, as a product of its time, has examples of not only Java, but also C++, probably to show concepts and techniques that apply to languages that behave differently in terms of linking and building. But regardless of its examples not really applying to what I work with, it was full of useful vocabulary and techniques to work with not only legacy systems, but really, any kind of system.