No-maintenance software must live in an environment which never changes (certain microcontroller code, and kiosk-type installations fit this definition). If you are devloping software exposed to the "normal" world, then change is inevitable as the environment evolves around you. Maintenance is a part of life. The key is to minimize the cost of that maintenance through good architecture and robust error handling.
You don't. You develop it as sloppy as possible and then make yourself indispensable to your company by being the only one who can maintain the pile of junk.
Seriously speaking the following things help alot:
1.Reduce external dependencies. The less integration with 3rd party apis and services the less maintenance you will be doing.
2. Reduce external dependencies.
3. Reduce external dependencies.
4. Unit Tests
5. Integration Tests
6. End to End Tests
7. Reduce external dependencies.
Two things are going to make Zero Maintenance kind of difficult. Assuming Ubuntu on an AWS EC2 instance here.
First one is taking OS updates that are security critical - as anytime you take an update theres a chance something somewhere gets broken.
Second one is AWS instances themselves being switched. From time to time (very infrequently in my experience) Amazon will send you an email indicating your EC2 instance is being migrated to a new physical host and to initiate this you must manually restart your instance.
As for the rest, a script in root's crontab that does:
1 - Delete log files older than X (because running out of disk space is not a good situation)
2 - Hit Lets Encrypt for new certs if necessary ( because expired certs give a lousy customer experience)
3 - Preemptively bounce any application servers (Nginx, PHP FPM, Tomcat, what have you )
4 - Setup all hosts such that your critical software restarts at boot time in the event of an unexpected reboot situation (gives you the ability to cron schedule nightly reboot command)
Additionally:
* If you're running any database regardless of where, be sure you allocated enough space that you don't end up running out of database storage
* Implement some downtime monitoring to tell you when there are issues
* It's a good practice to be changing passwords on any authenticated resource at some interval too
The practices listed here (off the top of my head - not an all inclusive list) are about as close as I attempt to get to Zero Maintenance myself. Customers pay for systems to be developed and they should expect some level of ongoing care and feeding as entropy is pervasive.
But its a good excuse to sell your customers a maintenance contract right?
I personally like to stop/start any application server or web sever running on my hardware over the weekend with cron. I say "Preemptively Bounce" on the assumption that which is not periodically rebooted will at some point crash. Id rather take a few minutes outage at a time of my choosing. It's basically just cheap insurance for the paranoid.
Have it do one thing very well and document it clearly so users can build it into their own processes.
If it is more complicated than that ( i.e. must do several things very well with ever-changing needs ), document it clearly and include a link to the source code and build instructions.
1. Try to make the software tolerable to the wrong input.
2. Develop tools which allows end-users to adjust the software, make as many settings as possible.
I don't think that those options are actually good in the end. If your software is tolerable to the wrong input, it might just work wrong and nobody will notice it. If there are too many options, nobody will know all of them and in the end they'll either ask you or configure it wrong. If you'll have too much of flexibility, then developers who will need to extend your software, will be forced to work bounded by inevitable restrictions.
I like software that's precise and does only one kind of thing. It crashes on wrong input, so I can either blame someone who's responsible for wrong input (I mean service, not ordinary user) or fix software. It must not be flexible, but it should have flexible architecture so I can just adjust or extend code to adapt it as necessary.
Apps can not be zero maintenance by definition. Apps are literally alive, apps mature, evolve, get older, there will always be some kind of maintenance. As world changes, apps change with it.
If ZERO maintenance is a HARD requirement, then think about total isolation. No packaging, and NO ENVIRONMENT CHANGES. With constant, isolated env, it is possible to have a minimal maintenance app.
also FYI, with zero maintenance requirement Agile approach will not work. Throw anything agile out of the door, you need a strict top to bottom waterfall with set requirements.
Another argument that Agile can not be a hammer for every nail. Common sense with project management and architecture is extremely important.
You can program defensively, which is a learned skill, and your app might run for years without complaining. But some dependency might change something and a regular push bring everything crashing down until you fix it.
So program defensively and expect to have to do the occasional bit of maintenance.
Think about it this way, every line of code you write will become obsolete one day (e.g. business will change or new version of the language comes out). Every external dependency, where you deploy, how you deploy, the OS where you host the application, even how the user consumes your application will change.
So to avoid any maintenance, minimize - code, complexity and all dependency and use a language and platform that can last a few years. Essentially, in today's world this will be very difficult and doing this will also cost you development time, there is no easy way around it.
For example, you can build your whole app in Clojure, which is rock solid and stable, but even then you will have to patch the OS, JVM, DB etc. With traffic changes you will have to scale up / down.
I've developed a couple of apps that only required a few hours a year essential maintenance. The biggest obstacles have been with being forced to upgrade libraries to work with changes to third party APIs (e.g. payment APIs, ad APIs), upgrades to do with OS changes (e.g. new versions of Android) and applying security patches to dependencies.
To decrease maintenance, generally you want to reduce your dependence on external services that might change, minimise the use of complex third party libraries that might have security problems later, and keep your app as simple as you can to reduce the chance of bugs.
It's hard to predict what changes are going to be required for a given ecosystem (e.g. Android, Mac, Chrome Web Store, web browsers) so sometimes it's a matter of luck unless you can guarantee the OS, hardware, APIs etc. are never going to change.
I'm currently working on a Chrome extension (https://www.checkbot.io) that doesn't require a lot of essential maintenance besides keeping up with changes Google have been making to make extensions more secure. Bracing myself for what breaking Manifest v3 changes are announced.
Exactly what I was thinking. Static content hosted in an environment you don’t have to patch, reboot, worry about things breaking after patches, etc. and the fact it’s static html and css means no runtime config, updating libraries, compatibility issues, etc.
I think the implication here is that you have to 'maintain your credit card'. Not an issue until you switch banks or have some sort of issue with a corporate card that you use with your AWS account.
I think it's being nitpicky for the purposes of this discussion but I think there are probably several HNers who could tell you about how their product hosted in AWS went down because of a credit card issue.
Maintenance means change. Any time something changes, you will need to update the application.
An application with zero maintenance means that it either has a very, very targeted function that doesn't change, or it isn't being used after a certain period of time.
Every part of the stack will need maintenance every now and then. Some parts even introduce breaking changes and force you to alter your own code. The slimmer the stack, the less often you have to fix it. And the less often you have to fix or refactor your application.
2: A stack that values stability
Linux is a good example. Linus Torvald: "We do not break userspace!"
PHP is a another one. The core developers rarely introduce breaking changes. And when they plan to do so, there is usually an intense fight over it.
3: Acceptance Testing
In the simplest form that means sending http requests to your web application and check if it returns the expected output. In my experience, acceptance tests find more real world issues then unit tests.
4: Write less code
Writing the same functionality with less code has multiple advantages. One of them is that it will break less often. Much more could be said about it. Paul Graham brings up the value of terseness frequently:
In order not to become a lifetime maintainer, you need to end-of-life applications. For technical reasons, we aspire to making applications have a long life, but from a business point of view, it's both unnecessary and difficult.
Don't plan for an application to live for more than five years, especially v1. Put enough work into architecture and maintainability to be able to throw it out and redevelop after five years. Be clear about this upfront. In five years' time you won't even be able to find devs to maintain what was developed today.
In order to 'maintain' an application properly business needs to keep investing in modernization of the application, which is more than just maintenance. Let's say they need to invest 30% of the original cost per year. Most will not do that saying 'It is a capital asset that I paid for and it should work as expected for as long as I need it' - okay but in five years time it will be so out of date that it will need to be redeveloped.
* sqlite says it's "zero maintenance" because nobody has to keep a database server running, and your .sqlite3 files don't need a defragmentation step or similar.
* There are middlewares like RabbitMQ where an upgrade through the OS installer generally Just Works [TM], no additional steps necessary. Yet somebody should monitor the RabbitMQ instance, just in case the service does go down, or reaches resource limits
* There are tools that have very limited scope and API surface to stay stable for a looong time, those are also kinda "zero maintenance".
In my experience, all serious business applications that automate workflows or otherwise create value do need some kind of regular maintenance.
Depending on the installation base and maintenance effort, striving for zero maintenance might not be cost effective.
> How do you as a developer, not become a lifetime maintaimer?
A maintainer is a developer.
Depending on the project, things you can do if you don't want to burden yourself with maintenance:
* Build a community around the project, and hand maintenance to the community
* abandon a project
* leave lots of documentation that makes it easy for others to maintain it
* pay somebody to maintain it
* work as a consultant/contractor, and fire the client after the initial development phase (might not be the best for your reputation, could be OK if you are up-front about it and make a very good handoff).
* If most of the maintenance is keeping it up at all, engineer for availability over consistency (if applicable to the business domain).
* Accept that maintenance is part of the normal lifecycle
The appropriate strategies highly depend on the kind of project.
Even if your business requirements never change, security updates are a thing. Many libraries have stated support policies after which a given version no longer receives updates. Fixing your application at a point in time and never updating dependencies etc is a liability. Assuming you update dependencies, at some point, you'll have breaking changes. (not really getting into the nuance of whether or not everyone will obey the rules of semantic versioning)
This all assumes your application is like most being built these days: you're using a framework on the web. If you put your application on a machine that never is exposed to the web, or you create an application with zero dependencies (including OS-level dependencies) you might get away with never updating it.
No. The only code that requires no maintenance is the code you do not write. In other words, "No code is easier to maintain than no code." Add that to the nihilist coding attributes:
Any code written will require some amount of maintenance.
The actual effort required to maintain the code will vary depending on what the code does, the environment the code runs in, and the needs of the code's end users.
Unmaintained code will ultimately fail the same way that all other things that humans build do. If someone does not maintain the code, it will eventually degrade and fail.
Anytime you write code, especially for a long-lasting endeavour, you should consider how the code you write will be maintained and what might cause it to fail sooner than expected.
That doesn't make any sense. I have code running on micro-controllers, that has been running 24/7 for 10 years. It's never going to "degrade", the hardware may fail but the code is solid.
It's really hard to answer if you don't provide any context :) Zero maintenance for a blog, small webshop or some Kubernetes controlled madness running a zillion pods? For the first two:
1) Make everything static, HTML, CSS, don't manage your own servers
2) Use as few dependencies as possible when dealing with JS
2 a) For backend try to find a service that do the work for you without you deploying your servers
I generally agree, but eventually you're gonna start getting emails saying things like "We're deprecating Node 8.x in our Lambda / Cloudfunction / etc"
By keeping it simple. Probably too simple -- If your app has any complexity, in the code, the infrastructure, or the features, it will need maintenance. If your app is literally just a static web page that does one thing, and never will need a new feature, then it can sit up on the web without maintenance.
But the odds of something that simple meeting your goals is unlikely.
99 comments
[ 3.7 ms ] story [ 174 ms ] threadThe blessing and curse of software is it's mutability.
Seriously speaking the following things help alot:
1.Reduce external dependencies. The less integration with 3rd party apis and services the less maintenance you will be doing. 2. Reduce external dependencies. 3. Reduce external dependencies. 4. Unit Tests 5. Integration Tests 6. End to End Tests 7. Reduce external dependencies.
And have no outside integration other than the most common of protocols.
First one is taking OS updates that are security critical - as anytime you take an update theres a chance something somewhere gets broken.
Second one is AWS instances themselves being switched. From time to time (very infrequently in my experience) Amazon will send you an email indicating your EC2 instance is being migrated to a new physical host and to initiate this you must manually restart your instance.
As for the rest, a script in root's crontab that does:
1 - Delete log files older than X (because running out of disk space is not a good situation)
2 - Hit Lets Encrypt for new certs if necessary ( because expired certs give a lousy customer experience)
3 - Preemptively bounce any application servers (Nginx, PHP FPM, Tomcat, what have you )
4 - Setup all hosts such that your critical software restarts at boot time in the event of an unexpected reboot situation (gives you the ability to cron schedule nightly reboot command)
Additionally:
* If you're running any database regardless of where, be sure you allocated enough space that you don't end up running out of database storage
* Implement some downtime monitoring to tell you when there are issues
* It's a good practice to be changing passwords on any authenticated resource at some interval too
The practices listed here (off the top of my head - not an all inclusive list) are about as close as I attempt to get to Zero Maintenance myself. Customers pay for systems to be developed and they should expect some level of ongoing care and feeding as entropy is pervasive.
But its a good excuse to sell your customers a maintenance contract right?
Do you mind explaining this?
If it is more complicated than that ( i.e. must do several things very well with ever-changing needs ), document it clearly and include a link to the source code and build instructions.
2. Develop tools which allows end-users to adjust the software, make as many settings as possible.
I don't think that those options are actually good in the end. If your software is tolerable to the wrong input, it might just work wrong and nobody will notice it. If there are too many options, nobody will know all of them and in the end they'll either ask you or configure it wrong. If you'll have too much of flexibility, then developers who will need to extend your software, will be forced to work bounded by inevitable restrictions.
I like software that's precise and does only one kind of thing. It crashes on wrong input, so I can either blame someone who's responsible for wrong input (I mean service, not ordinary user) or fix software. It must not be flexible, but it should have flexible architecture so I can just adjust or extend code to adapt it as necessary.
Apps can not be zero maintenance by definition. Apps are literally alive, apps mature, evolve, get older, there will always be some kind of maintenance. As world changes, apps change with it.
If ZERO maintenance is a HARD requirement, then think about total isolation. No packaging, and NO ENVIRONMENT CHANGES. With constant, isolated env, it is possible to have a minimal maintenance app.
Another argument that Agile can not be a hammer for every nail. Common sense with project management and architecture is extremely important.
So program defensively and expect to have to do the occasional bit of maintenance.
So to avoid any maintenance, minimize - code, complexity and all dependency and use a language and platform that can last a few years. Essentially, in today's world this will be very difficult and doing this will also cost you development time, there is no easy way around it.
For example, you can build your whole app in Clojure, which is rock solid and stable, but even then you will have to patch the OS, JVM, DB etc. With traffic changes you will have to scale up / down.
To decrease maintenance, generally you want to reduce your dependence on external services that might change, minimise the use of complex third party libraries that might have security problems later, and keep your app as simple as you can to reduce the chance of bugs.
It's hard to predict what changes are going to be required for a given ecosystem (e.g. Android, Mac, Chrome Web Store, web browsers) so sometimes it's a matter of luck unless you can guarantee the OS, hardware, APIs etc. are never going to change.
I'm currently working on a Chrome extension (https://www.checkbot.io) that doesn't require a lot of essential maintenance besides keeping up with changes Google have been making to make extensions more secure. Bracing myself for what breaking Manifest v3 changes are announced.
I think it's being nitpicky for the purposes of this discussion but I think there are probably several HNers who could tell you about how their product hosted in AWS went down because of a credit card issue.
Otherwise this is definitely the way to go. Nothing beats static files that you can just cp into a bucket.
- Never upgrade
- Cloudflare for SSL
An application with zero maintenance means that it either has a very, very targeted function that doesn't change, or it isn't being used after a certain period of time.
* Hosted on Heroku, which gets you continuous deployment and Let’s Encrypt
* Completely automated, even the smallest manual task
* Low traffic, which may be the most important. Apps with large and growing user bases are very difficult to manage hands-off.
Anything that depends on other stuff really is susceptible to changes and needed maintenance.
Every part of the stack will need maintenance every now and then. Some parts even introduce breaking changes and force you to alter your own code. The slimmer the stack, the less often you have to fix it. And the less often you have to fix or refactor your application.
2: A stack that values stability
Linux is a good example. Linus Torvald: "We do not break userspace!"
PHP is a another one. The core developers rarely introduce breaking changes. And when they plan to do so, there is usually an intense fight over it.
3: Acceptance Testing
In the simplest form that means sending http requests to your web application and check if it returns the expected output. In my experience, acceptance tests find more real world issues then unit tests.
4: Write less code
Writing the same functionality with less code has multiple advantages. One of them is that it will break less often. Much more could be said about it. Paul Graham brings up the value of terseness frequently:
https://twitter.com/paulg/status/1068483193605681152 https://twitter.com/paulg/status/1126403387044573185 https://twitter.com/paulg/status/1056858408039735297
Less is more. This is actually one of the reasons why I named my account no_gravity.
> Linux is a good example. Linus Torvald: "We do not break userspace!"
Sadly the people making things in userspace don't seem to mind breaking it frequently.
Don't plan for an application to live for more than five years, especially v1. Put enough work into architecture and maintainability to be able to throw it out and redevelop after five years. Be clear about this upfront. In five years' time you won't even be able to find devs to maintain what was developed today.
In order to 'maintain' an application properly business needs to keep investing in modernization of the application, which is more than just maintenance. Let's say they need to invest 30% of the original cost per year. Most will not do that saying 'It is a capital asset that I paid for and it should work as expected for as long as I need it' - okay but in five years time it will be so out of date that it will need to be redeveloped.
* sqlite says it's "zero maintenance" because nobody has to keep a database server running, and your .sqlite3 files don't need a defragmentation step or similar.
* There are middlewares like RabbitMQ where an upgrade through the OS installer generally Just Works [TM], no additional steps necessary. Yet somebody should monitor the RabbitMQ instance, just in case the service does go down, or reaches resource limits
* There are tools that have very limited scope and API surface to stay stable for a looong time, those are also kinda "zero maintenance".
In my experience, all serious business applications that automate workflows or otherwise create value do need some kind of regular maintenance.
Depending on the installation base and maintenance effort, striving for zero maintenance might not be cost effective.
> How do you as a developer, not become a lifetime maintaimer?
A maintainer is a developer.
Depending on the project, things you can do if you don't want to burden yourself with maintenance:
* Build a community around the project, and hand maintenance to the community
* abandon a project
* leave lots of documentation that makes it easy for others to maintain it
* pay somebody to maintain it
* work as a consultant/contractor, and fire the client after the initial development phase (might not be the best for your reputation, could be OK if you are up-front about it and make a very good handoff).
* If most of the maintenance is keeping it up at all, engineer for availability over consistency (if applicable to the business domain).
* Accept that maintenance is part of the normal lifecycle
The appropriate strategies highly depend on the kind of project.
They do benefit from a VACUUM from time to time [0].
[0] https://sqlite.org/lang_vacuum.html
This all assumes your application is like most being built these days: you're using a framework on the web. If you put your application on a machine that never is exposed to the web, or you create an application with zero dependencies (including OS-level dependencies) you might get away with never updating it.
Perhaps this should be elevated to "Burnam's Law".
No. The only code that requires no maintenance is the code you do not write. In other words, "No code is easier to maintain than no code." Add that to the nihilist coding attributes:
No code runs faster than no code.
No code has fewer bugs than no code.
No code uses less memory than no code.
No code is easier to understand than no code.
No code is easier to maintain than no code.
The actual effort required to maintain the code will vary depending on what the code does, the environment the code runs in, and the needs of the code's end users.
Unmaintained code will ultimately fail the same way that all other things that humans build do. If someone does not maintain the code, it will eventually degrade and fail.
Anytime you write code, especially for a long-lasting endeavour, you should consider how the code you write will be maintained and what might cause it to fail sooner than expected.
I also have a maintenance contract for one of these: https://arsandbox.ucdavis.edu/
It turns itself off at night and back on in the morning. 3 years running now without touching it once, used by hundreds of people daily.
1) Make everything static, HTML, CSS, don't manage your own servers
2) Use as few dependencies as possible when dealing with JS
2 a) For backend try to find a service that do the work for you without you deploying your servers
2 b) Maybe cloud functions are enough?
3) Write tests
4) Don't write bugs :D
5) Setup alerts (uptime robot)
I generally agree, but eventually you're gonna start getting emails saying things like "We're deprecating Node 8.x in our Lambda / Cloudfunction / etc"
But the odds of something that simple meeting your goals is unlikely.