1- Shield away from dependencies. Use languages that are robust (no JS, no PHP) and if possible, generate native .exes (Delphi, Rust, Go,...).
Langs with large runtime/deps (Java, .NET, Js) are always trouble in the long run. I re-enter with .NET Core and have regretted heavily it (because maintenance, not performance or dev productivity).
ie: If a lang/tool/ecosystem is for large teams (java, .net, c++), is not for zero maintenance.
How easy is to setup and get running something (without resort to auto-installers or docker images) is a high evidence in how good will be for this metric.
2- If possible (mobile) use iOS. Android is not robust at all for long term prospects
I made a enterprise iOS app that is also nearly worry-free. My only job is to upgrade xcode and recompile from time to time.
I enter android late in the game, dreaming that android become more or less good. Not.
3- Important! If possible, split the programas between what could be "zero maintenance" and high maintenance.
I have made one in Delphi that is running 10 years in some places with zero calls after the first 3 years of tweaking.
Is split in 2 parts: The Delphi side have stay solid, and the "business" side that requiere more changes are in scripts in python that I integrate with the Delphi side.
Even the python side is now near worry free, but I need to do changes here and there.
4- If need JS, pick VERY carefully how use it. JS is the anti-tesis of zero maintenance. The web is hostile in this area. You could lower damage if VERY carefully know what to use.
5- Stay away of stupid "is for scalability" traps. Micro-services, nosql and similar are the best way to destroy productivity. Modular code yet running in a monolithic (or maybe in a REST api + client) will be more than enough by long margins when coupled with postgresql or sqlite. Again, a solid RDBMS is what most need. "Eventual" consistency is a stupid choice most of time.
P.D: I'm solo developer, and have not time or high pay to cover for bad choices, so i try to perform very well in this metric.
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.
* 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.
I spent quite a bit of time getting it off the ground, but over the last 2 years, I've spent maybe ~10 hours in total keeping it running.
The only times when I've had to invest time into it, is when a certain piece of my tech stack gets deprecated or discontinued. For example, I had originally done login-auth through a SaaS provider, which then got acquired by a larger company which discontinued their API. I then had to go through their migration process to keep the site running. However, the above doesn't happen all that often, especially if you choose stable technologies and companies.
Besides that, I had consciously designed the site to be completely free of manual maintenance, even if it involved more upfront costs. Examples:
- Going serverless via Heroku
- Using SaaS services like RDS, S3, SendGrid etc
- Using scripts and cron-jobs/heroku-schedulers to automate anything that needs periodic maintenance
- Relying on "push" alerts as opposed to "polling" alerts. Ie, when something goes wrong, your server should notify you immediately. Instead of waiting for you to periodically check some dashboard
More details: https://software.rajivprab.com/2018/04/29/caucus-tech-stack/
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?
There are only three reasons I've been drawn into some projects: 1) A bug occurs and needs to be fixed 2) An external dependency breaks something
- Write tests and/or have high confidence in code/infrastructure behavior (using tools you know really well helps). Avoid cognitive complexity in code constructs aggressively. - Limit integration w/ 3rd parties EXCEPT the ones that reduce your goal of zero-maintenance. - Create interfaces/tooling which make automating tasks easy. - Get notified when things break
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.
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.
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)
It is a Debian-powered machine, not connected to internet, which is performing various tasks and controlling some hardware. The software running on it was built 6 years ago in C++ and using OpenCV and CUDA. The machine powers on and off itself on a specific routine due to on-site checks.
It clears old logs automatically if older than X days or bigger than Y MBytes.
Until today, no software or hardware failure occurred. The whole disk is snapshotted with dd command. If hard drive failures occur, it's easy to swap it and start again.
1. Don’t use a build system. Use scripting language that comes preinstalled on Debian / Ubuntu. Peel 5 is still my weapon of choice for robust small web apps. Look at python too.
2. Avoid JS / Ajax. I can bet that security restrictions will break it in the future, however good old form POST works still pretty good.
3. Use own hardware. Raspberry PI with HDD or some banana PI works quite allright. Also provisioning is easy by keeping a copy of your image.
4. Don’t use managed services. Use database on the very same machine that you host the app itself. Backup is an extra step you can achieve via those, but don’t use External service, since it will most probably break.
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.
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.
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.
Entrepreneurs occasionally ask me to take their idea and make it a reality. Their most common request is for me to build them a website so that they can sell stuff. Sure, I could take their money and build it, but it's much better for them to sell on an existing e-commerce site or learn how to use a CMS.
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.
If you don't want to be a lifetime maintainer, then you have to transfer ownership to someone else or consider the project to have reached its end of support.
Consider an analogy to building houses, it may appear that the builder has finished their job since the house is fully constructed, but like any system, it requires maintenance for the entire duration of its lifetime.
Systems degrade over time without maintenance.
Perhaps this should be elevated to "Burnam's Law".
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.
1. KISS, keep it simple, stupid.
Keep your code as simple and straight forward as possible. You can do that in a few ways: - As others have said, focus on keeping dependencies to a minimum. This can include libraries but also other 3rd party vendors/external apis. - try to keep feature creep out. the more complex the codebase the more likely it is to suffer failures. Keep things focused on solving specific problems.
2. Build software that is meant to be delegated.
You can't remove all dependencies. Whether its libraries, external apis, or hosting, every piece of software needs something to run. If you don't want to be stuck as a lifetime maintainer, then you'll need to ensure your code can run without you. There are many ways to do this: - use existing, well tasted, stable technology that is supported and maintained by your org, not something new and fancy for each project. - enlist others to help early on, sys admins, hosting providers, or whomever. Build your software in a way that is supported by those providers.
* 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.
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.
You haven't provided enough context here, but since we even patch software on Mars I doubt you can built a bug free, feature complete software that will last "forever", so you'll need to find ways to delegate maintenance to someone else.
But the odds of something that simple meeting your goals is unlikely.
And have no outside integration other than the most common of protocols.
So program defensively and expect to have to do the occasional bit of maintenance.
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.
- Never upgrade
- Cloudflare for SSL
Overall stick with technologies that have been around for a long time and have proven themselves to be stable and their developers do value stability. Sadly most developers prefer to run fast and break things, regardless of tech, so your options will be limited. Also avoid anything latest, greatest, shiny and new - even if their developers promise stability, at least for the initial versions until the tech matures a bit.
If you see anything that uses semver run away. Semver might sound like a good idea on the surface in that any breaking change means increasing a major version. But the flip side of that coin is that by choosing semver the developers communicate that they do plan on breaking backwards compatibility at some point. Despite the excuses a lot of semver enthusiasts will tell you, there are very very VERY few reasons to break backwards compatibility and the vast vast majority of them are imposed from outside (e.g. the sort where your OS drops 32bit support and there isn't anything you can do about it or the architecture you were relying on isn't supported by anyone anymore).
On the desktop stick with languages that either have multiple independent implementations (independent not only in terms of who developers it, but also in terms of codebase) based on a standard, like C and C++. This way you can switch between implementations in case something goes bad. Also do not use the latest versions of the standard unless every implementation (and by "every" i mean "really, truly, every" not just the popular ones) implements it with more or less the same features (stick with the least implemented ones). This gives you a greater set of choices to switch when you decide to switch.
For desktop UI on Windows use the Win32 API or roll your own. If you plan on being cross platform, roll your own anyway since the only thing you can rely on (at least for the foreseeable future) on Linux is X11 - anything else is bound to break and/or not exist in your users' computers. Note that if you also plan on supporting macOS rolling your own may not be liked over there and you should seriously consider if it is worth the hassle since as Apple has proven many times they do not care about backwards compatibility so you'll need to maintain your app regardless (though you can try and minimize that to just a recompile).
For web i do not know much, but i'd stick with stuff that do not break. PHP and Java seem stable. Client-side things tend to be very stable though Google does give me the impression that they'd like to flex their muscle to drop some stuff they consider "bad".
For mobile abandon all hope, it is the most ephemeral platform.
Beyond that, make either very small programs that you can easily modify or make modular programs that you can swap out things without much hassle.
Personally i work with desktop. For my own stuff i stick with C89 and Free Pascal. The former doesn't change, the latter does change but very very infrequently and it is all statically compiled anyway so assuming the underlying stuff do not change they'll work. Lazarus on Linux will eventually be an issue because Gtk2, but there isn't much that can be done about that (the author of FPGUI - that only relies on X11 - says that it can be used with the LCL FPGUI backend, but personally i haven't tried it and i think the backend isn't very mature). Win32 stuff is practically eternal (and funnily enough on Linux Win32 via Wine is the stablest ABI - essentially making x86+Win32+C89 the most stable combo even if Microsoft drops it :-P).