41554 blogs · [ { "id": "01a0d927-9fe9-71c4-bb8f-abfb074e73a6", "title": "AI is antithetical to learning", "url": "https://jola.dev/posts/ai-antithetical-learning", "published_at": "2026-09-22T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8364510f214", "title": "Migrating your Bluesky account the hard way", "url": "https://jola.dev/posts/migrating-atproto-account-hard-way", "published_at": "2026-09-08T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d83645847345", "title": "Cluster singleton pattern", "url": "https://jola.dev/posts/cluster-singleton-pattern", "published_at": "2026-08-31T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d836459b1745", "title": "cove.town, atproto self-hosted self-hosting", "url": "https://jola.dev/posts/cove-town-atproto-self-hosted", "published_at": "2026-08-28T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d836464367a7", "title": "Speeding up a Phoenix LiveView web app with a CDN", "url": "https://jola.dev/posts/speeding-up-phoenix-liveview-cdn", "published_at": "2026-08-26T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d83647370a4e", "title": "Self-hosting an atproto container registry", "url": "https://jola.dev/posts/self-hosting-atproto-container-registry", "published_at": "2026-08-25T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d836478eaf88", "title": "Migrating to the new Tangled knot2", "url": "https://jola.dev/posts/migrating-tangled-knot2", "published_at": "2026-08-23T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d836485d75c1", "title": "Self-hosting and Tangled", "url": "https://jola.dev/posts/self-hosting-and-tangled", "published_at": "2026-08-20T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d836488f4ecb", "title": "Self-hosting your PDS", "url": "https://jola.dev/posts/self-hosting-your-pds", "published_at": "2026-08-18T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d836496fab9a", "title": "Taking control of your atproto account", "url": "https://jola.dev/posts/taking-control-atproto-account", "published_at": "2026-08-16T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d83649e9d63c", "title": "No cost, no value", "url": "https://jola.dev/posts/no-cost-no-value", "published_at": "2026-08-11T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8364a33d454", "title": "Latch - an Elixir atproto OAuth library", "url": "https://jola.dev/posts/latch-elixir-atproto-oauth-library", "published_at": "2026-08-06T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8364a94bcf8", "title": "Limited output is a feature", "url": "https://jola.dev/posts/limited-output-is-a-feature", "published_at": "2026-08-04T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8364abf3b1e", "title": "Distributed rate limiter with HRW in Elixir", "url": "https://jola.dev/posts/distributed-ratelimiter-with-hrw", "published_at": "2026-07-29T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8364ac62779", "title": "A computer can never be held accountable", "url": "https://jola.dev/posts/a-computer-can-never-be-held-accountable", "published_at": "2026-07-28T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8364bc5a0a0", "title": "Elixir Cluster 101", "url": "https://jola.dev/posts/elixir-cluster-101", "published_at": "2026-07-21T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8364c1956cf", "title": "How to stop Claude from saying load-bearing", "url": "https://jola.dev/posts/how-to-stop-claude-from-saying-load-bearing", "published_at": "2026-07-14T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8364c76bd73", "title": "Let libraries be libraries", "url": "https://jola.dev/posts/let-libraries-be-libraries", "published_at": "2026-07-07T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8364c7aa9c8", "title": "CI workflows on Tangled for Elixir", "url": "https://jola.dev/posts/ci-workflows-on-tangled", "published_at": "2026-07-04T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8364c87c825", "title": "Automatically syncing your blog to atproto and standard.site", "url": "https://jola.dev/posts/automatically-syncing-your-blog-atproto-standard-site", "published_at": "2026-06-29T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8364d6ae28c", "title": "Appreciation for the small web", "url": "https://jola.dev/posts/appreciation-for-the-small-web", "published_at": "2026-06-15T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8364e3d05cb", "title": "Treating LLMs as programming books", "url": "https://jola.dev/posts/treating-llms-as-programming-books", "published_at": "2026-06-09T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8364f2af6d5", "title": "Publishing your blog to standard.site in Elixir", "url": "https://jola.dev/posts/publishing-your-blog", "published_at": "2026-06-05T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8364fc49035", "title": "Generating OG images in Elixir", "url": "https://jola.dev/posts/generating-og-images", "published_at": "2026-06-01T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8365033af37", "title": "The social contract of writing", "url": "https://jola.dev/posts/the-social-contract-of-writing", "published_at": "2026-05-25T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d836503787ae", "title": "Highest Random Weight in Elixir", "url": "https://jola.dev/posts/highest-random-weight-in-elixir", "published_at": "2026-05-21T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d836510f66c8", "title": "bunnyx: a bunny.net Elixir client library", "url": "https://jola.dev/posts/bunnyx-bunny-net-elixir", "published_at": "2026-05-17T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d836517df59f", "title": "Building for the joy of building", "url": "https://jola.dev/posts/building-for-the-joy-of-building", "published_at": "2026-05-12T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d836519888ed", "title": "Running local models on an M4 with 24GB memory", "url": "https://jola.dev/posts/running-local-models-on-m4", "published_at": "2026-05-10T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8365297082f", "title": "How to hit your Claude weekly limit so you can go outside and touch grass", "url": "https://jola.dev/posts/how-to-run-out-of-usage", "published_at": "2026-04-13T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8365334d35c", "title": "Dropping Cloudflare for bunny.net", "url": "https://jola.dev/posts/dropping-cloudflare", "published_at": "2026-04-02T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d83653cc4224", "title": "Building a blog with Elixir and Phoenix", "url": "https://jola.dev/posts/building-a-blog-with-elixir-and-phoenix", "published_at": "2026-03-24T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d83653e61c94", "title": "Stay in the Loop: How I Actually Use Claude Code", "url": "https://jola.dev/posts/stay-in-the-loop", "published_at": "2026-03-07T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d83654544d1d", "title": "Ruthless Prioritization: The Path to Delivery", "url": "https://jola.dev/posts/ruthless-prioritization", "published_at": "2025-08-18T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d836545ff074", "title": "Estimates Are More Valuable Than You Think", "url": "https://jola.dev/posts/estimates-are-more-valuable", "published_at": "2025-08-04T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d836554bb097", "title": "When Software Engineers Think They Need More Focus Time", "url": "https://jola.dev/posts/enough-focus-time", "published_at": "2025-07-28T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d836562574cd", "title": "If the Goal is Resiliency, Defensive Programming is Your Enemy", "url": "https://jola.dev/posts/defensive-programming-resilience", "published_at": "2025-07-21T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d83656367786", "title": "The Magic of Daily Pull Requests: Why Smaller is Better", "url": "https://jola.dev/posts/a-pr-a-day", "published_at": "2025-07-19T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8365652315a", "title": "Building a Distributed Rate Limiter in Elixir with HashRing", "url": "https://jola.dev/posts/distributed-ratelimiter", "published_at": "2025-02-04T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d83656cc8df8", "title": "Announcing Hex Diff", "url": "https://jola.dev/posts/announcing-hex-diff", "published_at": "2020-01-21T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d83657702885", "title": "Building Hex Diff", "url": "https://jola.dev/posts/building-hex-diff", "published_at": "2020-01-21T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8365818fb51", "title": "Push-based GenStage", "url": "https://jola.dev/posts/push-based-genstage", "published_at": "2019-10-19T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d83658bef6c2", "title": "The Erlang :queue module in Elixir", "url": "https://jola.dev/posts/erlang-queue-module-elixir", "published_at": "2019-10-18T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8365919b244", "title": "Patterns for managing ETS tables", "url": "https://jola.dev/posts/patterns-for-managing-ets-tables", "published_at": "2019-06-05T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d836593dd726", "title": "Health checks for Plug and Phoenix", "url": "https://jola.dev/posts/health-checks-for-plug-and-phoenix", "published_at": "2019-06-01T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8365a17cef9", "title": "The new `Registry.select/2` and what match specs are", "url": "https://jola.dev/posts/registry-select-2-and-match-specs", "published_at": "2019-05-13T00:00:00+00:00" }, { "id": "01a0878f-c398-71e0-acc8-d8365a3b7514", "title": "Elixir String Processing Optimization", "url": "https://jola.dev/posts/elixir-string-processing-optimization", "published_at": "2019-04-08T00:00:00+00:00" } ] posts Claim your blog
Back to Johanna Larsson, Software Engineer and Speaker
Blog · corpus.blog/blogs/jola.dev/posts

Johanna Larsson, Software Engineer and Speaker

jola.dev

2026

2025

2020

2019