Compass Navigation Streamline Icon: https://streamlinehq.com
applied cartography

Recent forays into developer productivity

I've written before about my posture around LLMs being mostly summarizable as design your systems and abstractions to accommodate an infinite number of junior engineers.

One of the nice things about this framing is that it sidesteps the trap of fake work that benefits LLMs and theoretical marginal productivity at the expense of actual productivity. Instead, it lets you fall into a different trap—one that I have tried so hard to avoid for the past few years—which is over-investment in developer productivity and tooling.

Here's the catch, though: this shape of work is largely toilsome and uninteresting and low-risk, making it particularly well-suited for LLMs to take initial exploratory steps. And so I ended up with a pretty nice feedback loop where, with an order of magnitude less effort on my part than would have otherwise been the case, Buttondown developer productivity has increased pretty dramatically over the past three months.


It is tricky to truly measure developer productivity. But there are at least a number of quantitative measures that are hard to argue with: fast builds, lints, and deploys are unambiguously better than slow ones.

That's where I've spent the majority of my robot-assisted efforts. None of these are even particularly clever or novel, and I list them out not in hopes that you'll be impressed but purely as a catalog of things that you should throw a bit of time at, just in case you haven't already:

Change Savings Notes
Parallelize backend linting ~14s warm, ~10s cold 52% reduction warm
Parallelize frontend linting ~48s 73% reduction
Speed up marketing preview builds ~2 min Skip Sentry source maps and prerendering
Speed up docs Vercel builds ~2.5 min Skip static page generation on previews
Speed up file generation ~60s Lightweight CSS builds, skip unchanged icons
Speed up codebase fixtures ~390ms os.walk instead of glob.glob (~12x faster)
Speed up slow tests ~30s Targeted optimizations across test files
Use pre-sent emails in comment fixtures ~10s Avoids redundant email sending during test setup
Migrate to inline-snapshot-django ~5s Faster SQL fingerprinting in perf snapshots
DRY up test suites ~15s Parametrize + deduplicate (e.g. mailgun tests: 448 → 263 lines)
Decouple asset build from Heroku deploy ~2 min Run asset build in parallel with test suite

None of these required any particular genius or even creativity. They were all, individually, the kind of thing where a sufficiently motivated (and distracted) engineer would say "yeah, I know exactly how to fix this, it's just not worth the time."

In sum: Buttondown's end-to-end CI now takes around seven minutes to run, down from ~twenty this time last year —

Step Duration What
1 ~2 min Linting + building + testing in parallel (backend suite is the long pole)
2 ~90s Deploying to the demo app and healthchecking
3 ~90s Deploying to the production app and healthchecking
4 ~90s Deploying to the constellation of other things (docs, marketing site, admin, etc.) and healthchecking

About the Author

I'm Justin Duke — a software engineer, writer, and founder. I currently work as the CEO of Buttondown, the best way to start and grow your newsletter, and as a partner at Third South Capital.

Colophon

You can view a markdown version of this post here.