This and Lindy Effect factors a lot into my choices for what to use for my projects. My choice for a project I want to be as maintenance-free as possible are special subsets of ASCII/txt, SQLite, Perl, Bash, PHP, HTML, JS, CSS. The subsets I choose are the parts of these languages which have persisted the longest.
Using the Lindy Effect for guidance, I've built a stack/framework that works across 20 years of different versions of these languages, which increases the chances of it continuing to work without breaking changes for another 20 years.
I love PHP, however since around 7.4 they have become pretty happy to make breaking changes to the language, including recently in ways where you cannot satisfy older and newer versions of the runtime simultaneously.
I end up spending often a couple weeks of my life on and off fixing things after every major release.
JS is hated but if you compile to browser JS that code will run in 2100. If you mainly deal with files / blobs not databases you will have these things in 2100 too. I think a lot of apps can be JS plus Dropbox integration to sync files. Dropbox may rot but make that a plugin (seperate .js file) and offer local read/write too and I think you'd be pretty future proof.
There were companies not quite worth a $billion who would have never made it that far if they couldn't convince masses of people that platform rot was good for them.
As a software user and teacher, I think about software rot a lot. My concern is that it has a tendency to grow by addition rather than replacement. New features are added whilst the fundamental limits of the architecture are left unattended to.
The reason that Blender grew from being an inside joke to a real contender is the painful re-factoring it underwent between 2009 and 2011.
In contrast, I can feel the fact that the code in After Effects is now over 30 years old. Its native tracker is slow and ancient and not viable for anything but the most simple of tasks. Tracking was 'improved' by sub-contracting the task to a sub-licensed version of Mocha via a truly inelegant integration hack.
There is so much to be said for throwing everything away and starting again, like Apple successfully did with OSX (and Steve Job did to his own career when he left Apple to start Next). However, I also remember how Blackberry tried something similar and in the process lost most of their voodoo.
those written for e.g. Linux will likely cease working in a decade or two
Have we already passed the era of DON'T BREAK USERSPACE when Linus would famously loudly berate anyone who did?
I suspect Win32 is still a good target for stability; I have various tiny utilities written decades ago that still work on Win11. With the continued degradation of Microsoft, at least there is WINE.
Unless explicitly addressed rot rate is proportional to popularity.
Unpopular targets, platforms, languages, etc don't get changed and provide a much needed refuge. There are some interpreted languages like perl where a program written today could run on a perl from 2001 and a program from 2001 would run on perl today. And I'm not talking about in a container or with some special version. I'm talking about the system perl.
Some popular languages these days can lose forwards compatibility (gain features, etc) within just a few months that every dev will use within a few more months. In these cultures sofware rot is really fast.
Nobody has a better ecosystem of “industrial marine grade code rot resistance” than Microsoft. That I can run the same .NET web app code compiled 20 years ago on a new Server 2025 is an easy experience unequaled by others. Or the same 30 year old VBA macros still doing their thing in Excel 365. There’s a company that knows how to do backwards compatibility.
I suspect this is true for a lot of software; a modern-day JVM can still run Java from 20 years ago as long as you didn't do anything weird, Linux hasn't significantly changed since then, the web is one of the most widely supported and standardized platform out there with the 1996 Space Jam website still working and rendering today as it was back then (your screen just got bigger).
Is software rot real? I'm sure, but it's not in the runtime. It's likely in the availability and compatibility of dependencies, and mainly the Node ecosystem.
I don't have experience with .NET. So that's nice to hear you've got a reliable setup. But, this has generally not been my experience with Microsoft.
There's tons of old programs from the Windows 95-XP era that I haven't been able to get running. Just last week, I was trying to install and run point and click games from 2002 and the general advise online is to just install XP. There was a way (with some effort) to get them working on Windows 7. But, there's no way to get them to work that I've seen on 10/11.
Python 2 situation opened my eyes to this. To this day I see a lot of py2 stuff floating around, especially around work environments. So much so, in fact, that I had to make scripts that automatically pull the sources of 2.7.18 and build them in the minimal configuration to run stuff.
It's hard to take this article seriously. We should write software for DOS because we won't need to maintain it post-release?
Maybe software written in the age of DOS was relatively trivial compared to modern tools. Maybe there's a benefit to writing code in Rust rather than C89.
We as an industry need to seriously tackle the social and market dynamics that lead to this situation. When and why has "stable" become synonymous with "unmaintained"? Why is it that practically every attempt to build a stable abstraction layer has turned out to be significantly less stable than the layer it abstracts over?
I think don’t worry too much about trying to avoid it. Think 5-10 years ahead max, rather than 20.
In 20-30 years there’s a good chance that what you’ve written will be obsolete regardless - even if programs from 1995 ran perfectly on modern systems they’d have very few users because of changing tastes. A word processor wouldn’t have networked collaborative editing (fine for GRRM though), an image editor wouldn’t have PNG support, and they wouldn’t be optimised for modern hardware (who would foresee 4K screens and GPUs back then - who knows how we’ll use computers in 2055).
There are also always containers if the system needs those old versions.
> For example, a program written a decade ago may no longer work with new versions of the libraries it depends on because some of them have changed without retaining backwards compatibility.
The rot is real but we have a way to run Linux (and any really) software in 40 years. For example:
From alpine:3.14
...
Just as I can run thousands of games from the 80s on my vintage CRT arcade cab using a Pi and MAME (with a Pi2JAMMA adapter), I'll be able to run any OCI container in 30 years.
The issue of running old software is solved: we've got emulators, VMs, containerization, etc.
Sure they may lack security upgrades but we'll always be able to run them in isolation.
The rot is not so much that the platform won't exist in the future or that old libs would mysteriously not be available anymore: the problem is that many software aren't islands. It's all the stuff many need to connect to that's often going to be the issue.
For games that'd be, say, a game server not available anymore. Or some server validating a program to make sure its license has been paid. Or some centralized protocol that's been "upgraded" or fell into irrelevancy. Or some new file format that's now (legitimately or not) all the shit.
Take VLC: there's not a world in which in 40 years I cannot run a VLC version from today. There's always going to be a VM or, heck, even just an old Linux version I can run on bare metal. But VLC ain't an island either: by then we'll have coolmovie-48bits.z277 where z277 is the latest shiny video encoding format.
At least that's where I see the problem when running old software.
You can't build permanent software in a world where a) everything is connected to everything else, and b) hackers will exploit anything and everything they can get their hands on.
Isn't that half the problem right there? Stop connecting everything to everything. Make your app work offline. And for anything that must connect, at least use a well defined API that can swap for some other service. E.g. S3 API is now defacto for block storage.
I wish I could write all the business logic I write on an NES and never have to worry about requirements going bad. I guess the thing is, if you're writing anything on top of a network layer of any kind, eventually it's going to require patches unless you literally own all the wires and all the nodes in the network, like a secure power plant or some money clearing system in a bank that's been running the same COBOL since the 1960s. And since you're probably not writing code that directly interfaces with the network layer, you're going to be reliant on all the libraries that do, which in turn will be subject to change at the whims of breaking changes in language specs and stuff like that, which in turn are subject to security patches, etc.
In other words, if you need your software to live in the dirty world we live in, and not just in a pristine bubble, things are gonna rot.
Picking tools and libraries and languages that will rot less quickly however seems like a good idea. Which to me means not chaining myself to anything that hasn't been around for a decade at least.
I got royally screwed because 50-60% of my lifetime code output before 2018, and pretty much all the large libraries I had written, were in AS3. In a way, having so much code I would have maintained become forced abandonware was sort of liberating. But now, no more closed source and no more reliance on any libs I don't roll or branch and heavily modify myself.
Despite it being everyone's favorite shame language, COBOL's DATA DIVISION makes it uniquely well-suited for long-term stability. Common practice is to avoid binary fields. This means what you see in your program is what you see on the wire or in a file.
>And since you're probably not writing code that directly interfaces with the network layer, you're going to be reliant on all the libraries that do
That said, why the network layer doesn't run as a socks or http proxy or something? That would greatly simplify network logic. All network libraries provide old interfaces like streams and requests.
While Emacs itself is not entirely immune to software rot (external dependencies and all), it’s truly amazing how little to no rot is experienced by elisp software (packages). If you find an Emacs package written 15 years ago, the chances of successfully running out of the box are incredibly high.
Over the course of my learning and my career, I've kind of gone back and forth on this a bit.
On the one hand, software is like a living thing. Once you bring it into this world, you need to nurture it and care for it, because its needs, and the environment around it, and the people who use it, are constantly changing and evolving. This is a beautiful sentiment.
On the other hand, it's really nice to just be done with something. To have it completed, finished, move on to something else. And still be able to use the thing you built two or three decades later and have it work just fine.
The sheer drudgery of maintenance and porting and constant updates and incompatibilities sucks my will to live. I could be creating something new, building something else, improving something, instead, I'm stuck here doing CPR on everything that I have to keep alive.
I'm leaning more and more toward things that will stand on their own in the long-term. Stable. Done. Boring. Lasting. You can always come back and add or fix something if you want. But you don't have to lose sleep just keeping it alive. You can relax and go do other things.
I feel like we've put ourselves in a weird predicament with that.
I can't help but think of Super Star Trek, originally written in the 1970s on a mainframe, based on a late 1960s program (the original mainframe Star Trek), I think. It was ported to DOS in the 1990s and still runs fine today. There's not a new release every two weeks. Doesn't need to be. Just a typo or bugfix every few years. And they're not that big a deal. -- https://almy.us/sst.html
I think that's more what we should be striving for. If someone reports a rare bug after 50 years, sure, fix it and make a new release. The rest of your time, you can be doing other stuff.
It is interesting that one of the most solid piece of software component that is relatively resistant to rotting is Shell/Bash scripts. (Including Makefiles)
Python, Ruby, etc. constantly get obsolete over time, packages get removed from the central repositories, ceasing to work.
Obviously shell scripts contain _many_ external dependencies, but overall the semantics are well-defined even if the actual definitions are loose against the shell script itself.
P.S: I have written couple of Bash-script projects that are still running (mostly deployment automation scripts) meanwhile, some of which I was being "smart" and wrote them in Python 2.7, unfortunately ceased to function, requiring upgrades...
I recently discovered how many of my bash scripts run perfectly fine in git-bash on windows. I was pleased. I believe Bun (yes the js runtime) can run .sh scripts too. And of course under WSL too. So 3 different ways I can run them on Windows. File paths can get a little sketchy but with a couple helpers it's not hard to convert back and forth.
Software does not rot, the environment around software, the very foundation which owes its existence: the singular task of enabling the software, is what rots.
Let's look at any environment snapshot in time, the software keeps working like it always did.. Start updating the environment, and the software stops working, or rather, the software works fine, but the environment no longer works.
I'm not saying never to update software, but, only do it if it increases speed, decreases memory usage, and broadens compatibility.
I like things better the way they were.
I like things better now than how they will be tomorrow.
I can't remember the last time I saw a software update that didn't make it worse.
60 comments
[ 2.6 ms ] story [ 72.2 ms ] threadUsing the Lindy Effect for guidance, I've built a stack/framework that works across 20 years of different versions of these languages, which increases the chances of it continuing to work without breaking changes for another 20 years.
I end up spending often a couple weeks of my life on and off fixing things after every major release.
Cough cough vibing cough cough
The reason that Blender grew from being an inside joke to a real contender is the painful re-factoring it underwent between 2009 and 2011.
In contrast, I can feel the fact that the code in After Effects is now over 30 years old. Its native tracker is slow and ancient and not viable for anything but the most simple of tasks. Tracking was 'improved' by sub-contracting the task to a sub-licensed version of Mocha via a truly inelegant integration hack.
There is so much to be said for throwing everything away and starting again, like Apple successfully did with OSX (and Steve Job did to his own career when he left Apple to start Next). However, I also remember how Blackberry tried something similar and in the process lost most of their voodoo.
Have we already passed the era of DON'T BREAK USERSPACE when Linus would famously loudly berate anyone who did?
I suspect Win32 is still a good target for stability; I have various tiny utilities written decades ago that still work on Win11. With the continued degradation of Microsoft, at least there is WINE.
Unpopular targets, platforms, languages, etc don't get changed and provide a much needed refuge. There are some interpreted languages like perl where a program written today could run on a perl from 2001 and a program from 2001 would run on perl today. And I'm not talking about in a container or with some special version. I'm talking about the system perl.
Some popular languages these days can lose forwards compatibility (gain features, etc) within just a few months that every dev will use within a few more months. In these cultures sofware rot is really fast.
Is software rot real? I'm sure, but it's not in the runtime. It's likely in the availability and compatibility of dependencies, and mainly the Node ecosystem.
There's tons of old programs from the Windows 95-XP era that I haven't been able to get running. Just last week, I was trying to install and run point and click games from 2002 and the general advise online is to just install XP. There was a way (with some effort) to get them working on Windows 7. But, there's no way to get them to work that I've seen on 10/11.
> while those written for e.g. Linux will likely cease working in a decade or two
there's nothing to support this claim in practice. linux is incredibly stable
Maybe software written in the age of DOS was relatively trivial compared to modern tools. Maybe there's a benefit to writing code in Rust rather than C89.
In 20-30 years there’s a good chance that what you’ve written will be obsolete regardless - even if programs from 1995 ran perfectly on modern systems they’d have very few users because of changing tastes. A word processor wouldn’t have networked collaborative editing (fine for GRRM though), an image editor wouldn’t have PNG support, and they wouldn’t be optimised for modern hardware (who would foresee 4K screens and GPUs back then - who knows how we’ll use computers in 2055).
There are also always containers if the system needs those old versions.
The rot is real but we have a way to run Linux (and any really) software in 40 years. For example:
Just as I can run thousands of games from the 80s on my vintage CRT arcade cab using a Pi and MAME (with a Pi2JAMMA adapter), I'll be able to run any OCI container in 30 years.The issue of running old software is solved: we've got emulators, VMs, containerization, etc.
Sure they may lack security upgrades but we'll always be able to run them in isolation.
The rot is not so much that the platform won't exist in the future or that old libs would mysteriously not be available anymore: the problem is that many software aren't islands. It's all the stuff many need to connect to that's often going to be the issue.
For games that'd be, say, a game server not available anymore. Or some server validating a program to make sure its license has been paid. Or some centralized protocol that's been "upgraded" or fell into irrelevancy. Or some new file format that's now (legitimately or not) all the shit.
Take VLC: there's not a world in which in 40 years I cannot run a VLC version from today. There's always going to be a VM or, heck, even just an old Linux version I can run on bare metal. But VLC ain't an island either: by then we'll have coolmovie-48bits.z277 where z277 is the latest shiny video encoding format.
At least that's where I see the problem when running old software.
In other words, if you need your software to live in the dirty world we live in, and not just in a pristine bubble, things are gonna rot.
Picking tools and libraries and languages that will rot less quickly however seems like a good idea. Which to me means not chaining myself to anything that hasn't been around for a decade at least.
I got royally screwed because 50-60% of my lifetime code output before 2018, and pretty much all the large libraries I had written, were in AS3. In a way, having so much code I would have maintained become forced abandonware was sort of liberating. But now, no more closed source and no more reliance on any libs I don't roll or branch and heavily modify myself.
Well, that's why I called BubbleOS BubbleOS: https://gitlab.com/kragen/bubbleos/
Not there yet, though...
I share your painful experience of losing my work to proprietary platforms.
That said, why the network layer doesn't run as a socks or http proxy or something? That would greatly simplify network logic. All network libraries provide old interfaces like streams and requests.
On the one hand, software is like a living thing. Once you bring it into this world, you need to nurture it and care for it, because its needs, and the environment around it, and the people who use it, are constantly changing and evolving. This is a beautiful sentiment.
On the other hand, it's really nice to just be done with something. To have it completed, finished, move on to something else. And still be able to use the thing you built two or three decades later and have it work just fine.
The sheer drudgery of maintenance and porting and constant updates and incompatibilities sucks my will to live. I could be creating something new, building something else, improving something, instead, I'm stuck here doing CPR on everything that I have to keep alive.
I'm leaning more and more toward things that will stand on their own in the long-term. Stable. Done. Boring. Lasting. You can always come back and add or fix something if you want. But you don't have to lose sleep just keeping it alive. You can relax and go do other things.
I feel like we've put ourselves in a weird predicament with that.
I can't help but think of Super Star Trek, originally written in the 1970s on a mainframe, based on a late 1960s program (the original mainframe Star Trek), I think. It was ported to DOS in the 1990s and still runs fine today. There's not a new release every two weeks. Doesn't need to be. Just a typo or bugfix every few years. And they're not that big a deal. -- https://almy.us/sst.html
I think that's more what we should be striving for. If someone reports a rare bug after 50 years, sure, fix it and make a new release. The rest of your time, you can be doing other stuff.
https://how.complexsystems.fail/
Python, Ruby, etc. constantly get obsolete over time, packages get removed from the central repositories, ceasing to work.
Obviously shell scripts contain _many_ external dependencies, but overall the semantics are well-defined even if the actual definitions are loose against the shell script itself.
P.S: I have written couple of Bash-script projects that are still running (mostly deployment automation scripts) meanwhile, some of which I was being "smart" and wrote them in Python 2.7, unfortunately ceased to function, requiring upgrades...
Same site has this article about "bedrock platforms" which resonate deeply with me https://permacomputing.net/bedrock_platform/
Software does not rot, the environment around software, the very foundation which owes its existence: the singular task of enabling the software, is what rots.
Let's look at any environment snapshot in time, the software keeps working like it always did.. Start updating the environment, and the software stops working, or rather, the software works fine, but the environment no longer works.
I'm not saying never to update software, but, only do it if it increases speed, decreases memory usage, and broadens compatibility.
I like things better the way they were.
I like things better now than how they will be tomorrow.
I can't remember the last time I saw a software update that didn't make it worse.