<channel>
  <title>Devon Estes</title>
  <link>http://devonestes.com</link>
  <description>The personal blog of Devon Estes</description>
  <lastBuildDate>Wed, 14 Jan 2026 10:23:46 +0000</lastBuildDate>
  <language>en-us</language>
  <atom:link href="http://devonestes.com/feed.xml" rel="self" type="application/rss+xml" />
  <item>
  <title>The Parable of Painting an Office</title>
  <description><![CDATA[Today I'm taking a bit of a different track on what I'm writing about. Instead of something very technical, I'm going to talk about something completely non-technical - estimation. Estimation is one of those things that everybody wants, but nobody ever really gets, and this is something that can be really hard to explain to product folks, but I've used this example to explain our faults in estimation quite a lot, and so I wanted to actually write it down and share it with folks in case they could use it as well.]]></description>
  <pubDate>Wed, 03 Feb 2021 01:01:01 +0000</pubDate>
  <link>http://devonestes.com/the-parable-of-painting-an-office</link>
  <guid>http://devonestes.com/the-parable-of-painting-an-office</guid>
</item>

<item>
  <title>Three Ways To Get Started With Mutation Testing</title>
  <description><![CDATA[I've just pushed some significant functionality from Muzak Pro into Muzak, which means that it's even easier for folks to work some mutation testing into their workflow and start seeing the benefits! Today I'm going to break down three ways that you might want to get started with that.]]></description>
  <pubDate>Tue, 12 Jan 2021 01:01:01 +0000</pubDate>
  <link>http://devonestes.com/three-ways-to-get-started-with-mutation-testing</link>
  <guid>http://devonestes.com/three-ways-to-get-started-with-mutation-testing</guid>
</item>

<item>
  <title>Three Classes of Problems Found by Mutation Testing</title>
  <description><![CDATA[It's fairly common for folks who haven't used mutation testing previously to not immediately see the value in the practice. Mutation testing is, after all, still a fairly niche and under-used tool in the average software development team's toolbox. So today I'm going to show a few specific types of relatively common problems that mutation testing is great at finding for us (and that humans are notoriously bad at finding).]]></description>
  <pubDate>Wed, 18 Nov 2020 01:01:01 +0000</pubDate>
  <link>http://devonestes.com/examples-of-mutation-testing</link>
  <guid>http://devonestes.com/examples-of-mutation-testing</guid>
</item>

<item>
  <title>Announcing Muzak and Muzak Pro</title>
  <description><![CDATA[As of today, Muzak and Muzak Pro are live! If you follow me on twitter you may have seen some hints that I've been making some good progress recently on the mutation testing library that I've been working on for close to a year now, and I think things are in a good enough place to push up the first versions of both Muzak and Muzak Pro.]]></description>
  <pubDate>Mon, 16 Nov 2020 01:01:01 +0000</pubDate>
  <link>http://devonestes.com/announcing_muzak</link>
  <guid>http://devonestes.com/announcing_muzak</guid>
</item>

<item>
  <title>Migrating to Elixir with the Strangler Pattern</title>
  <description><![CDATA[I think it's fair to say that a good amount of folks - if not the majority of them - using Elixir in production today are doing so after migrating an application to Elixir from some other language instead of just building in Elixir from scratch. Of course this idea of re-writing an application is scary, and rightly so! But there are some ways to make this process simpler and less scary, and also to reduce the likelihood of introducing regressions during this process, and that's what I'm going to go over today.]]></description>
  <pubDate>Mon, 28 Sep 2020 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/migrating-to-elixir-with-the-strangler-pattern</link>
  <guid>http://devonestes.com/migrating-to-elixir-with-the-strangler-pattern</guid>
</item>

<item>
  <title>Designing For Elixir Compiler Hints</title>
  <description><![CDATA[There are some nice new features coming in Elixir 1.11, and one many folks are excited about are some new compile-time checks. The one I've heard the most excitment about is the the compile-time check for non-existent fields in structs.]]></description>
  <pubDate>Mon, 07 Sep 2020 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/designing-for-elixir-compiler-hints</link>
  <guid>http://devonestes.com/designing-for-elixir-compiler-hints</guid>
</item>

<item>
  <title>Testing Third Party Integrations</title>
  <description><![CDATA[One thing that is always hard, regardless of what language you're working in, is testing integrations with third party services. I mean, how are you going to test something like uploading files to S3 without actually uploading the file to S3?! The answer to that is usually "mocking," but then there comes the question of how exactly one does that. Well, today I'm going to show how I test these sorts of things in code I work on.]]></description>
  <pubDate>Tue, 21 Jul 2020 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/testing-third-party-integrations</link>
  <guid>http://devonestes.com/testing-third-party-integrations</guid>
</item>

<item>
  <title>Trying To Speed Up Compilation With Absinthe</title>
  <description><![CDATA[I run my tests a lot when I'm working, and nothing bums me out more when I'm running my tests so frequently is long compile times before I can even run my tests. One of the unfortunate issues with absinthe is that it's a very macro-heavy library, and as such it effectively touches every file in your application, meaning that you need to recompile a ton of files if you're using it.]]></description>
  <pubDate>Wed, 10 Jun 2020 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/trying-to-speed-up-compilation-with-absinthe</link>
  <guid>http://devonestes.com/trying-to-speed-up-compilation-with-absinthe</guid>
</item>

<item>
  <title>Local Metrics Aggregation With Counters</title>
  <description><![CDATA[Recently I needed to get a better picture of how my application's database connection pool was doing, but there was a bit of a hitch. DBConnection has a highly optimized queuing algorithm, but the downside of that optimization is that you can't get an accurate picture of the number of idle and busy connections in the pool at any given time like you can with Poolboy.]]></description>
  <pubDate>Fri, 01 May 2020 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/local-metrics-aggregation-with-counters</link>
  <guid>http://devonestes.com/local-metrics-aggregation-with-counters</guid>
</item>

<item>
  <title>What's Inside a Reduction?</title>
  <description><![CDATA[I recently finished up the basics for a feature in Benchee that I had been pretty excited about for a while now - reduction counting! But after trying it out on my own for a bit to look for bugs and see how it could be best used so I could document the feature well, I pretty quickly ran into some confusing results.]]></description>
  <pubDate>Mon, 02 Mar 2020 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/inside-a-reduction</link>
  <guid>http://devonestes.com/inside-a-reduction</guid>
</item>

<item>
  <title>A proposal for an Absinthe application structure</title>
  <description><![CDATA[One of the great things about GraphQL is how broad the abstractions are. Everything is just an "object", with "fields"! This makes things infinitely composable, and is where a good deal of the power in GraphQL comes from. But, like all things, there are downsides to this - first and foremost is that it makes organizing a project difficult.]]></description>
  <pubDate>Mon, 27 Jan 2020 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/a-proposal-for-absinthe-project-structure</link>
  <guid>http://devonestes.com/a-proposal-for-absinthe-project-structure</guid>
</item>

<item>
  <title>Writing (and testing) a custom Credo check</title>
  <description><![CDATA[I've previously written about why one might want to write custom Credo checks, but I didn't talk about the way I actually like to go about doing it in that post, so today I'm going to break down my workflow for writing custom Credo checks.]]></description>
  <pubDate>Mon, 20 Jan 2020 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/writing-and-testing-a-custom-credo-check</link>
  <guid>http://devonestes.com/writing-and-testing-a-custom-credo-check</guid>
</item>

<item>
  <title>The truth about hiring</title>
  <description><![CDATA[It's the end of the decade, and I'm breaking from my normal technical posts for something different that's been bugging me for the last couple of months.]]></description>
  <pubDate>Fri, 27 Dec 2019 00:00:00 +0000</pubDate>
  <link>http://devonestes.com/the-truth-about-hiring</link>
  <guid>http://devonestes.com/the-truth-about-hiring</guid>
</item>

<item>
  <title>A Sneak Peek at Elixir 1.10</title>
  <description><![CDATA[It's already the middle of November, and that means that before you know it, January will be here - and January means time for a new version of Elixir!]]></description>
  <pubDate>Mon, 18 Nov 2019 00:00:00 +0000</pubDate>
  <link>http://devonestes.com/sneak-peek-at-elixir-1-10</link>
  <guid>http://devonestes.com/sneak-peek-at-elixir-1-10</guid>
</item>

<item>
  <title>Adding Gleam to your Elixir project</title>
  <description><![CDATA[There's a really cool new BEAM language out there called Gleam. It's super early days for the language, but what it offers (strong type safety) I think is worth some experimentation for folks that are interested.]]></description>
  <pubDate>Wed, 23 Oct 2019 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/adding-gleam-to-your-elixir-project</link>
  <guid>http://devonestes.com/adding-gleam-to-your-elixir-project</guid>
</item>

<item>
  <title>From Elixir to Erlang</title>
  <description><![CDATA[It's been a while since I've written here, partly because I've been taking care of my kids mostly solo for a while while my wife is out of town, but also because I've been working with a new client since the middle of April.]]></description>
  <pubDate>Wed, 12 Jun 2019 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/elixir-erlang</link>
  <guid>http://devonestes.com/elixir-erlang</guid>
</item>

<item>
  <title>Decoding Dialyzer - Part 1</title>
  <description><![CDATA[Dialyzer can be a tricky tool to figure out, but it can also be really helpful in spotting bugs or inaccurate typespecs for us, so I'm going to go through a couple of the more common warnings that you'll see in your daily use of Dialyzer to help understand what's happening, some of the causes of those common warnings, and how you can resolve them.]]></description>
  <pubDate>Thu, 14 Mar 2019 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/decoding-dialyzer</link>
  <guid>http://devonestes.com/decoding-dialyzer</guid>
</item>

<item>
  <title>Soft delete with Ecto 3 and Postgres</title>
  <description><![CDATA[One thing that folks sometimes want or need to do is to be able to "soft delete" records in a database. This means that instead of actually removing the record from a database, you in some way keep it there but make it "invisible" to your application.]]></description>
  <pubDate>Thu, 21 Feb 2019 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/soft-delete-with-ecto-3-and-postgres</link>
  <guid>http://devonestes.com/soft-delete-with-ecto-3-and-postgres</guid>
</item>

<item>
  <title>Unit Tests in Elixir - Part 3</title>
  <description><![CDATA[In part 1 of this series I went over a couple rules that I follow when writing unit tests, and in part 2 I showed how to unit test GenServers. Today, though, we're gonna be getting our hands dirty and breaking some of those rules that I laid out in part 1. I mean, what good are rules if you don't break them every now and then!]]></description>
  <pubDate>Mon, 10 Dec 2018 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/unit-tests-in-elixir-part-3</link>
  <guid>http://devonestes.com/unit-tests-in-elixir-part-3</guid>
</item>

<item>
  <title>A Proposal for Some New Rules for Phoenix Contexts</title>
  <description><![CDATA[I like rules. Decision making is way easier when there are rules there to guide you, and I like my decisions to be easy to make. Sure, sometimes we break the rules when we're writing software, and that's ok.]]></description>
  <pubDate>Tue, 20 Nov 2018 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/a-proposal-for-context-rules</link>
  <guid>http://devonestes.com/a-proposal-for-context-rules</guid>
</item>

<item>
  <title>Unit Tests in Elixir - Part 2</title>
  <description><![CDATA[In part 1 of this series I went over a couple rules that I follow when writing unit tests. Now I'm going to dig in to some of the specifics of how to unit test certain types of behavior that can be a little tricky to do properly.]]></description>
  <pubDate>Fri, 02 Nov 2018 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/unit-tests-in-elixir-part-2</link>
  <guid>http://devonestes.com/unit-tests-in-elixir-part-2</guid>
</item>

<item>
  <title>Unit Tests in Elixir - Part 1</title>
  <description><![CDATA[Unit tests are important. So are end-to-end tests that mimic real user behavior. All the other stuff in between on the testing pyramid - not so much.]]></description>
  <pubDate>Thu, 18 Oct 2018 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/unit-tests-in-elixir-part-1</link>
  <guid>http://devonestes.com/unit-tests-in-elixir-part-1</guid>
</item>

<item>
  <title>Benchmarking with StreamData</title>
  <description><![CDATA[Recently my friend and benchee co-maintainer Tobi had an idea to use benchee to run benchmarks with random data]]></description>
  <pubDate>Thu, 04 Oct 2018 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/benchmarking-with-stream-data</link>
  <guid>http://devonestes.com/benchmarking-with-stream-data</guid>
</item>

<item>
  <title>Avoiding flaky tests in Phoenix</title>
  <description><![CDATA[There is far and way a single assertion in ExUnit that is responsible for more test flakiness than any other. It's probably the culprit for more than half of all test failures that shouldn't fail.]]></description>
  <pubDate>Fri, 07 Sep 2018 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/avoiding-flakey-tests</link>
  <guid>http://devonestes.com/avoiding-flakey-tests</guid>
</item>

<item>
  <title>Writing custom Credo checks</title>
  <description><![CDATA[I love automation of things. I especially love automating the simple parts of code review, since much of that stuff can be easily automated with static analysis tools.]]></description>
  <pubDate>Wed, 29 Aug 2018 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/writing-custom-credo-checks</link>
  <guid>http://devonestes.com/writing-custom-credo-checks</guid>
</item>

<item>
  <title>Using :erlang.trace/3 to listen to garbage collection events</title>
  <description><![CDATA[I recently did a lot of traveling, which is why I haven't written for a while. In those travels, I got to meet some new Elixir friends, and we even went over some code together.]]></description>
  <pubDate>Thu, 26 Jul 2018 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/using-erlang-trace-3</link>
  <guid>http://devonestes.com/using-erlang-trace-3</guid>
</item>

<item>
  <title>All in</title>
  <description><![CDATA[Ughhh, I hate that I'm writing this post. I hate these things usually. But, I've found that I've had to repeat myself in long emails a couple times recently, and I hate that even more, so when that happens I write a blog post that I can just share the link to for future times when I need this thing.]]></description>
  <pubDate>Mon, 28 May 2018 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/all-in</link>
  <guid>http://devonestes.com/all-in</guid>
</item>

<item>
  <title>Measuring memory consumption on the BEAM</title>
  <description><![CDATA[Benchee 0.13 was released this weekend, and in that release there's one feature that I'm SUPER excited about. Starting with this release, you can now benchmark memory usage in Elixir or Erlang functions!]]></description>
  <pubDate>Mon, 16 Apr 2018 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/measuring-memory-consumption-on-the-beam</link>
  <guid>http://devonestes.com/measuring-memory-consumption-on-the-beam</guid>
</item>

<item>
  <title>What's the deal with module attributes?</title>
  <description><![CDATA[I was recently doing some work on documenting and adding some missing typespecs to the Elixir codebase, and in that work I saw something that I thought I could improve.]]></description>
  <pubDate>Wed, 14 Feb 2018 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/whats-the-deal-with-module-attributes</link>
  <guid>http://devonestes.com/whats-the-deal-with-module-attributes</guid>
</item>

<item>
  <title>How I run tests</title>
  <description><![CDATA[In recent weeks I've learned that it's not just writing tests that's important to me, but actually how I use them to benefit my development that matters as well.]]></description>
  <pubDate>Mon, 22 Jan 2018 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/how-i-run-tests</link>
  <guid>http://devonestes.com/how-i-run-tests</guid>
</item>

<item>
  <title>"For the right candidate"</title>
  <description><![CDATA[I recently went through the process of looking for a new job. I've been a remote worker for the last 6 years, and I really like the flexibility of working remotely.]]></description>
  <pubDate>Sun, 14 Jan 2018 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/for-the-right-candidate</link>
  <guid>http://devonestes.com/for-the-right-candidate</guid>
</item>

<item>
  <title>Benchmarking guard clauses</title>
  <description><![CDATA[I was lying in bed last night and for some reason I remembered this issue that was opened in July. I remembered, "Hey, I should add that to fast-elixir!" and]]></description>
  <pubDate>Thu, 07 Dec 2017 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/benchmarking-guard-clauses</link>
  <guid>http://devonestes.com/benchmarking-guard-clauses</guid>
</item>

<item>
  <title>Everything you need to know about Elixir's new formatter</title>
  <description><![CDATA[It's been a big weekend! The new formatter that José mentioned in his ElixirConf talk is finally here! It landed on Sunday, and that means we can now poke around]]></description>
  <pubDate>Mon, 09 Oct 2017 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/everything-you-need-to-know-about-elixirs-new-formatter</link>
  <guid>http://devonestes.com/everything-you-need-to-know-about-elixirs-new-formatter</guid>
</item>

<item>
  <title>Phoenix contexts aren't finished yet</title>
  <description><![CDATA[I recently migrated a Phoenix app from 1.2 to 1.3, including introducing some contexts. I like the concept in general, but I think the current implementation (from the few examples I've seen, and from the examples in the official documentation) isn't quite finished yet.]]></description>
  <pubDate>Mon, 11 Sep 2017 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/phoenix-contexts-arent-finished-yet</link>
  <guid>http://devonestes.com/phoenix-contexts-arent-finished-yet</guid>
</item>

<item>
  <title>Insurance</title>
  <description><![CDATA[I come from America. It's a beautiful, but dangerous, place. We have all sorts of terrible natural disasters that can strike at any moment, and without warning. Hurricanes, tornadoes, earthquakes, wildfires, volcanoes, tsunamis, blizzards,]]></description>
  <pubDate>Fri, 01 Sep 2017 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/insurance</link>
  <guid>http://devonestes.com/insurance</guid>
</item>

<item>
  <title>I don't really like pairing (but I want to)</title>
  <description><![CDATA[Yeah, you read that title right. I've tried to do it many times over the past few years, and I've just never felt like it was helpful or enjoyable.]]></description>
  <pubDate>Wed, 23 Aug 2017 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/i-dont-really-like-pairing</link>
  <guid>http://devonestes.com/i-dont-really-like-pairing</guid>
</item>

<item>
  <title>A Big Elixir Refactoring</title>
  <description><![CDATA[I've just finished my first really substantial refactoring of someone else's code in Elixir. I wanted to make some changes to Benchee so that it would be easier to add another feature later on. We needed a new data model, and there]]></description>
  <pubDate>Thu, 27 Jul 2017 00:18:00 +0000</pubDate>
  <link>http://devonestes.com/a-big-elixir-refactoring</link>
  <guid>http://devonestes.com/a-big-elixir-refactoring</guid>
</item>

<item>
  <title>Patronizing Open Source</title>
  <description><![CDATA[In this week's episode of The Bikeshed, Sean Griffin went through some of his issues with funding open source work through services such as Patreon, which allow individuals or companies to contribute to an individual or group on a]]></description>
  <pubDate>Tue, 18 Jul 2017 10:18:00 +0000</pubDate>
  <link>http://devonestes.com/patronizing-open-source</link>
  <guid>http://devonestes.com/patronizing-open-source</guid>
</item>

<item>
  <title>My New Favorite Elixir Testing Trick</title>
  <description><![CDATA[When I write my Ruby tests, I'm a big fan of using test doubles and asserting those doubles receive messages with the correct arguments. I guess I like to practice what Justin Searls calls Discovery Testing]]></description>
  <pubDate>Thu, 13 Jul 2017 10:18:00 +0000</pubDate>
  <link>http://devonestes.com/my-new-favorite-elixir-testing-trick</link>
  <guid>http://devonestes.com/my-new-favorite-elixir-testing-trick</guid>
</item>

<item>
  <title>Refactoring for Tests in Elixir</title>
  <description><![CDATA[I've been turning something over in my mind recently, so I'm going to try and write down some of these thoughts to get some clarity around my thinking here. Now that my talks are over for a while, I'm able to dive back]]></description>
  <pubDate>Thu, 25 May 2017 10:18:00 +0000</pubDate>
  <link>http://devonestes.com/refactoring-for-tests-in-elixir</link>
  <guid>http://devonestes.com/refactoring-for-tests-in-elixir</guid>
</item>

<item>
  <title>On Programmers and Labor Markets</title>
  <description><![CDATA[It looks like I'm going to have to learn some new things for work soon (specifically some machine learning stuff). This isn't at the top of my list of things I want to be learning, but since my manager said that it’s likely]]></description>
  <pubDate>Fri, 17 Feb 2017 10:18:00 +0000</pubDate>
  <link>http://devonestes.com/on-programmers-and-labor-markets</link>
  <guid>http://devonestes.com/on-programmers-and-labor-markets</guid>
</item>

<item>
  <title>I Got My Programming Time Back And So Can You</title>
  <description><![CDATA[I usually work remotely from Berlin (or wherever my family happens to be at the moment, which today is Sacramento), which I really like, but recently I spent about a month in the office. It was great seeing all my colleagues]]></description>
  <pubDate>Thu, 16 Jun 2016 10:18:00 +0000</pubDate>
  <link>http://devonestes.com/i-got-my-programming-time-back-and-you-can-too</link>
  <guid>http://devonestes.com/i-got-my-programming-time-back-and-you-can-too</guid>
</item>

<item>
  <title>Implementing Elixir's Pipeline in Ruby</title>
  <description><![CDATA[I've been really loving Elixir, and one of the things I've loved the most is the pipeline operator |>. You see it in cases like this]]></description>
  <pubDate>Mon, 16 May 2016 10:18:00 +0000</pubDate>
  <link>http://devonestes.com/implementing-elixirs-pipeline-in-ruby</link>
  <guid>http://devonestes.com/implementing-elixirs-pipeline-in-ruby</guid>
</item>

<item>
  <title>Go and Elixir - Separated at Birth?</title>
  <description><![CDATA[Elixir (and Erlang for that matter) handles concurrency in a really neat way - with single responsibility processes, aka the Actor model. Spawning multiple processes certainly isn't exclusive to Elixir / Erlang, and neith]]></description>
  <pubDate>Tue, 19 Jan 2016 10:18:00 +0000</pubDate>
  <link>http://devonestes.com/go-and-elixir-separated-at-birth</link>
  <guid>http://devonestes.com/go-and-elixir-separated-at-birth</guid>
</item>

</channel>
