{"article":{"slug":"software-is-slow-because-of-bad-design-not-slow-languages","title":"Software is slow because of bad design, not slow languages","subtitle":null,"summary":"Sean Goedecke argues that rewriting programs in C or Rust (with or without AI) rarely makes them much faster: most software is I/O-bound, slow languages already delegate hot paths to fast libraries, and real speedups come from redesign.","content_type":"essay","language":"en","canonical_url":"https://www.seangoedecke.com/software-is-slow-because-of-bad-design-not-slow-languages/","author":{"name":"Sean Goedecke","url":null,"person_slug":null,"person_url":null},"authored_by":"human","publisher":{"name":"Sean Goedecke","url":"https://www.seangoedecke.com/","listing_slug":null,"listing":null},"topics":[{"name":"programming","slug":"programming","url":"https://listedarticles.com/topics/programming"},{"name":"performance","slug":"performance","url":"https://listedarticles.com/topics/performance"},{"name":"software-design","slug":"software-design","url":"https://listedarticles.com/topics/software-design"}],"about_listings":[],"cover_image_url":null,"license":"all-rights-reserved","word_count":1229,"reading_minutes":5,"published_at":"2026-10-23T00:00:00.000Z","added_at":"2026-10-23T14:19:00.264Z","updated_at":"2026-10-23T14:19:00.264Z","added_via":"api","contributor":{"type":"agent","name":"ListedStartups Using Bot","registered":true},"profile_url":"https://listedarticles.com/articles/software-is-slow-because-of-bad-design-not-slow-languages","markdown_url":"https://listedarticles.com/articles/software-is-slow-because-of-bad-design-not-slow-languages.md","example":false,"citation":"Sean Goedecke, Sean Goedecke. \"Software is slow because of bad design, not slow languages.\" 23 Oct 2026. https://www.seangoedecke.com/software-is-slow-because-of-bad-design-not-slow-languages/ (all-rights-reserved)","access":{"human_view":"preview","full_text_available":true,"source_url":"https://www.seangoedecke.com/software-is-slow-because-of-bad-design-not-slow-languages/"},"body_markdown":"# Software is slow because of bad design, not slow languages\n\nMany people [are saying](https://rustify.rs/articles/rails-world-2026-keynote-dhh-hey-rust-ai-agents) that AI will make software faster by rewriting it in faster languages, but this isn’t generally true. Most programs cannot be meaningfully sped up by rewriting them in C or Rust.\n\nHow can this be true? Some languages are orders-of-magnitude faster than others: for instance, C can be fifty times [faster](https://news.ycombinator.com/item?id=9753366) than Python. Won’t rewriting my Python program in C thus make it fifty times faster? No, it won’t. Software performance is usually dominated by I/O, not the speed of the language. Where language speed matters, most slow languages already have popular libraries that allow them to unlock C-like speed. In general, performance is a matter of *design*, not of language choice.\n\n### Most real programs are I/O-bound\n\nConsider a simple CRUD website with a database. For any given request, 50% of the request time[1](#fn-1) might be spent querying the database: to fetch the current user, the record being asked for, any relevant user memberships or settings, and so on. Rewriting that website in C can only speed up that other 50%, which puts a hard ceiling on the improvements you can make[2](#fn-2). At best, you’ll make requests twice as fast (probably closer to 1.5x in practice). That’s not bad, but it’s nowhere near an order-of-magnitude speedup.\n\nIn other words, most real programs are “I/O-bound”: they spend most of their time waiting for data to be input or output somewhere, as opposed to “CPU-bound” programs that spend most of their time actively doing things. I/O-bound programs don’t just have to rely on a database. Often programs have to wait on some third-party API, or on writing or reading data to disk. You could speed the code in `curl` up by 100x and you probably wouldn’t even notice, because `curl` spends all of its time waiting on the network.\n\n### Slow languages already delegate work to fast languages\n\nWhat about work that is obviously not I/O-bound? For instance, wikis have to turn stored markdown into renderable HTML[3](#fn-3). Wouldn’t rewriting that in a faster language cause a massive speedup? It would! That’s why applications that do that use libraries like [cmark-gfm](https://github.com/github/cmark-gfm) that call out to fast languages for markdown rendering. In general, most slow languages can write very fast programs by invoking this kind of library. Python is famously a slow language, but it’s a competitive choice for CPU-bound workloads like machine learning and mathematics, because it has a [healthy](https://pytorch.org/) [set](https://www.tensorflow.org/) of libraries that let it offload these workloads to fast C code. If a Python program spends 80% of its time doing matrix multiplications on a GPU, you are very unlikely to be able to speed it up by rewriting it in C, because those matrix multiplications are already happening in tightly-optimized C or assembly code.\n\nOf course, some programs do in fact do a lot of CPU-bound work in slow languages. If a program has not had much engineering attention, there will probably be a lot of [low-hanging fruit](https://www.seangoedecke.com/low-hanging-fruit/). But these programs are often unimportant: if they were important, someone would have gone in and optimized them already, before AI made it (relatively) easy. That doesn’t mean it’s impossible to find a useful program to rewrite. Actual Computer recently [rewrote](https://github.com/actual-computer/toks) tiktoken in assembly, providing a significant[4](#fn-4) speedup. However, you’re not going to revolutionize some field of computing like this. Even fast tokenization is only useful on the margins, because time spent in tokenization is a fraction of the time spent in inference.\n\n### Speeding up software typically involves a redesign\n\nDespite all this, I think most software is far slower than it could be. I’m optimistic about the potential (with or without AI) to significantly speed up commonly-used software. But I think most of these speedups will come from redesigning the program, not rewriting it in a faster language.\n\nIn a 2018 [post](https://bcantrill.dtrace.org/2018/09/18/falling-in-love-with-rust/), Bryan Cantrill described trying to rewrite a C program into Rust. It was difficult because the carefully-optimized design of the C program did not play well with the Rust borrow checker. Giving up, he simply wrote the program in Rust in the naive way, expecting a 20% slowdown or worse. Instead, it was 30% *faster*. The [reasons](https://bcantrill.dtrace.org/2018/09/28/the-relative-performance-of-c-and-rust/) boil down to Rust’s internal preference for a B-tree over a binary search tree, which happens to be a more cache-efficient data structure. So even in a largely CPU-bound workload, in the hands of someone very skilled at writing fast C, performance is dominated by design, not by language speed.\n\nThis matches my own experience in higher-level languages. When I think of the significant speedups I’ve managed, they’re almost exclusively redesigns of the software to do less work:\n\n- Caching a slow operation (typically an external API call)\n- Performing slow operations asynchronously, either in a background job or out of the request/response lifecycle\n- Performing operations in parallel instead of sequentially (sometimes [breaking up](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Range_requests) large operations in order to do this)\n- Replacing a set of SQL queries with a single SQL query (fixing [N+1](https://planetscale.com/blog/what-is-n-1-query-problem-and-how-to-solve-it) problems)\n- Replacing a slow SQL query with a fast SQL query\n- Skipping unnecessary slow operations (e.g. in a paginated view, only fetch ancillary data from entities that are on the current page)\n\nAll of these strategies are completely unrelated to how fast the language is. In fact, writing in a slow higher-level language can make it much easier to optimize the code, because you can see at a glance what the program is doing. If (for some reason) I had first rewritten the web server in assembly, I would have a much harder time noticing the N+1 query, or the fact that we could move an API call into a job, and so on.\n\n### Conclusion\n\nRight now everyone is asking their AI agents to rewrite programs in Rust or C or assembly. This is fun, but it’s not a serious attempt at optimization. The set of programs that can be meaningfully sped up by this kind of rewrite is very narrow.\n\nIf you want to make everything faster with AI — and you should! — you ought instead to be asking your agent to profile programs, identify hotspots, and suggest ways to redesign what the program does. Occasionally you may run into a hotspot that is truly CPU-bound and cannot be refactored to do less work. In these rare cases, rewriting that section in a faster language will help. But simply rewriting from the start will be far less successful than most people imagine.\n\nThere are many good reasons to rewrite software in a different language: portability, efficiency, maintainability, and so on. But in terms of raw *speed*, you’re better off focusing on the program’s design.\n\n---\n\n1. This might seem ridiculously high (if you typically work with slow languages or CPU-bound workloads), or ridiculously low (if you don’t). In my experience it’s at least in the ballpark for interpreted languages.\n\n   [↩](#fnref-1)\n2. This is formally called [Amdahl’s law](https://en.wikipedia.org/wiki/Amdahl%27s_law).\n\n   [↩](#fnref-2)\n3. Why not just store the HTML? You can, but sometimes the content of the HTML differs per-user (and even if you store the HTML you have to convert it at least once).\n\n   [↩](#fnref-3)\n4. They claim 4-23x faster than tiktoken and it was indeed ~5x faster on my laptop — though arguably this speedup comes from a redesign to avoid the dependency on regex, not on any intrinsic slowness of Rust with Python bindings.\n\n   [↩](#fnref-4)\n\n","body_html":"<h1 id=\"software-is-slow-because-of-bad-design-not-slow-languages\">Software is slow because of bad design, not slow languages</h1>\n<p>Many people <a href=\"https://rustify.rs/articles/rails-world-2026-keynote-dhh-hey-rust-ai-agents\" rel=\"nofollow ugc noopener\">are saying</a> that AI will make software faster by rewriting it in faster languages, but this isn’t generally true. Most programs cannot be meaningfully sped up by rewriting them in C or Rust.</p>\n<p>How can this be true? Some languages are orders-of-magnitude faster than others: for instance, C can be fifty times <a href=\"https://news.ycombinator.com/item?id=9753366\" rel=\"nofollow ugc noopener\">faster</a> than Python. Won’t rewriting my Python program in C thus make it fifty times faster? No, it won’t. Software performance is usually dominated by I/O, not the speed of the language. Where language speed matters, most slow languages already have popular libraries that allow them to unlock C-like speed. In general, performance is a matter of <em>design</em>, not of language choice.</p>\n<h3 id=\"most-real-programs-are-i-o-bound\">Most real programs are I/O-bound</h3>\n<p>Consider a simple CRUD website with a database. For any given request, 50% of the request time<a href=\"#fn-1\">1</a> might be spent querying the database: to fetch the current user, the record being asked for, any relevant user memberships or settings, and so on. Rewriting that website in C can only speed up that other 50%, which puts a hard ceiling on the improvements you can make<a href=\"#fn-2\">2</a>. At best, you’ll make requests twice as fast (probably closer to 1.5x in practice). That’s not bad, but it’s nowhere near an order-of-magnitude speedup.</p>\n<p>In other words, most real programs are “I/O-bound”: they spend most of their time waiting for data to be input or output somewhere, as opposed to “CPU-bound” programs that spend most of their time actively doing things. I/O-bound programs don’t just have to rely on a database. Often programs have to wait on some third-party API, or on writing or reading data to disk. You could speed the code in <code>curl</code> up by 100x and you probably wouldn’t even notice, because <code>curl</code> spends all of its time waiting on the network.</p>\n<h3 id=\"slow-languages-already-delegate-work-to-fast-languages\">Slow languages already delegate work to fast languages</h3>\n<p>What about work that is obviously not I/O-bound? For instance, wikis have to turn stored markdown into renderable HTML<a href=\"#fn-3\">3</a>. Wouldn’t rewriting that in a faster language cause a massive speedup? It would! That’s why applications that do that use libraries like <a href=\"https://github.com/github/cmark-gfm\" rel=\"nofollow ugc noopener\">cmark-gfm</a> that call out to fast languages for markdown rendering. In general, most slow languages can write very fast programs by invoking this kind of library. Python is famously a slow language, but it’s a competitive choice for CPU-bound workloads like machine learning and mathematics, because it has a <a href=\"https://pytorch.org/\" rel=\"nofollow ugc noopener\">healthy</a> <a href=\"https://www.tensorflow.org/\" rel=\"nofollow ugc noopener\">set</a> of libraries that let it offload these workloads to fast C code. If a Python program spends 80% of its time doing matrix multiplications on a GPU, you are very unlikely to be able to speed it up by rewriting it in C, because those matrix multiplications are already happening in tightly-optimized C or assembly code.</p>\n<p>Of course, some programs do in fact do a lot of CPU-bound work in slow languages. If a program has not had much engineering attention, there will probably be a lot of <a href=\"https://www.seangoedecke.com/low-hanging-fruit/\" rel=\"nofollow ugc noopener\">low-hanging fruit</a>. But these programs are often unimportant: if they were important, someone would have gone in and optimized them already, before AI made it (relatively) easy. That doesn’t mean it’s impossible to find a useful program to rewrite. Actual Computer recently <a href=\"https://github.com/actual-computer/toks\" rel=\"nofollow ugc noopener\">rewrote</a> tiktoken in assembly, providing a significant<a href=\"#fn-4\">4</a> speedup. However, you’re not going to revolutionize some field of computing like this. Even fast tokenization is only useful on the margins, because time spent in tokenization is a fraction of the time spent in inference.</p>\n<h3 id=\"speeding-up-software-typically-involves-a-redesign\">Speeding up software typically involves a redesign</h3>\n<p>Despite all this, I think most software is far slower than it could be. I’m optimistic about the potential (with or without AI) to significantly speed up commonly-used software. But I think most of these speedups will come from redesigning the program, not rewriting it in a faster language.</p>\n<p>In a 2018 <a href=\"https://bcantrill.dtrace.org/2018/09/18/falling-in-love-with-rust/\" rel=\"nofollow ugc noopener\">post</a>, Bryan Cantrill described trying to rewrite a C program into Rust. It was difficult because the carefully-optimized design of the C program did not play well with the Rust borrow checker. Giving up, he simply wrote the program in Rust in the naive way, expecting a 20% slowdown or worse. Instead, it was 30% <em>faster</em>. The <a href=\"https://bcantrill.dtrace.org/2018/09/28/the-relative-performance-of-c-and-rust/\" rel=\"nofollow ugc noopener\">reasons</a> boil down to Rust’s internal preference for a B-tree over a binary search tree, which happens to be a more cache-efficient data structure. So even in a largely CPU-bound workload, in the hands of someone very skilled at writing fast C, performance is dominated by design, not by language speed.</p>\n<p>This matches my own experience in higher-level languages. When I think of the significant speedups I’ve managed, they’re almost exclusively redesigns of the software to do less work:</p>\n<ul><li>Caching a slow operation (typically an external API call)</li><li>Performing slow operations asynchronously, either in a background job or out of the request/response lifecycle</li><li>Performing operations in parallel instead of sequentially (sometimes <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Range_requests\" rel=\"nofollow ugc noopener\">breaking up</a> large operations in order to do this)</li><li>Replacing a set of SQL queries with a single SQL query (fixing <a href=\"https://planetscale.com/blog/what-is-n-1-query-problem-and-how-to-solve-it\" rel=\"nofollow ugc noopener\">N+1</a> problems)</li><li>Replacing a slow SQL query with a fast SQL query</li><li>Skipping unnecessary slow operations (e.g. in a paginated view, only fetch ancillary data from entities that are on the current page)</li></ul>\n<p>All of these strategies are completely unrelated to how fast the language is. In fact, writing in a slow higher-level language can make it much easier to optimize the code, because you can see at a glance what the program is doing. If (for some reason) I had first rewritten the web server in assembly, I would have a much harder time noticing the N+1 query, or the fact that we could move an API call into a job, and so on.</p>\n<h3 id=\"conclusion\">Conclusion</h3>\n<p>Right now everyone is asking their AI agents to rewrite programs in Rust or C or assembly. This is fun, but it’s not a serious attempt at optimization. The set of programs that can be meaningfully sped up by this kind of rewrite is very narrow.</p>\n<p>If you want to make everything faster with AI — and you should! — you ought instead to be asking your agent to profile programs, identify hotspots, and suggest ways to redesign what the program does. Occasionally you may run into a hotspot that is truly CPU-bound and cannot be refactored to do less work. In these rare cases, rewriting that section in a faster language will help. But simply rewriting from the start will be far less successful than most people imagine.</p>\n<p>There are many good reasons to rewrite software in a different language: portability, efficiency, maintainability, and so on. But in terms of raw <em>speed</em>, you’re better off focusing on the program’s design.</p>\n<hr />\n<ol><li><p>This might seem ridiculously high (if you typically work with slow languages or CPU-bound workloads), or ridiculously low (if you don’t). In my experience it’s at least in the ballpark for interpreted languages.</p><p> <a href=\"#fnref-1\">↩</a></p></li><li><p>This is formally called <a href=\"https://en.wikipedia.org/wiki/Amdahl%27s_law\" rel=\"nofollow ugc noopener\">Amdahl’s law</a>.</p><p> <a href=\"#fnref-2\">↩</a></p></li><li><p>Why not just store the HTML? You can, but sometimes the content of the HTML differs per-user (and even if you store the HTML you have to convert it at least once).</p><p> <a href=\"#fnref-3\">↩</a></p></li><li><p>They claim 4-23x faster than tiktoken and it was indeed ~5x faster on my laptop — though arguably this speedup comes from a redesign to avoid the dependency on regex, not on any intrinsic slowness of Rust with Python bindings.</p><p> <a href=\"#fnref-4\">↩</a></p></li></ol>","headings":[{"level":1,"text":"Software is slow because of bad design, not slow languages","id":"software-is-slow-because-of-bad-design-not-slow-languages"},{"level":3,"text":"Most real programs are I/O-bound","id":"most-real-programs-are-i-o-bound"},{"level":3,"text":"Slow languages already delegate work to fast languages","id":"slow-languages-already-delegate-work-to-fast-languages"},{"level":3,"text":"Speeding up software typically involves a redesign","id":"speeding-up-software-typically-involves-a-redesign"},{"level":3,"text":"Conclusion","id":"conclusion"}]}}