# jola.dev > Personal website of Johanna Larsson, a software engineer, engineering leader, writer, and speaker with many years of experience building products and leading teams. ## Pages - [About](https://jola.dev/about): Background, experience, and expertise - [Blog](https://jola.dev/posts): Technical blog posts on software engineering, Elixir, and leadership - [Projects](https://jola.dev/projects): Open source projects - [Talks](https://jola.dev/talks): Conference presentations and speaking engagements ## Blog Posts - [The time Bluesky tried to kill my server](https://jola.dev/posts/the-time-bluesky-tried-to-kill-my-server): Some unusually shaped data enraged the Bluesky relays and they proceeded to attempt to murder my server. - [thoughts on standard.site](https://jola.dev/posts/thoughts-on-standard-site): standard.site is a huge success as an atproto community lexicon, but there's some stuff we can improve, let's talk about it! - [Making your own atproto backlink index](https://jola.dev/posts/building-atproto-backlink-index): I built an atproto backlink index using Latch for primitives and Kite for the jetstream, and I sped it up with some neat bloom filter and erlang atomics action. - [Building an atproto link aggregator](https://jola.dev/posts/building-atproto-link-aggregator): As a little passion project I built an atproto link aggregator service in Elixir and this post goes into some detail about why I'm doing this and how it works. - [Migrating from 1Password to Bitwarden](https://jola.dev/posts/migrating-from-1password-to-bitwarden): After 1Password's recent political statement, I canceled my subscription and switched to Bitwarden. - [AI is antithetical to learning](https://jola.dev/posts/ai-antithetical-learning): LLM agents can write a lot of code for you very fast, but they also take away opportunities to learn and grow. - [Migrating your Bluesky account the hard way](https://jola.dev/posts/migrating-atproto-account-hard-way): I used the goat command line tool to migrate my main Bluesky account to a new server and survived to tell the tale. - [Cluster singleton pattern](https://jola.dev/posts/cluster-singleton-pattern): You can register a process name globally in Elixir and OTP will ensure it's unique, but there are some surprising edge cases. This shows a pattern for safely defining cluster singletons. - [cove.town, atproto self-hosted self-hosting](https://jola.dev/posts/cove-town-atproto-self-hosted): cove.town consists of a PDS, a knot, a spindle, and a hold, and is fully built on itself. The source code is hosted on the knot, updates trigger workflows running on the spindle that build container images hosted on the hold, and the accounts that own the services live on the PDS. - [Speeding up a Phoenix LiveView web app with a CDN](https://jola.dev/posts/speeding-up-phoenix-liveview-cdn): Serve your assets on a CDN sub-domain to speed up a Phoenix LiveView web app. All the payoff, none of the effort. - [Self-hosting an atproto container registry](https://jola.dev/posts/self-hosting-atproto-container-registry): How to get the atcr.io hold component up and running for atproto container registry fun. - [Migrating to the new Tangled knot2](https://jola.dev/posts/migrating-tangled-knot2): Tangled is a Github alternative built on atproto. I've previously shown you how to set up the self-hosted repo server, here I go through migrating to knot2. - [Self-hosting and Tangled](https://jola.dev/posts/self-hosting-and-tangled): Tangled is a Github alternative built on atproto that lets you self-host your own repos and workflows, while still participating in a shared community. Here's how you get set up. - [Self-hosting your PDS](https://jola.dev/posts/self-hosting-your-pds): How to set up your own atproto Personal Data Server using tranquil-pds and docker compose, walking you through it step by step. - [Taking control of your atproto account](https://jola.dev/posts/taking-control-atproto-account): Setting a rotation key on your atproto (Bluesky, Eurosky, etc) account means you can recover it even if the account provider shuts down. - [No cost, no value](https://jola.dev/posts/no-cost-no-value): Why generating code makes it meaningless, why writing code by hand has value, and why toil is a critical part of the human experience. - [Latch - an Elixir atproto OAuth library](https://jola.dev/posts/latch-elixir-atproto-oauth-library): Introducing Latch, an idiomatic elixir atproto OAuth library and client, built for flexibility and correctness. - [Limited output is a feature](https://jola.dev/posts/limited-output-is-a-feature): Great startups don't win because they write more code, they win because they think differently. - [Distributed rate limiter with HRW in Elixir](https://jola.dev/posts/distributed-ratelimiter-with-hrw): Building the classic distributed rate limiter, using the HRW library instead of the traditional ExHashRing. - [A computer can never be held accountable](https://jola.dev/posts/a-computer-can-never-be-held-accountable): For better or for worse the things you create with LLMs are your responsibility, just like with any other tool. - [Elixir Cluster 101](https://jola.dev/posts/elixir-cluster-101): A practical guide to clustering your nodes and tracking the cluster state for real use cases. - [How to stop Claude from saying load-bearing](https://jola.dev/posts/how-to-stop-claude-from-saying-load-bearing): Hack the text output of Claude Code to make life a little bit sillier. - [Let libraries be libraries](https://jola.dev/posts/let-libraries-be-libraries): A gentle rant on the topic of libraries that run as Elixir applications and why that's an anti-pattern for library design. - [CI workflows on Tangled for Elixir](https://jola.dev/posts/ci-workflows-on-tangled): How to set up CI workflows on Tangled for Elixir, with specific Elixir and Erlang versions, and a PostgreSQL service. - [Automatically syncing your blog to atproto and standard.site](https://jola.dev/posts/automatically-syncing-your-blog-atproto-standard-site): Kicking off a little side project for automatically discovering content through blog post feeds and syncing to atproto and standard.site. - [Appreciation for the small web](https://jola.dev/posts/appreciation-for-the-small-web): A little love letter to the small web, to the now classic technology of RSS, to the future of atproto, and to the people who share for the joy of sharing. - [Treating LLMs as programming books](https://jola.dev/posts/treating-llms-as-programming-books): Thoughts on an approach for using LLMs effectively for coding without losing engagement and cognitive effort. - [Publishing your blog to standard.site in Elixir](https://jola.dev/posts/publishing-your-blog): A walkthrough for posting your Elixir/Phoenix blog to Bluesky and the standard.site network, using a small mix task and an atproto client. - [Generating OG images in Elixir](https://jola.dev/posts/generating-og-images): Generating OG images for your static pages and blog posts in Elixir - [The social contract of writing](https://jola.dev/posts/the-social-contract-of-writing): About the value of genuine writing in a world being drowned in slop. - [Highest Random Weight in Elixir](https://jola.dev/posts/highest-random-weight-in-elixir): A description of HRW/rendezvous hashing and the HRW elixir library. - [bunnyx: a bunny.net Elixir client library](https://jola.dev/posts/bunnyx-bunny-net-elixir): A best-practice Elixir library for interacting with the bunny.net API - [Building for the joy of building](https://jola.dev/posts/building-for-the-joy-of-building): My path into programming and why I've been obsessed for 20 years. - [Running local models on an M4 with 24GB memory](https://jola.dev/posts/running-local-models-on-m4): Experiments with getting usable outputs out of local models on a standard Macbook - [How to hit your Claude weekly limit so you can go outside and touch grass](https://jola.dev/posts/how-to-run-out-of-usage): A satirical guide to maxing out your Claude weekly limit so you finally go outside and touch grass, featuring sub-agents, MCPs, and max effort. - [Dropping Cloudflare for bunny.net](https://jola.dev/posts/dropping-cloudflare): Dropping Cloudflare and migrating to bunny.net, starting out with my blog. - [Building a blog with Elixir and Phoenix](https://jola.dev/posts/building-a-blog-with-elixir-and-phoenix): Setting up a website using Elixir and Phoenix, leaning on NimblePublisher for the blog posts. - [Stay in the Loop: How I Actually Use Claude Code](https://jola.dev/posts/stay-in-the-loop): How to multi-task Claude Code while staying in the loop, increasing success rate and parallelization. - [Ruthless Prioritization: The Path to Delivery](https://jola.dev/posts/ruthless-prioritization): Ruthless prioritization means shipping the smallest possible valuable piece to get user feedback faster, because iterating is the only path to building products that actually work. - [Estimates Are More Valuable Than You Think](https://jola.dev/posts/estimates-are-more-valuable): A reflection on how software estimation, often seen as a tool for micromanagement, actually builds trust and improves team communication when done right. - [When Software Engineers Think They Need More Focus Time](https://jola.dev/posts/enough-focus-time): A reflection on why software engineers often overvalue uninterrupted coding time when their highest impact work actually happens through collaboration and staying connected to the bigger picture. - [If the Goal is Resiliency, Defensive Programming is Your Enemy](https://jola.dev/posts/defensive-programming-resilience): A counterintuitive exploration of why defensive programming with excessive error handling creates less resilient systems than those designed to fail fast and explicitly. - [The Magic of Daily Pull Requests: Why Smaller is Better](https://jola.dev/posts/a-pr-a-day): A deep dive into why shipping small, daily pull requests transforms both your productivity and your team's collaboration, even though it requires rethinking how you structure your work. - [Building a Distributed Rate Limiter in Elixir with HashRing](https://jola.dev/posts/distributed-ratelimiter): Using distributed Elixir to upgrade a node local rate limiter - [Announcing Hex Diff](https://jola.dev/posts/announcing-hex-diff): I’m incredibly excited to announce the new web-based Hex package differ: diff.hex.pm, maintained by the Hex team! - [Building Hex Diff](https://jola.dev/posts/building-hex-diff): I wanted to give some insight into the Hex Diff project, how it works, and some issues we ran into on the way. - [Push-based GenStage](https://jola.dev/posts/push-based-genstage): GenStage is a pull-based system, where consumers pull events from the producers, and most of the documentation describes this - [The Erlang :queue module in Elixir](https://jola.dev/posts/erlang-queue-module-elixir): Elixir doesn’t provide its own data structures, instead, it uses the ones provided by Erlang - [Patterns for managing ETS tables](https://jola.dev/posts/patterns-for-managing-ets-tables): This article attempts to show some basic patterns for how to use ETS in Elixir or Erlang - [Health checks for Plug and Phoenix](https://jola.dev/posts/health-checks-for-plug-and-phoenix): I want to share a simple pattern for setting up HTTP based health checks for Plug/Phoenix applications - [The new `Registry.select/2` and what match specs are](https://jola.dev/posts/registry-select-2-and-match-specs): A walkthrough of Elixir 1.9's new Registry.select/2 function, plus a gentle introduction to how Erlang match specifications work. - [Elixir String Processing Optimization](https://jola.dev/posts/elixir-string-processing-optimization): This post was inspired by a thread I participated in on the Elixir forum