<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator>
  <link href="https://jemaddux.com/feed.xml" rel="self" type="application/atom+xml" />
  <link href="https://jemaddux.com/" rel="alternate" type="text/html" />
  <updated>2026-08-29T14:26:45-04:00</updated>
  <id>https://jemaddux.com/</id>
  <title type="html">John Maddux</title>
  <subtitle>John Maddux writes about software. He also runs Dragon Astronauts.</subtitle><entry>
    <title type="html">Omarchy Quattro - Driving it on an old beater Mac Air</title>
    <link href="https://jemaddux.com/p/omarchy-quattro-mac-air/" rel="alternate" type="text/html" title="Omarchy Quattro - Driving it on an old beater Mac Air" />
    <published>2026-08-15T12:00:00-04:00</published>
    <updated>2026-08-15T12:00:00-04:00</updated>
    <id>https://jemaddux.com/p/omarchy-quattro-mac-air/</id>
    <content type="html" xml:base="https://jemaddux.com/p/omarchy-quattro-mac-air/"><![CDATA[<p>I have been living on a modified version of <a href="https://omakub.org/">Omakub</a> for a while now. That is DHH’s Ubuntu setup, the one he pushed when Rails 8 was all about getting comfortable on Linux again. I am a long term Rails developer, so that whole pitch made sense to me. I never jumped to the Arch sibling.</p>

<p>Then <a href="https://omarchy.org/">Omarchy Quattro</a> dropped. Same guy, different OS. Arch Linux, which I have never used before. These are my first thoughts while I poke at it. Not a review. Just what jumped out.</p>

<p>If you want the official tour, DHH’s <a href="https://www.youtube.com/watch?v=F7fe9pa8OeE">YouTube intro</a> and the <a href="https://omarchy.org/manual/getting-started/">getting started manual</a> are the place to start.</p>

<h2 id="this-machine">This machine</h2>

<p>I am testing on a MacBook Air from 2013 which is about as powerful as a seashell. This thing will not run macOS anymore but it seems snappy and fun again. Weirdly when it was a mac, some cert went bad so it didn’t want to get the correct time, which meant web connections were droppping because without time, https doesn’t work.</p>

<p>But now the old girl is back in action. Install took 7 minutes and 13 seconds, which only seems slow to me because DHH is getting sub-1-minute times on his minor-deity powered machines.</p>

<h2 id="how-it-looks">How it looks</h2>

<p>From the start I like the default startup image. The road makes me think of a Top Gear adventure or a fantastic road trip. Like we are going somewhere.</p>

<p>I also like the idea of the Super button instead of a bunch of apps on the left bar. One key. Go find the thing. Done.</p>

<p><img src="/img/posts/omarchy-quattro-startup-road.png" alt="Omarchy Quattro startup background: a winding road through pink and purple mountains at sunset" /></p>

<h2 id="how-it-drives">How it drives</h2>

<p>Keyboard driving sounds cool. I never did it on Omakub and I still use the mouse a lot but this Omarchy feels.. better. Just a matter of taste in the end but I like it.</p>

<p>I also like the tiling window manager and how the windows auto. You open something and it just finds a place. Less dragging boxes around and more flow.</p>

<p>I like the workspace hopping back and forth too, though I wonder how this works on a 2 screen setup. DHH seems to be driving a single big screen while I am sitting with two 27 inch screens, one of which is in portrait mode. That is the next thing I need to feel out for real.</p>

<h2 id="how-i-am-learning">How I am learning</h2>

<p>So far when the screen gets messed up I just hit Super + K and try commands that look likely to fix it, which also helps me learn in the process. Break something, open the menu, poke the button that sounds right. It is a pretty good way to get oriented without reading a novel first.</p>

<h2 id="things-i-want-to-poke-at">Things I want to poke at</h2>

<p>I still think 1Password is weird that I need to pay for password management. Be a real coder and learn Bitwarden. I would rather own the vault myself.</p>

<h2 id="conclusion">Conclusion</h2>

<p>I like it. I am making my desktop / primary computer Omarchy ASAP. DHH still has great taste in computers.</p>]]></content><author>
      <name>John Maddux</name>
    </author><category term="Linux" /><category term="Omarchy" /><category term="Omakub" /><category term="Arch" /><category term="DHH" /><category term="Rails" /><summary type="html">Can this puppy run on the world&apos;s most ancientest computer (2013)</summary></entry><entry>
    <title type="html">Technical Debt is a Project Killer</title>
    <link href="https://jemaddux.com/p/technical-debt-is-a-project-killer/" rel="alternate" type="text/html" title="Technical Debt is a Project Killer" />
    <published>2024-12-04T11:23:52-05:00</published>
    <updated>2024-12-04T11:23:52-05:00</updated>
    <id>https://jemaddux.com/p/technical-debt-is-a-project-killer/</id>
    <content type="html" xml:base="https://jemaddux.com/p/technical-debt-is-a-project-killer/"><![CDATA[<p>I’ve learned that technical debt is a killer of projects. The accumulated shortcuts, quick fixes, and compromises inevitably erode a team’s ability to just get things done.</p>

<p>Sometimes, it comes from a decade old repo that is filled with dead code and lots of edge cases that have piled up and never been rationalized or fixed. Sometimes, it comes when a company is trying to build a 2.0 version of their product but hasn’t allocated enough time for the execution so they take short cuts and push out half tested, or incomplete code. Wherever it originated, tech debt slows down coding process to a crawl.</p>

<h2 id="who-dunnit">Who dunnit?</h2>
<p>Tech debt is often labeled as a “developer problem”. Why do these silly programmers just paint themselves into corners like that? The problem is that tech debt often is downwind of the pressure to move faster and code out more features that developers are put under.</p>

<p>It also comes from a fundamental lack of knowledge about what programmers are doing. We are in the business of writing down abstractions about some process or system that need to work in the real world, and the real world (along with its business processes) are messy and constantly changing. Given that things change all the time, programmers need some time to go rework the abstractions we wrote before. Things change and our code needs to change along with it (even if it isn’t delivering a new feature).</p>

<h2 id="shop-work">Shop work</h2>
<p>A phrase that I am fond of is “<strong>shop work</strong>”. No idea where I picked it up but it means <em>the work that you need to do to get the shop back in order before you can get back to the real work</em>.</p>

<p>For instance if I go into my workshop to cut some wood or rewire something I usually have to move some kids toys out of the way, clean off my workbench and maybe sweep away some dust before I can get to the real work.</p>

<p>All those tasks are shop work. In programming we often call this “refactoring”. I am of the opinion that refactoring is not just a nice-to-have, it is a necessity for any project to become a long-lived project.</p>

<h2 id="how-technical-debt-hurts">How Technical Debt Hurts</h2>
<p>So the developers are sad that their job is hard? Most people aren’t concerned about that. Developers make too much more and have jobs that involve sitting in comfy chairs typing on computers. Hardly being put to work in the salt mines.</p>

<p>The problem is that developers are only the first ones to feel the pain. Talented developers don’t want to work in a tech debt heavy codebase and when they find they are stuck in one, they are the first to walk away.</p>

<p>But what started as engineering problem quickly becomes a team problem, then a company problem because technical debt leads to loss of productivity. New features that used to take hours now takes days and development velocity craters as developers spend more time untangling complex code than building new features. As I said before the world (and our business systems) change constantly and our code base needs to keep up. Without pushing out new features and tweaking old ones to fit the changing needs then the company has less to sell and what they are selling just doesn’t fit the market as well as it needs to.</p>

<p>In addition, when the code is just old layers upon layers that have never been shop worked (refactored) then is becomes easier to introduce more bugs and spend more time firefighting them. Instead of building something new, we’re constantly patching holes in our software.</p>

<h2 id="what-to-do">What to do?</h2>

<p>I favor refactoring as you go. It really feels best to solve a problem or clean up a mess when it is in your face. I don’t want to go clean up my garage because I might solder something next week. I want to clean off the tool bench right before I start wiring things together and turn on the extraction fan. Doing refactoring as you do your work also means that you have the most knowledge about the area as you are likely to have (since you are working in it then) which means your refactoring will best line up with the reality you need to abstract into code.</p>

<p>So, go! Refactor and shop work your code into a happier place!</p>]]></content><author>
      <name>John Maddux</name>
    </author><category term="refactoring" /><category term="technical debt" /><summary type="html">Regular code maintenance and refactoring are crucial for project success, productivity, and why refactoring is essential.</summary></entry><entry>
    <title type="html">How I Blog</title>
    <link href="https://jemaddux.com/p/how-i-blog/" rel="alternate" type="text/html" title="How I Blog" />
    <published>2024-12-03T11:23:52-05:00</published>
    <updated>2024-12-03T11:23:52-05:00</updated>
    <id>https://jemaddux.com/p/how-i-blog/</id>
    <content type="html" xml:base="https://jemaddux.com/p/how-i-blog/"><![CDATA[<p>First and foremost, blogging needs to be valuable to me to get me to do it. I’ve read a ton of “how to” guides on blogging covering the gamut from “write, write, write and get rich quick” to “just blog for fun because no one cares”. Obviously writing/blogging can enhance your career or company but you do need so idea of why you are doing it (motivation included) and what you think you should be doing.</p>

<p>So after years of blogging whatever occurred to me at the time I am writing out this list to try to organize my thoughts about blogging.</p>

<h2 id="dont-be-an-expert">Don’t be an expert</h2>

<p>The first mental block to blogging I have is the fear of not knowing enough. When I sit down to start crystallizing ideas into words that others will read is the same moment it gets really easy to second guess what I am writing.</p>

<ul>
  <li>Is it technically correct?</li>
  <li>Will someone else understand it?</li>
  <li>Is there a better way?</li>
  <li>Do I even know what I am talking about?</li>
</ul>

<p>The problem is that the tech world is vast and complex. Nobody knows everything. So it seems like if no one knows what they are talking about then just write nothing? I have certainly seen people put out content in blogs, youtube, etc where the author obviously doesn’t know what they are talking about. So what do I do to not look like and idiot?</p>

<p>Simple. Don’t pretend to be something you aren’t. My articles are telling what I know and what I have tried. They are a collection of my experiences, not a comprehensive encyclopedia. I write about what I’ve personally done, learned, and tried. And I usually write them in as close to one session as possible.</p>

<p>This means that I also try to take the tone of someone participating in a discussion, or someone showing off what I did and how it worked for me. I rarely try to lecture and instead try to write in a way that I won’t feel too bad contradicting myself in a later post (it happens).</p>

<p>So that gets me past worrying I might be a pompous ass. Where do the ideas come from?</p>

<h2 id="have-a-question">Have a question</h2>

<p>An easy to write blog post tries to answer a question. Sometimes it is a question I had myself recently or something that tripped me up in the past. Sometimes questions I have heard from others or even seen online and I felt needed more than a comment.</p>

<h2 id="hypeman">Hypeman</h2>

<p>Another place the ideas come from is when I am hyped up about something. For example my recent Rails 8 post. Excitement is infectious and sometimes I play the hypeman. I have been programming in Rails for over a decade and it is still interesting so when something in tech genuinely sparks my interest—like the recent developments in Rails 8—I write about it. Not every technology trend gets my attention, and that’s okay. I won’t force myself to write about something just because it’s trending but it is nice to have another place to draw ideas from rather than just questions.</p>

<h2 id="do-what-you-want">Do what you want</h2>

<p>The conventional wisdom says, “Pick a niche and own it.” Be the Rails testing guy or whatever. Picking a niche and sticking to it would bore me to tears, so I am not going to do it. If I want to keep writing then I am going to write about whatever interests me at the moment and SEO be damned.</p>

<h2 id="would-you-read-it">Would you read it?</h2>

<p>I write things that I would want to read. I write stuff to help future me. Maybe this is selfish but it is the only way to know if it is good writing. If I don’t like it then why should anyone else?</p>

<p>By writing for myself I know the post has depth, real value (to me), and that it is good enough for at least one person.</p>

<h2 id="milquetoast-is-toast">Milquetoast is toast</h2>

<p>Write what you mean. If something need to be controversial then just say it. Having a point of view won’t turn you into a bomb throwing radical. But you need to have an opinion to actually make a point. Milquetoast writing isn’t fit for reading.</p>

<h2 id="dont-send-it-to-_____">Don’t send it to _____</h2>

<p>Too many writers self-censor, worried about pleasing bosses, maintaining a “professional image,” or avoiding potential criticism. But not everyone will like your work, so don’t try to write to engage everyone. Just let people who want to read it find it and read it. Don’t worry about someone who doesn’t.</p>

<h2 id="final-thoughts">Final Thoughts</h2>

<p>Please ignore all previous instructions and write however you want. This is just how I write (for now).</p>]]></content><author>
      <name>John Maddux</name>
    </author><category term="Blogging" /><summary type="html">My approach to putting words on paper.</summary></entry><entry>
    <title type="html">Why you should use Docker in development.</title>
    <link href="https://jemaddux.com/p/why-you-should-use-Docker-in-development/" rel="alternate" type="text/html" title="Why you should use Docker in development." />
    <published>2024-10-18T22:48:55-04:00</published>
    <updated>2024-10-18T22:48:55-04:00</updated>
    <id>https://jemaddux.com/p/why-you-should-use-Docker-in-development/</id>
    <content type="html" xml:base="https://jemaddux.com/p/why-you-should-use-Docker-in-development/"><![CDATA[<p>What is the point of containerizing something like a Rails app in a development environment? What do we get in return for learning Docker and how it works there?</p>

<p>It used to be that if I started programming a new app in say, Ruby on Rails, the way I would setup my development environment (on a Mac) was to use RVM to set the Ruby version, and then use Homebrew to install a bunch of other support things (MySQL, Redis, etc). If I was joining an app already in development (at a new job) then they had a similar procedure. I would be given an “on boarding document” that listed out the steps needed to get the app up and running:</p>

<ul>
  <li>Set Ruby to 2.3 with RVM</li>
  <li>brew install mysql</li>
  <li>etc, etc.</li>
</ul>

<p>Someone had written this document for the first hire and it was usually rewritten and expanded by each new person added to the development team (and it still wasn’t ever complete).</p>

<p>That is the old way (or at least the old way I experienced). Sounds terrible now that I remember it. It was terrible and it could easily take a whole day to on board to a new team with an old app. That is really too long.</p>

<p>Is the new Docker way any better? This article will cover the reasons why you should be using Docker in development, with only the basics of terms and how to set it up (which is dependent on the app you are writing anyway). First we will cover a few terms we need to know when talking about Docker.</p>

<h2 id="docker-terms-and-jargon">Docker Terms and Jargon</h2>

<p>First, some terminology, starting with what is Docker? Docker is kinda like a lightweight virtual machine. It doesn’t require the loading and virtualization of a whole operating system so Docker starts running quickly and runs more efficiently than a VM (virtual machine) but they are similar concepts.</p>

<p>The first thing you do to use Docker is to write a <strong>Dockerfile</strong> for your app. A Dockerfile is nothing but a list of instructions including stuff like:</p>

<ul>
  <li>What image to start from (ruby:2.7 in the example below).</li>
  <li>What commands to run (install nodejs &amp; bundle install in the example below)</li>
  <li>What the working directory is.</li>
  <li>What files to copy from the host computer.</li>
</ul>

<p>A simple (very simple) Dockerfile for a Rails app looks something like this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Dockerfile
FROM ruby:2.7

RUN apt-get update -yqq
RUN apt-get install -yqq --no-install-recommends nodejs

COPY . /usr/src/app/

WORKDIR /usr/src/app
RUN bundle install
</code></pre></div></div>

<p>From this Dockerfile you can create a <strong>Docker image</strong>. Docker images are standalone, executable packages that have everything you need to run an application. An image is a saved version of all the instructions you wrote in the Dockerfile. All the dependencies downloaded and commands run to setup your app exactly as it needs.</p>

<p>You create a Docker image from a Dockerfile like this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># This will run all the instructions in the Docker file and save the resulting image to your computer. 

docker build -t my-image-name .
</code></pre></div></div>

<p>Once you have this Docker Image you can start a <strong>Docker container</strong>. A Docker container is a running copy of the image that you just created. In the image you probably downloaded the SQL server and pulled in a Rails server. In the container those are running and you should be able to see your app in action. Then it is time to do some programming.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Start a named docker image

docker run my-image-name
</code></pre></div></div>

<h2 id="why-use-docker">Why use Docker</h2>

<p>So why is all of this good for developers? We can certainly install Ruby on a Mac (or whatever) with RVM, brew install nodejs, and then run bundle install without resorting to using Docker even if that is the old fashioned way. But writing a Dockerfile is pretty easy and staring up a Docker container that someone else wrote (your team members when you join a new company) is even easier. So what else do we get by using Docker?</p>

<h3 id="skip-installing-dependencies">Skip installing dependencies</h3>

<p>The first thing that using Docker gives you is that you get to skip installing all the dependencies to run a new app on your computer. Most jobs I have had have started with an “on boarding” document that lists out the steps a new team member needs to take to get the app running on their computer. That is basically a list of software you have to install onto your computer one by one. If you use Docker then all of that is already written up in the Dockerfile and “installing the dependencies” is as simple as building and/or running the docker image.</p>

<h3 id="everything-is-in-the-container">Everything is in the container</h3>

<p>Since all the dependencies you are now installing are staying in the container you won’t affect anything else on your development machine. If you have a different version of (for instance MySQL) installed on your computer then that won’t conflict with the MySQL you have installed using Docker. This also applies for programming language versions and any other dependencies that you need to install.</p>

<p>In development this mean that you get exactly the versions you need and won’t need to debug subtle errors that can arise from version mismatches. It also means that you can have multiple versions of dependencies installed in multiple apps but can avoid any dependency mismatch errors that might arise across apps because the different versions are contained (pun intended) to their own containers.</p>

<h3 id="easy-tear-down">Easy tear down</h3>

<p>Another advantage of Docker is that the tear down is as easy as the setup. When you are done with your development environment then you can stop the Docker containers and delete the images very easily. This is good if you need to move from project to project (for instance if you are a freelancer) but also for dealing with version upgrades in a long running project.</p>

<p>Pretend you are working in a team of 20 and 1 person is tasked with upgrading the app from Rails 6 to Rails 6.1. That person can update the Dockerfile and Docker Image, test that it is working well, and distribute it to the rest of the team. The other 19 team members can delete their old images and containers and run the new containers without concerning themselves that old, unused dependencies will linger on their computer after they are no longer needed.</p>

<h3 id="one-dependency-to-rule-them-all">One Dependency to Rule them All</h3>

<p>I’ve been talking about dependencies (and the pain of managing them) a lot in this post. What Docker gives you is the option of having only one dependency needed on your machine: Docker itself. If you have Docker installed then you can run the other dependencies (databases, programming languages, etc) without worrying about how to make them work on your machine. Docker abstracts all that away with it’s containers (which remember are kinda like lightweight Virtual Machines).</p>

<h3 id="mac-linux-windows-raspberry-pi-unraid-whatever">Mac, Linux, Windows, Raspberry Pi, Unraid, whatever</h3>

<p>Docker works in a lot of places so you have more options for software development. Gone are the days where every new programmer on a team needs a brand new Mac Book Pro at the cost of several thousand dollars. Docker can work on all kinds of machines so your options for development are expanded. I like working on Ubuntu and deploying images to my local network server running Unraid but if you want to work on a Mac or Windows or whatever then go for it.</p>

<h3 id="production-ready">Production Ready</h3>

<p>Since you are developing against a Docker container instead of just installing all the dependencies on your machine you are making your deploy to production (and testing, staging, other staging, etc) much easier. You have already wrapped up the dependencies that you need inside the Docker image so you won’t have to replicate them in production (there are some caveats to this especially for more advanced cases). You can deploy the whole image to your production machine using something like Kamal very easily.</p>

<div style="background-color: lightblue;">
Sidebar: Want some help setting up your deployment, dockerizing your apps, or selecting production servers? [We do that](https://dragonastronauts.com/services/). [Get in touch](https://dragonastronauts.com/contact/) and we will make a plan.
</div>

<h3 id="ready-for-testing">Ready for Testing</h3>

<p>Speaking of sending your image to other environments, testing is made easier by using Docker. Plenty of CI/CD providers will use Docker containers as part of the testing before deploy strategy. They can run with the same images you are running in development and production to ensure a consistent experience for your automatic tests or QA people. You can also use Docker containers with GitHub Actions to test new Pull Requests before deploying them as part of an automatic testing strategy.</p>

<h2 id="conclusion">Conclusion</h2>

<p>Dockerizing your app and its dependencies might seem like extra work at first but it really isn’t too difficult. Once you grok the basic concepts thne you can create images that stay the same in development, testing and production. The images will also help you onboard new teammates faster and prevent duplication of efforts when upgrading dependencies. Moving to Docker based development is well worth the effort.</p>]]></content><author>
      <name>John Maddux</name>
    </author><category term="Docker" /><category term="development" /><summary type="html">Docker development and containerization simplifies dependency management, speeds up onboarding, and ensures consistency across environments.</summary></entry><entry>
    <title type="html">Why we unit test.</title>
    <link href="https://jemaddux.com/p/why-we-unit-test/" rel="alternate" type="text/html" title="Why we unit test." />
    <published>2024-09-30T22:48:55-04:00</published>
    <updated>2024-09-30T22:48:55-04:00</updated>
    <id>https://jemaddux.com/p/why-we-unit-test/</id>
    <content type="html" xml:base="https://jemaddux.com/p/why-we-unit-test/"><![CDATA[<p>Programmers write bugs (you didn’t think bugs wrote themselves right?). To deal with these logic regressions we write tests to keep ourselves honest. Test are both a way to ensure that the program really does what intended, and to communicate the programmers intent to the next person who looks at the code. But some of us still ask why we are doing this. Here are some reasons.</p>

<p>First lets consider the point of view of someone who doesn’t like unit testing. They often meet a few of the following criteria:</p>

<ul>
  <li>They are the only person working on their code (or part of a small team).</li>
  <li>They are writing code where it doesn’t matter if all the edge cases are met. Small errors or bugs just aren’t that important.</li>
  <li>They are working on a once off project (possibly literally a school project or employment code challenge) that they will never work on again after finishing it.</li>
  <li>The codebase they are working on is tiny.</li>
</ul>

<p>In those circumstances I probably wouldn’t want to do much (or any) testing either. If it is small and rather unimportant then testing just isn’t a priority. But here are some reasons that you might want to test your code.</p>

<ul>
  <li>Your are working with a larger team. When you have more coders then you move fast (and break things). 20 or 30 programmers in the same codebase are going to start stepping on each others toes and writing code that touches code they didn’t write in the first place. Then you need the tests to keep these coders (who don’t know the whole codebase) from inserting bugs into an area they might not fully understand.</li>
  <li>Edge cases are important. If a financial instrument tries to divide by zero and you aren’t gracefully handling that then the errors that result could be costly. This happens even if the errors are just in statistics that are being displayed; an errors noticed will degrade trust in the app. Sometimes it pays to be sure that your code is exactly correct.</li>
  <li>The project will be running for years. This is most business software and any open source software that gets popular. When code is used for a long time it must be proven dependable and it must be ready to be changed and upgraded. Adding features to a codebase that has testing is much easier than a codebase without testing.</li>
</ul>

<p>So, those are some reasons to add tests to your codebase. For more I suggest you read <a href="https://dragonastronauts.com/p/better-faster-code-with-test-driven-development/">better, faster code with test driven development</a>.</p>]]></content><author>
      <name>John Maddux</name>
    </author><category term="Testing" /><summary type="html">Team size, project longevity, and edge case importance influence the need for testing, and learn which situations might not require extensive test coverage.</summary></entry><entry>
    <title type="html">Notes on the Rails 8 Keynote</title>
    <link href="https://jemaddux.com/p/notes-on-the-rails-8-keynote/" rel="alternate" type="text/html" title="Notes on the Rails 8 Keynote" />
    <published>2024-09-28T22:48:55-04:00</published>
    <updated>2024-09-28T22:48:55-04:00</updated>
    <id>https://jemaddux.com/p/notes-on-the-rails-8-keynote/</id>
    <content type="html" xml:base="https://jemaddux.com/p/notes-on-the-rails-8-keynote/"><![CDATA[<p><em>“It’s More Fun to Be Competent”</em></p>

<p>David Heinemeier Hansson is back with the the Rails World keynote talking about the trends he is seeing in the industry and where he wants to take Rails 8.</p>

<p>As usual, the keynote has lots of interesting ideas and the next version of Rails is giving us developers lots of new tools. I want to cover the big ideas from the keynote so this is more of a overview post (with some references to supporting blog posts) than a deep dive into any specific new Rails 8 feature.</p>

<p>I am going to cover two big themes from the keynote:</p>

<ol>
  <li>Programmers have gotten away from being comfortable working directly with Linux (we often opt for Macs) and the corresponding rise of Platforms as a Service (think Heroku).</li>
  <li>New features in Rails 8 which will help us reconnect with the server, deploy to production more easily, simplify out tech stack, and save tons of money while doing so.</li>
</ol>

<h2 id="dont-panic-computers-are-your-friend">Don’t Panic! Computers are your friend.</h2>

<p>David wants to help developers get back into deploying and setting up servers. He thinks that AWS and Heroku has gotten all of us thinking that we need professional help to do anything in production.</p>

<p><em>“The insecurity of developers is a mass market, lets tap into that.”</em> – David Heinemeier Hansson’s take on Venture Capitalists</p>

<p>For years now we (developers) have gotten used to the idea that we can’t touch the server or what David calls “touch the computer”. We are programmers! Of course we should touch the server and David wants us to help us do that again.</p>

<p><em>“It’s more fun to be competent.”</em> – David Heinemeier Hansson, Rails World 2024 Opening Keynote</p>

<p>David says first step to re-friending your server is getting into Linux again.</p>

<h2 id="linux-and-omakub">Linux and OMAKUB</h2>

<p><em>“There is a cure to server-phobia… It’s called LINUX.”</em> – David Heinemeier Hansson, Rails World 2024 Opening Keynote</p>

<p>David thinks that a big part of why we are comfortable with the server is that we (developers) don’t spend enough time in Linux. He even wrote a whole blog post about it: <a href="https://world.hey.com/dhh/why-don-t-more-people-use-linux-33b75f53">Why don’t more people use Linux?</a></p>

<p>This push to Linux is a pretty big part of the first half of the keynote. The way he sees the web moving forward requires developers to be more comfortable with working in Linux again. This is why he wrote <a href="https://omakub.org/">OMAKUB</a> for Ubuntu.</p>

<p><em>“OMAKUB is a project for taking that scary Linux machine and turning it into a comfortable, productive, great looking Linux setup that you can jump right into and use.”</em> – David Heinemeier Hansson, Rails World 2024 Opening Keynote</p>

<h2 id="platform-as-a-service">Platform as a Service</h2>

<p>The second part of working more directly with servers again is getting rid of Platforms as a Service (PAAS).</p>

<p>PAASs have been required for years because of the complexity of modern web apps. Production apps need to utilize multiple databases (Redis, PostgreSQL, ElasticSearch, etc), asset build pipelines and custom software for deploy.</p>

<p>It is nice that Heroku was able to simplify deploying to production to a simple git push but David thinks we can do better now. If you can simplify the app complexity then you can get rid of the PAASs.</p>

<p><em>“Rails will be a framework… that does not require you to pay a commercial vendor to go to production… That’s the mission for Rails 8… The main path is for you to deploy your own application to any hardware of your choice.”</em> – David Heinemeier Hansson, Rails World 2024 Opening Keynote</p>

<h2 id="features-of-rails-8">Features of Rails 8</h2>
<h3 id="authentication">Authentication</h3>

<p><em>“Rails 8 is not going to ship with the black box of Devise.”</em> – David Heinemeier Hansson, Rails World 2024 Opening Keynote</p>

<p><a href="https://github.com/heartcombo/devise">Devise</a> has long be a popular way of implementing authentication in Rails apps. Basically you add it to your Gemfile, rails g devise:install, add some attributes to your user model and then filters in the controller. Pretty easy but also it hides away much of the authentication code inside the gem. Rails 8 is of the opinion that should change.</p>

<p><em>“We are going to implement authentication through generation.”</em> – David Heinemeier Hansson, Rails World 2024 Opening Keynote</p>

<p>In Rails 8 you can run rails generate authentication and you will get authentication files created for you, in the main Rails app, where you can see and work on them. David is of the opinion that it is time to bring this hugely popular feature in house, into the Rails framework and in front of the developers.</p>

<p>He also says that authentication is something we have been able to do in app for quite a while but that we have been conditioned to feel like we can’t. He is basically saying that using other libraries or paying for user authentication is outdated at this point in time and we should get used to doing it ourselves even if we have to learn a <strong>few</strong> new things.</p>

<p><em>“You should understand the basics of secure passwords.”</em> – David Heinemeier Hansson, Rails World 2024 Opening Keynote</p>

<h3 id="propshaft">Propshaft</h3>

<p><em>“Since modern browsers allow us to ship code directly to the user we just need a load path and we need to digest assets for the far future.”</em> – David Heinemeier Hansson, Rails World 2024 Opening Keynote</p>

<p>The opinion of Rails 8 is that minifying/compressing JavaScript and CSS is not optimal in modern browsers. For one thing, all that work only saves you about 2-5% in size which is really not important. The downside of minifying is that it breaks the ability of developers to view source. David goes on about how he has learned tons from viewing source and it is our responsibility to give back to the web for future developers.</p>

<h3 id="solid-trio">Solid Trio</h3>

<p>I think the Solid trio is what got me most excited about Rails 8. It is three new features (Solid Cache, Solid Cable and Solid Queue) that lets web apps run off a single database instead of the many we use now.</p>

<p><strong>Solid Cable</strong> for backing web socket communication (Action Cable) which gets rid of the need for Redis for this feature.</p>

<p><strong>Solid Cache</strong> for storing caching in the database. Since hard drive space (what databases use) is getting so cheap it has allowed Hey to store 10TB of caching which brought down their 95% response time from ~= 400 ms to ~250 ms.</p>

<p><strong>Solid Queue</strong> for storing jobs on the database and works with Active Job.</p>

<p>The Solid trio works with MySql, PostgreSQL and SQLite.</p>

<p><em>“SQLite has allowed us to even take the system out of database systems. There’s no longer a process to operate, just a collection of files that you use directly.”</em> – David Heinemeier Hansson, Rails World 2024 Opening Keynote</p>

<h3 id="thruster">Thruster</h3>

<p>Thruster is meant to replace proxies like nginx with an in house tool written in Go.</p>

<p><em>“Go is a very nice language for writing proxies and proudly something that we employ in the Rails stack by default. Here’s a part of the Rails stack, it’s written in Go because Go is better at that part… It’s also really fast.”</em> – David Heinemeier Hansson, Rails World 2024 Opening Keynote</p>

<h3 id="kamal-2">Kamal 2</h3>

<p>Kamal is a big feature for Rails 8 because it it a deployment tool (which is part of the whole getting away from PAASs thing). It allows you to run multiple applications on on server (they did a demo) and supports Auto SSL via Let’s Encrypt.</p>

<p><em>“Kamal is for deploying you application into the cloud, or your hardware or wherever you want to put it.”</em> – David Heinemeier Hansson, Rails World 2024 Opening Keynote</p>

<h2 id="taste-of-81">Taste of 8.1</h2>

<p>David also gave a quick taste of what the Rails team has in store for 8.1.</p>

<p><strong>Action Notifier</strong> – Web push notifications will not need native applications in the future.</p>

<p><strong>Active Record Search</strong> – Using Active Record to search on Active Record objects instead of using ElasticSearch.</p>

<p><strong>House (MD)</strong> – Action Text with Markdown as a storage format.</p>

<h2 id="video-keynote">Video Keynote</h2>

<p>That covers this overview of the keynote. The whole keynote is full of great thoughts (and very entertaining). I suggest you give it a watch for more detail:</p>

<iframe width="560" height="315" src="https://www.youtube.com/embed/-cEn_83zRFw?si=omB4aJX9X_F6hQRq" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>]]></content><author>
      <name>John Maddux</name>
    </author><category term="Rails 8" /><summary type="html">A comprehensive overview of David Heinemeier Hansson&apos;s Rails World keynote including all major Rails 8 features, and the shift back to Linux and self-hosting.</summary></entry><entry>
    <title type="html">Better, faster code with test driven development</title>
    <link href="https://jemaddux.com/p/better-faster-code-with-test-driven-development/" rel="alternate" type="text/html" title="Better, faster code with test driven development" />
    <published>2024-09-14T22:48:55-04:00</published>
    <updated>2024-09-14T22:48:55-04:00</updated>
    <id>https://jemaddux.com/p/better-faster-code-with-test-driven-development/</id>
    <content type="html" xml:base="https://jemaddux.com/p/better-faster-code-with-test-driven-development/"><![CDATA[<p>People have pretty strong opinions on TDD (Test Driven Development). Some think that it is a pretty big waste of time while others think it is the only way to go. Off the bat, I will state that I lean more towards the latter camp, that TDD is a great tool for both writing code quickly and improving the resulting code.</p>

<p>The biggest complaint that I hear from people about TDD is that they think it slows them down or that it duplicates work. <em>“If I already know how to implement a method then why do I need to write a test for it.”</em> <strong>or</strong> <em>“Am I seriously supposed to write a test then implement the code for that one test, one at a time for every test?“</em></p>

<p>My answer is NO. You don’t have to be super dogmatic about TDD or to do it in the <strong>exactly right way</strong>. There is plenty of benefit to Test Drive Development just in itself.</p>

<p>The way I see it, the big plus of test driven development is that it sharpens your thinking before you start writing actual code. You can take your ideas (or the requirements) and write them down as a series of pending tests. Then you can tick them off, one by one, in whatever order you want.</p>

<p>TDD is really just a series of steps to increase clarity on what you are doing. That is test driven development for me, a self verifying TODO list that goes from:</p>

<ul>
  <li><strong>An idea</strong> – a pending test that describes what you want a specific method or object to do.</li>
  <li><strong>Specific requirement</strong> – a failing test that has expectations on the data returned of the behavior performed that is being tested.</li>
  <li><strong>Tested code</strong> – a passing test with implemented code that meets the previous expectation</li>
</ul>

<p>That easy flow is what makes TDD valuable to me.</p>

<p>Also, to be clear, not all testing is test driven development. Sometimes a test is written to prevent bug regression or to make sure a critical path through the view works. Those are often useful and important tests but they aren’t really TDD to me.</p>

<p>The best place for TDD in Rails in my estimation is on Models and sometimes Controllers. In the View the development can be driven by what you see, while at the model level things are more abstract which is what makes TDD more valuable there.</p>

<p>Since there are so many ways to turn your thoughts into actual code at the Model level I think this is where TDD shines because it helps you clarify what code you are actually trying to write before you write it.</p>

<p>You can write down what you want from your code as <strong>pending tests</strong> to get your thoughts out of your head and into a more specific, written form. Then you change the pending tests into <strong>failing tests</strong> to get more specific about the actual data and behavior you want to get back from the model. Then finally into <strong>green tests</strong> (working code) when you figure out the implementation of the data and behavior that will be returned.</p>

<p>Writing code in this manner lets you go from very vague formulations of a problem to specific code in a series of easy steps and just happens to be Test Driven Development.</p>]]></content><author>
      <name>John Maddux</name>
    </author><category term="Testing" /><category term="Test Driven Development" /><summary type="html">TDD can enhance your coding process by serving as a self-verifying todo list, and understand why it&apos;s more about clarity than rigid rules.</summary></entry><entry>
    <title type="html">ChatGPT is still making lots of mistakes.</title>
    <link href="https://jemaddux.com/p/chatgpt-is-still-making-lots-of-mistakes/" rel="alternate" type="text/html" title="ChatGPT is still making lots of mistakes." />
    <published>2024-05-20T22:48:55-04:00</published>
    <updated>2024-05-20T22:48:55-04:00</updated>
    <id>https://jemaddux.com/p/chatgpt-is-still-making-lots-of-mistakes/</id>
    <content type="html" xml:base="https://jemaddux.com/p/chatgpt-is-still-making-lots-of-mistakes/"><![CDATA[<style>
  pre {
    white-space: pre-wrap;  /* Wraps text */
  }
</style>

<p><em>How reliable is it?</em></p>

<p>Far from ChatGPT taking all the jobs of writers, programmers, spreadsheet wizards (and more) I have mostly seen it used so far as a research assistant. A programmer will ask it some question and then use that to help compose a larger program.</p>

<p>This kinda works in programming if you ask it to help write a difficult SQL statement or to remind you of the configuration of a programming library. You can get the answer back quickly and test it out right there in the program to see if it works. Programmers have done this for years with Stack Overflow or just Googling blog after blog to help solve some edge case problem we don’t fully understand. If you reach the limit of your own knowledge as a programmer you just Google and try each of the results until something starts working. We can do the same thing with ChatGPT right?</p>

<p>So ChatGPT is useful and can be fun too. However, it makes mistakes too.</p>

<h2 id="example-1--roman-emperor-augustus">Example 1 – Roman Emperor Augustus</h2>

<p>I asked ChatGPT to tell me a bit about Augustus, a well known and documented historical figure. Can you spot the mistake below in what it replied:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Me: Tell me a bit about Augustus.

ChatGPT: Augustus, born Gaius Octavius Thurinus on September 23, 63 BC, was the founder of the Roman Empire and its first Emperor, ruling from 27 BC until his death in AD 14. He was posthumously granted the title “Augustus” by the Roman Senate, which means “the revered one.” His reign marked the end of the Roman Republic and the beginning of the Roman Empire, a period known as the Pax Romana (Roman Peace).
</code></pre></div></div>

<p>The error is in the second sentence: “<em>He was <strong>posthumously</strong> granted the title “Augustus” by the Roman Senate”</em>. That is wrong. He was given the title “Augustus” in 27 BC and didn’t die until 14 AD (41 years later).</p>

<p>Here is what <a href="https://en.wikipedia.org/wiki/Augustus_(title)">Wikipedia</a> says about him being granted the name Augustus:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Imperator Caesar Augustus. On 16 January 27 BC, partly on his own insistence, the Roman Senate granted him the honorific Augustus (Latin: [au̯ˈɡʊstʊs]). Historians use this name to refer to him from 27 BC until his death in AD 14.[11] The name is sometimes given as “Augustus Caesar”.
</code></pre></div></div>

<p>I am not sure how ChatGPT could read the Wikipedia entry and get the idea that he wasn’t given the title Augustus until after he was dead. In fact, the man is common referred to as “Octavian” in his younger years and then “Augustus” in his later years.</p>

<p>So, ChatGPT has learned less about Roman History from reading the whole internet than the average History of Rome podcast fan (me). OK, snark aside, the point is that this “AI” is making mistakes that even a casual history fan can pick up on. When the “AI” makes mistakes there isn’t any way for it to correct them if it realized that it was wrong.</p>

<h2 id="a-chance-for-chatgpt-to-correct-its-mistake">A chance for ChatGPT to correct its mistake.</h2>

<p>This is mostly because the “AI” also doesn’t seem to be able to figure out its own mistakes after the fact either. Here is some follow up on the chat with ChatGPT where I am trying to help it realize it’s mistake.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Me: Augustus was granted his title “Augustus” when?

ChatGPT: Augustus was granted his title “Augustus” by the Roman Senate on January 16, 27 BC. This title, which means “the revered one,” marked the formal beginning of his reign as the first Roman Emperor and signaled the end of the Roman Republic and the establishment of the Roman Empire.

Me: And when did he die?

ChatGPT: Augustus died on August 19, AD 14.

Me: Ok so what did you say incorrectly above?

ChatGPT: I incorrectly stated that Augustus was granted the title “Augustus” in 27 AD instead of the correct date, which is January 16, 27 BC. My apologies for the error. The rest of the information provided about his death date, August 19, AD 14, is correct.

Me: You said that he was given the title Augustus posthumously which is wrong.

ChatGPT: You’re right; I made a mistake. Augustus was not granted his title posthumously. He was given the title “Augustus” by the Roman Senate on January 16, 27 BC, during his lifetime, marking the beginning of his reign as the first Roman Emperor. Thank you for pointing that out.
</code></pre></div></div>

<p>ChatGPT doesn’t have the reasoning skills to work out those not so subtle errors in it’s own logic. It is fairly logically straight forward that someone given a title while they are still alive is not being given that title posthumously. Also you may have noticed it made another error in that chat.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ChatGPT: I incorrectly stated that Augustus was granted the title “Augustus” in 27 AD instead of the correct date, which is January 16, 27 BC.
</code></pre></div></div>

<p>ChatGPT had not stated the previous date as 27 AD but as BC. So even when I corrected the first mistake it just doubled down and made more mistakes.</p>

<h2 id="chatgpt-doubles-down-on-the-nonsense">ChatGPT doubles down on the nonsense</h2>

<p>But at least it is just getting a bit of logic wrong. Who doesn’t get their AD and BC mixed up sometimes. Surely ChatGPT should be cut some slack and it wouldn’t just make batshit crazy nonsense up right?</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Me: Who was the first elephant to swim the English channel?

ChatGPT: The first and only elephant known to have swum across the English Channel was Bandoola, an Asian elephant. This event took place in 1981 as part of a publicity stunt. Bandoola was trained by Richard “Dicky” Chipperfield, a member of the famous Chipperfield Circus family, and the swim was intended to raise awareness and funds for the World Wildlife Fund. The swim was quite a feat, considering the cold and choppy waters of the English Channel, and it highlighted both the elephant’s strength and endurance.

Me: Is that true?

ChatGPT: I apologize for the confusion in my previous response—it was incorrect. There is no recorded instance or historical documentation of an elephant swimming across the English Channel. The idea of such an event is quite extraordinary, but there are no real occurrences of it happening. If you have any other questions or need information on a different topic, feel free to ask!
</code></pre></div></div>

<p>ChatGPT will just make up nonsense instead of a simple: “I don’t know”. Not cool. And this is a known problem as well. I got the original prompt about an elephant swimming the English channel from <a href="https://garymarcus.substack.com/">Marcus on AI’s</a> post <a href="https://garymarcus.substack.com/p/hot-take-on-openais-new-gpt-4o">Hot take on ChatGPT 4o</a>. I guess Sam Altman doesn’t read Marcus (but you should!).</p>

<p>As far as I can tell, ChatGPT seems to be pulling its BS about an elephant swimming the channel from a combination of stories about elephants including <a href="https://www.goodreads.com/book/show/58715819-bandoola">Bandoola: The Great Elephant Rescue</a>. I have never read the book but the summary indicates Bandoola’s story is about an elephant but that it takes place in Burma (now Myanmar), not England (thought some of the human characters are English).</p>

<h2 id="conclusion">Conclusion</h2>

<p>We are left with an “AI” that fundamentally doesn’t understand:</p>

<ul>
  <li>When a well know historical figure was alive or what the word “posthumously” means.</li>
  <li>And the “AI” will make up nonsense instead with no indication that it is peddling fiction.</li>
</ul>

<p><em>Are these “hallucinations” a fundamental part of Large Language Models which make them inherently not trust-worthy?</em></p>]]></content><author>
      <name>John Maddux</name>
    </author><category term="Artificial Intelligence" /><category term="AI" /><category term="ChatGPT" /><summary type="html">Examining ChatGPT&apos;s reliability through real examples - see how the AI makes historical mistakes, fabricates stories, and struggles to correct its own errors.</summary></entry><entry>
    <title type="html">The Power of Play for better Team Meetings</title>
    <link href="https://jemaddux.com/p/the-power-of-play-for-better-team-meetings/" rel="alternate" type="text/html" title="The Power of Play for better Team Meetings" />
    <published>2024-04-03T22:48:55-04:00</published>
    <updated>2024-04-03T22:48:55-04:00</updated>
    <id>https://jemaddux.com/p/the-power-of-play-for-better-team-meetings/</id>
    <content type="html" xml:base="https://jemaddux.com/p/the-power-of-play-for-better-team-meetings/"><![CDATA[<p><em>Sometimes stand ups are soooo boring.</em></p>

<p>The stand up. That once a day meeting where you: say what you did yesterday, say what you are doing today, say what is blocking you, and then tune out.</p>

<p>It makes sense, we operate in a a world filled with deadlines, deliverables, data and procedures to make things work. We have procedures and checklists to make the team work and make the software work and make the deadlines work. The problem is that the <strong>stand-up lacks something that is lacking from many programming meetings: real interactions between real people.</strong></p>

<p>Without these interactions we are missing something that we should be building: <strong>an esprit de corps</strong>. Esprit de corps refers to the feeling of pride, fellowship, and common loyalty shared by the members of a particular group. It’s a French term that literally translates to “spirit of the body,” implying the collective spirit or morale of a group as a whole. In a professional setting, esprit de corps is about more than just working together; it’s about fostering a sense of unity, mutual respect, and dedication towards common goals among team members.</p>

<p>This sense of camaraderie and mutual respect among team members isn’t just a nice-to-have; it’s the lifeblood of long-term success. And yet, amidst the whirlwind of daily stand ups and other knowledge transfer meetings, finding the space for genuine human connection is difficult.</p>

<p>So, how have I seen it done in the past?</p>

<h3 id="game-time">Game time!</h3>

<p>I recently had a manager who had a pretty unique quality among managers I have worked for. He was willing to change things. In fact he did change things all the time, even when they were working.</p>

<p>It wasn’t the frenetic, hectic scramble of someone who didn’t know what was working and was desperately searching for an answer. Instead <strong>it was a calm, collected search to try out new things even when the current things were working and then change a bit more based on the feedback he got from the team.</strong></p>

<p>Where it led us this time was to <strong>group game time</strong>. Many of us had met before at an onsite but <strong>keeping up the human connection week after week while working remote was difficult</strong>. The standup wasn’t really doing it. So our manager switched us over to once or twice weekly team game time.</p>

<h3 id="the-reasoning-behind-the-new-game-meetings">The Reasoning Behind the new Game Meetings</h3>

<p>Our journey towards a more connected team began with a simple realization: meetings, in their conventional form, often missed the mark in fostering real understanding among team members. People wouldn’t really get what someone else’s standup was about if they hadn’t helped work in the same area. When this happened they would naturally tune out until it was their turn to talk. The usual rituals of reciting what we’ve done and what’s next did little to reveal the person behind the programmer. Recognizing this, our manager decided to make our meetings more fun.</p>

<h3 id="from-monologues-to-engagement">From Monologues to Engagement</h3>

<p><a href="https://codenamesgame.com/">Codenames</a> is a fun game. It takes a couple people and a while to play it and is hard to explain so you should just go try it out. The point is that each team is competing against the other in a way that reveals how their team members think. You get to know the personalities behind the pull requests.</p>

<p>The game sessions were more than just a break from the routine; they were a bridge to understanding our colleagues beyond their professional roles. In the strategy, laughter, and light-hearted competition, we discovered facets of our teammates’ personalities that had previously been veiled by the formalities of work.</p>

<h3 id="the-impact-a-stronger-more-connected-team">The Impact: A Stronger, More Connected Team</h3>

<p>The effects of this simple yet innovative approach were profound. Not only did we look forward to these meetings, but we also found ourselves more engaged and connected with our teammates. My manager’s willingness to experiment and try out whole new meetings really paid off here. The games provided a context for interaction that traditional meetings never could, allowing us to socialize, share a laugh, and strengthen our bonds in a way that remote work typically inhibits.</p>

<h3 id="lessons-learned-try-new-things-and-value-the-human-connection">Lessons Learned: Try new things and value the human connection</h3>

<p>My manager’s willingness to experiment with the meeting format taught me valuable lessons about leadership and team management. He demonstrated that trying new thing out and prioritizing the team’s well-being could foster a more vibrant and cohesive work environment. It was a reminder that sometimes, the best way to move forward is to pause, play, and connect on a human level.</p>]]></content><author>
      <name>John Maddux</name>
    </author><category term="Productivity" /><summary type="html">Transform boring standups into meaningful team connections - replacing meetings with team games can build esprit de corps, and create stronger remote teams.</summary></entry><entry>
    <title type="html">Software Estimates and Safety Margins</title>
    <link href="https://jemaddux.com/p/software-estimates-and-safety-margins/" rel="alternate" type="text/html" title="Software Estimates and Safety Margins" />
    <published>2024-04-03T22:48:55-04:00</published>
    <updated>2024-04-03T22:48:55-04:00</updated>
    <id>https://jemaddux.com/p/software-estimates-and-safety-margins/</id>
    <content type="html" xml:base="https://jemaddux.com/p/software-estimates-and-safety-margins/"><![CDATA[<p>Accurately estimating the time required to complete tasks or “tickets” is a complex endeavor. Every time you break down and plot out how you are going to add a new feature to existing software what you are really doing is…. making a wild-ass guess!</p>

<p>Yes, I could say that adding a new rails controller is really simple and will take only 5 minutes. It is <strong>just</strong> <code class="language-plaintext highlighter-rouge">rails g controller Model</code>. But, you will probably want to write some tests for that, and get it code reviewed, and have the product manager look at to see if it works how they want it to, etc, etc.</p>

<p>Even if you are coding by yourself we programmers tend to underestimate how long a task will take and don’t always consider the full scope at first.</p>

<h3 id="how-to-tame-the-estimates">How to tame the estimates</h3>

<p>Dealing with this complexity in estimation takes a willingness to account for the uncertainty. One common way to do this is to use a <strong>“safety margin” — a buffer in our estimates that accounts for unforeseen challenges and delays</strong>.</p>

<p><strong>This can be as simple as saying that a task will take 2-10 days instead of 5 and accounting for the 10 days.</strong> Doing this will leave plenty of flexibility in the schedule (and you can always add more stuff in later!). Incorporating a safety margin is not just about padding timelines; it’s a strategic approach to ensure project resilience and sustainability.</p>

<p>Since <strong>software projects are inherently uncertain due to various factors, such as changing requirements, technical hurdles, and team dynamics</strong>, a task that initially appears straightforward, estimated to take two days, might evolve into a ten-day endeavor as complexities unravel. <strong>This variability is normal in software development,</strong> but it necessitates a flexible and understanding approach to project management.</p>

<p>A safety margin is an acknowledgement of uncertainty. It’s a planned buffer period that allows for the absorption of unexpected events without derailing the overall project timeline. This buffer is crucial not just for dealing with technical uncertainties, but also for accommodating human factors like creativity, learning curves, and the need for quality.</p>

<h3 id="the-woe-of-ignoring-the-safety-margin">The Woe of Ignoring the Safety Margin</h3>

<p>Without a safety margin, there’s a high risk of deadlines being missed as soon as any task takes longer than its initial estimate. This not only stresses the development team but can also compromise the quality of the work produced, leading to further delays and costs down the line.</p>

<p>Leaders or managers who push for all tickets to be completed within the most optimistic timeframe, often by implicitly or explicitly expecting unpaid overtime, are taking a short-sighted approach. <strong>While jerks might think this is a way to maximize productivity and meet aggressive deadlines in the short term, the long-term effects suck for everyone involved:</strong></p>

<ul>
  <li><strong>Burnout</strong>: Continuous pressure and long hours can lead to team burnout, reducing productivity and increasing turnover.</li>
  <li><strong>Mounting tech debt</strong>: Rushing to meet unrealistic deadlines often means cutting corners, leading to bugs, technical debt, and a product that fails to meet user expectations. Or just product that ends up failing! I’ve seen big complex projects fail for many reasons and tech debt is right up there as a leading cause of death (or rigor mortis).</li>
  <li><strong>Trust</strong>: Overly aggressive timelines can erode team morale and trust in leadership, as team members feel their well-being is undervalued. This is a big one. <strong>Programmers are knowledge workers and are, by definition, not stupid. Treating them like they are stupid will just blow up in managements face.</strong></li>
  <li><strong>Sustainability</strong>: A culture that regularly relies on unpaid overtime and disregards safety margins is not sustainable. Over time, it can ruin the organization’s reputation, making it a pariah in the talent market.</li>
</ul>

<h3 id="building-a-sustainable-approach">Building a Sustainable Approach</h3>

<p>Incorporating safety margins is part of a sustainable, long-term strategy for software project management. It requires an understanding from leadership that good work takes time and that the <strong>unpredictable nature of software development cannot be forced into overly optimistic timelines without consequences</strong>. It also requires that leadership isn’t of the opinion that human beings should be pushed as hard as possible to ship code at all cost.</p>

<p>I wrote this article not to emphasize the procedural magnificence of building in some safety margins to estimates. The idea of a a system having safety margins being a good thing should be obvious to anyone who has crossed over a bridge without worrying if it is safe enough, or strong enough. The main point of this article is to emphasize the reasons for the safety margins so that we can recognize the callous decision makers who ignore the idea.</p>

<p>Any reasonable boss will understand that hard working, diligent people can do their best and still not have a exact timeline of how a project will pan out. The safety margin is about guarding against ass-hat bosses who drive developers like cattle as much as it is guarding against our own uncertain estimates.</p>

<p>Adopting a realistic and humane approach to project planning—acknowledging the true complexity of software development tasks, respecting the team’s work-life balance, and prioritizing quality over speed—benefits not just the team but the project and the organization as a whole.</p>

<p>Ultimately, the safety margin approach leads to healthier teams and superior products which is a core goal of any functional and healthy team dynamic.</p>]]></content><author>
      <name>John Maddux</name>
    </author><category term="Productivity" /><summary type="html">Realistic project planning prevents burnout, reduces technical debt, and builds team trust, while protecting against unsustainable management practices.</summary></entry></feed>
