Do you have a backend service implemented in Rust that you’re going to deploy in a Docker container? Not sure how to write the Dockerfile? Start by copy-pasting the one below. # Customization point: set the name of the binary built by Cargo. ARG BINARY_NAME = app FROM rust:1-trixie AS chef RUN --mount = type = cache,target = /usr/local/cargo/registry \ --mount = type = cache,target =…
This week I attended Nordic PGDay 2026 . It’s a one-day PostgreSQL conference that travels between Stockholm, Copenhagen, Oslo, and Helsinki. I don’t know much about PostgreSQL, but since I like databases and the event was close by, I thought I’d pop in. It’s pretty nice to take a tram to a conference instead of an airplane. In this post, I want to share a few things that I…
Have you heard of Andrej Karpathy’s autoresearch project ? He has automated the research into training a small LLM with a coding agent. The agent makes changes to improve the training performance, measures the effect, and keeps the changes that work. That’s cool and we should do it, too. pi-autoresearch is a plugin for the Pi coding agent that implements the autoresearch loop. This…
Thanks to the coding agents, it’s easier than ever to create small pieces of software. I’ve been creating small apps, tools, and toys for myself. Last week I posted about Goblin Mode , my tool for spinning up development VMs. Let’s take a look at what else I’ve made! Small web apps I made a photo gallery for sharing my photos online. The app is called kuvasivu (Finnish for…
I’ve been working on a new tool for spinning up development environments. It’s called Goblin Mode . It spins up a new virtual machine (VM) on Hetzner and configures everything to be ready so that you can just SSH in and that start developing. It is something that I’ve wanted to have for a while now, but the arrival of the coding agents got me to implement it. The agents like…
Thanks to the coding agents like Claude Code, programming is now over . It’s more efficient to prompt an AI model to write code than it is to write it by hand. However, programming is just one of the many tasks that a software engineer has to take care of, albeit a central one. What about the other tasks? Can they be handled by an AI agent? The software delivery loop When you work in a…
Coding agents are so good now that they’re going to change the work of software engineers permanently. Allow me to have some takes 1 . Programming is over Claude Code with Opus 4.5 has left a strong impression on me. It can code now. Not just a bit – it can create big chunks of decent enough code. The quality of the output is as good as that of many human developers but it works much faster.…
Welcome to 2026. It sure has been a year already in terms of world events. Nevertheless, I’m going to talk a bit about how my 2025 was, the same procedure as every year . On the photos: there’s one photo for each month, in chronological order. Professional life I make my living by working as a software engineer. It’s a job that I really enjoy: building software is a lot of fun. Early…
After a nine-year break, PyCon Finland was back this Friday as a part of PloneConf 2025. I took a morning train to Jyväskylä and gave my talk about extending Python with Rust . It went fine. I went through the slides so fast that I must have skipped over something, but thankfully there were a lot of great questions from the audience so we made good use of the extra time. A talk video will be…
Welcoming. That’s the word that comes to my mind when I think about PyCon UK 2025 . PyCon UK is the main Python conference in the UK. This year’s edition took place a week ago - mid-September - in Manchester at Contact Theatre. I attended the conference in person and gave a talk, too. My way to Manchester In May, I was thinking about extending Python with Rust. I had done it at work…
uv is a Python package and project management tool. 1 Maturin is a build backend for Python extension modules implemented in Rust. How to best use them together? Why uv? First of all, if you’ve already got Maturin, why do you need uv? There are a couple of reasons: uv takes care of the virtualenv management. You can use uv to install development dependencies such as pytest. You could use…
Last week, I gave a talk titled Compressing floating point data with Gorilla at Helsinki Python Meetup . There’s no recording, but here is a blog version of the slides. Gorilla is a simple algorithm for compressing floats. It’s over a decade old and it’s not the state of the art anymore but since it sparked the development of a whole family of algorithms, it’s a great…
Nota bene: This is a notebook post. I'm jotting down some notes, often based on an ongoing project I'm working on. There will be less context and explanation than in my normal posts. I’ve been looking into algorithms for compressing floating-point data in columnar databases. Here’s a family tree for a few of them. Gorilla : The original algorithm based on xorring the consecutive…
Nota bene: This is a notebook post. I'm jotting down some notes, often based on an ongoing project I'm working on. There will be less context and explanation than in my normal posts. What are your options for a file format if you want to store timeseries data? CSV or JSON lines: The simple, stupid option which is not to be overlooked. It works as long as you don’t have too much data or too…
Let’s implement leader election using Amazon S3’s If-Match condition by building a distributed lock with it. In August 2024, Gunnar Morling published a blog post that shows how to do it with the If-None-Match condition. Back then, If-Match had not yet been released. This post shows another way to solve the same problem. The post is intended to stand on its own so you don’t need…
In my last post , I wrote about my plans for this year: This time I’m trying to be more intentional, especially career-wise. I concluded that it is time for me to move on from my position as a software engineer at Oura Health. I had a great two and a half years there, building and operating the backend-slash-database that is the main data store of the company, and I learned a lot about…
It’s 2025 now. This century is now 25% complete! As is my tradition , I’m going to reflect on the year gone by. On the photos: there’s one photo for each month, in chronological order. Software engineering At work, I continued to build cloud backends to manage data. I ended up spending a lot of time with Rust, OpenTelemetry, Docker, GitHub Actions (GHA). Out of these…
This week I wrote a bunch of architectural decision records (ADRs) for a project I’m working on. ADRs were popularized by Michael Nygard’s blog post Documenting architecture decisions . Nygard does a great job explaining why they will be useful in the future. They will give useful context about decisions for the people who weren’t around when the decisions were made, and also for…
When do you add comments to your code? Do you do it all? Everyone has seen one of these comments: counter += 1 # increment counter by 1 This comment is explains what is already obvious from the code, so it’s not useful. What’s worse is when somebody then changes the code to be like this: counter += 2 # increment counter by 1 Now the comment does not match the code anymore. People bring…
In the past few weeks, I’ve spent a lot of time building Docker images on GitHub Actions. Anyone who has done it knows what it is like: I’ve been waiting a lot . To avoid waiting, you’ll want to set up build caching. Here’s a few things I learned about it. Building Docker Compose targets For one of our services, we have a Docker Compose based setup for running it locally.…
This week I reviewed my notes about code review and noticed there’s something I haven’t written about: code review often happens too late . Nota bene: When I talk about code review, I talk about it in the context of corporate software engineering. Other contexts, such as open-source projects, have different problems and solutions. Typically a developer requests code review for their…
Every time ThoughtWorks publishes their Technology Radar , I take a look. It’s a nice source for finding out about new technologies and I think the Hold/Assess/Trial/Adopt system makes sense even if I often disagree with the classification choices. At work, I’ve been building some internal tooling for working with timeseries data and I’ve had a chance to try some new things. I…
Apparently it was Fred Brooks in The Mythical Man Month who wrote that, when building a new software system, you should “plan to throw one away”. It sounds like great advice, but I haven’t seen anyone follow it. I recently built a prototype of an internal tool at work and I thought this time I will throw it away. The tecnology I chose was Python. Normally when I write Python, I…
This Tuesday was the day of the first Systems from HEL meetup. It’s a meetup about systems programming – there’s a bunch of systems meetups in the US and now there’s one in Helsinki, too. Pekka Enberg, the founder of the meetup, was also the first person to give a presentation. He talked about deterministic simulation testing (DST). He gave an overview of the technique and demoed…
Last time I thought I had a trick in my pocket to ensure that I get some writing done: The solution I’m going to try is free writing, similar to morning pages: set a timer for ten minutes and just write whatever is on your mind. It did not quite work the way I hoped for. Free writing is great, but it’s just that my work last week was in the weeds and I cannot write about it in detail.…
I’ve now done ten weeks of weeknotes . Let’s talk about how it has gone. In the first note , I wrote this: I haven’t posted much. I’d like to change that. Instead of trying harder, I’d like to try solving it . A friend suggested posting weeknotes, so here goes. Certainly it worked in the sense that I’ve posted every week. In general I’ve seen three kinds…
My week wasn’t too focused as I was slightly ill, so I’m going to offer a selection of small thoughts. My main concern at work has been how to get the tool I started working on a while ago to the users. The work has been slow due to my conference trips and other priorities, but I’ve gotten to the point where I must get feedback from the potential users. I’ve tried to figure…
This week I attended EuroRust 2024 in Vienna, Austria. It was a two-day conference about the Rust programming language, organized by Mainmatter , a Rust consultancy 1 , and this was the second time it was organized. This was my first Rust conference. Unfortunately, it ended up being more of a miss than a hit for me, and it might be the last one in a while. It was on me, really. I go to conferences…
It is the perf season at work. We’ve been reviewing our own and each other’s job performance. The reviews will feed into managers’ assessment of our performance which in turns affects whether we will get a raise or a promotion. I struggled a bit with writing the reviews. I realized I haven’t been giving as much feedback as I should have been and now I’ve got a backlog…
I wanted to track a memory leak in a Python program. The program was leaking only in production and so I had to figure out how to use Memray to attach to a process in Kubernetes. There were a few hurdles on the way, so here’s what I did. Add Memray to your container image. We use Poetry for our Python projects, so I added Memray as a dependency. poetry add memray If you’re using the…
Last week I attended Heart of Clojure . It was held the last time in 2019 and I had such great time that I decided to go again even though I don’t use Clojure these days. I knew what to expect, but nevertheless I ended up surprised. I gave a lightning talk where I told everyone to blog as it clarifies their thoughts and feelings. Well, here’s a plot twist: Heart of Clojure ended up…
I was thinking about debugging tools last week . The same theme continues this week. My big insight is that many development and debugging tools must work with broken or incomplete inputs . Here are a few examples: A debugger must work with programs that crash. In fact, that is exactly the time when many of us reach for a debugger. Your editor should work even if there are some syntax or type…
I’m switching the gears a bit at work and instead of working on databases, I’ll be working on a new internal developer tool for making sense of some timeseries data. That is what has been on my mind this week. Essentially I’m making a debugging tool. What’s the bar for a successful debugging tool? At least it must be better than printf. There are endless articles where…
This week I’ve been thinking about object storage services such as Amazon S3. Despite being called “object” storage, in my mind they are used for storing files. However, that’s not the only way to think about them. Another perspective is that they are key-value stores for storing binary blobs Nowadays a lot of people want to use them as a storage backend for their databases…
This week at work we were talking about improving the developer experience around the company. It is about how it feels to work with the technical systems as a software developer. Is it fun or frustrating to develop a new feature? What about debugging a production issue? If you were truly ambitious about it, you might ask how to make it more fun and more exciting and more meaningful. We were more…
Preface: I’m trying out weeknotes I believe writing regularly in public about your ideas is valuable. Writing helps you to clarify your thinking and sharing it lets you get feedback. You get something you can refer back to and link to. I’ve been writing regularly. However, as regular readers may have noticed, I haven’t posted much. I’d like to change that. Instead of trying…
A few months ago I wrote about how to build AWS Lambda deployment packages with Pex . It works, but it left me wondering: why isn’t there a one-command solution for building the packages for simple Python projects? I decided to build one. It’s called paketoi . It takes a requirements.txt file and your source files and bundles them into a zip file that you can deploy on AWS Lambda.…
There’s a lot of debate about software engineering methods and paradigms such as test-driven development (TDD), pair programming, agile methods, functional programming, and so on. Which one is the best? This is how the debate is often framed: it’s about finding the one true method that will deliver the best results and should be used always. Someone will write a post putting forward…
At work, we use GitHub to collaborate on code. We create short-lived feature branches and merge them back to the main branch via pull requests (PRs). This is a fairly standard workflow. Unfortunately I’m not too happy with it. I’ve had trouble finding a perfect way of working with git and GitHub’s PR view. I’d like to have the following: Useful git history. There are many…
Update: See also my new tool that simplifies this . So, you want to deploy a Python script to AWS Lambda and you have a few dependencies with native code. How do you build the .zip deployment package for it? Let’s say that you have your script in lambda_function.py and your dependencies listed in requirements.txt . If you want to follow along at home, I’ve prepared a GitHub repo with…
Hello and happy new year. Like last year , I’m going to indulge in self-reflection and tell you about my year. On the photos: there’s one photo for each month, in chronological order. Software engineering I poured a lot of energy into technical work. I built a system for managing large data migrations and spent a lot of time on polishing and operating a large cloud backend written in Python.…
Are you developing a backend service in Python? I have two pieces of advice for you: Do not use pip and requirements.txt to manage Python dependencies. They lack crucial features that should be built-in. Use Poetry instead. To me, the first one is a no-brainer. The second one is more tentative: Poetry is a great option, but it’s hardly the only option worth considering. I’ll explain…
Nota bene: This is a notebook post. I'm jotting down some notes, often based on an ongoing project I'm working on. There will be less context and explanation than in my normal posts. I’ve been using Poetry for package management in Python projects for a while now and, for what it’s worth, it’s working well for me. However, some regular tasks require multiple commands with…
Nota bene: This is a notebook post. I'm jotting down some notes, often based on an ongoing project I'm working on. There will be less context and explanation than in my normal posts. I’ve been experimenting with the so-called branchless version-control workflows. The idea is that instead of using named branches, you just juggle a bunch of commits on top of the main branch. Here are a couple…
Year 2023 is here. So, how was 2022? Allow me to review my year. On the photos: there’s one photo for each month, in chronological order. Professionally In January 2022 I wrote this: For many years, I’ve focused on building web services in Clojure. However, I feel that I’ve done enough of it for now and more interesting problems and bigger impact await elsewhere. Thus I’d like to turn a new page…
When you’re writing code with a modern editor or an IDE, you can count on having a number of convenient features such as syntax highlighting, autocomplete, and code navigation. Unless you’re writing SQL, of course! A lot of editors and IDEs, such as IntelliJ IDEA, have really nice support for SQL. However, it’s not so easy to benefit from it in practice. If you’re writing…
Dear fellow Clojure enthusiasts, do you know what the following two code snippets evaluate to? And why is that the result? ( identical? ## NaN ## NaN ) ( let [ x ## NaN ] ( identical? x x )) I didn’t know it a couple of days ago and it took me a while to understand it. Now I want to share my understanding. Go on, make a guess and check it with a REPL. When you’re ready – or if…
The last time I wrote about how database schema migration tools could do more to help us . The way I see it, any schema migration solution has to cover three tasks: creating, managing, and executing migrations. Creating migrations. The first task is to create a migration script. If your scripts consist of DDL commands in SQL files, you’ll probably write them by hand. A linter like Squawk can…
If you’re developing an application that is backed by a SQL database, sooner or later you will need to do a schema migration. Maybe you’ll need to add a new table or a new column, create a new index, or change some constraint. Luckily there are plenty of tools to help you! Migratus for Clojure, Flyway for Java, and dbmate as a more language-independent option are examples of the most…
Epistemic status: Anecdotes and opinions. I’ve used Clojure for over a decade now: I first learned it in 2012 and started using it professionally in 2013. I’ve been reflecting on what has happened and what the future looks like. In this post, I want to share a few musings about it. Missed opportunity: production REPLs REPL is so central to Clojure that people even talk about…