The /home/mustafa/dev/projects directory on my computer is like a digital cemetery. It contains everything from half-finished PHP scripts from 2012 to Golang backends from 2021 that I thought "would definitely take off" but were only used by 3 people (one of whom was my mom). My 20 years of field experience has taught me this: starting a project is exciting, growing it is hard, but pulling the plug is a true sign of professionalism.
Most of the time, we form emotional bonds. We deceive ourselves with excuses like "I buried 3 weekends into that," "I stayed up all night designing that PostgreSQL schema," or "The domain is very generic, it might come in handy one day." In reality, that project is nothing more than 120 MB of RAM wasted in the docker stats output and a $15 domain fee charged to the credit card every year. Today, I will explain the "kill criteria" I apply to my own projects and my technical cleanup process.
Infrastructure Costs and "Idle" Resources
The cost of a side project isn't just money; the mental load is much more expensive than the cash. I had a small financial calculator running on my VPS. Only 5-10 people visited it per day, but there was a PostgreSQL instance, a Redis, and an Nginx reverse proxy running in the background. One day, when I checked with the top command, I saw that this project was consuming 15% of system resources even while sitting idle.
We tend to fill everything up, thinking Docker containers are "isolated anyway." However, every systemd unit or Docker container writes logs, takes up space on journald, and creates context switching overhead at the kernel level. Last year, when I shut down 4 different small projects that were no longer receiving traffic, I saw the Load Average on the server drop from 0.85 to 0.12. This meant a more stable environment for the applications that are my main business and actually make money.
# A simple monitoring method I use to identify idle projects
<figure>
<Image src={cover} alt="An old, dusty computer case among server cables with a " />
</figure>
# I find upstreams that haven't received requests in Nginx logs in the last 30 days
grep "14/Apr/2026" /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -nr
If a project hasn't shown organic growth in the last 3 months and is technically not even in "maintenance mode" but is essentially "abandoned," it doesn't deserve that VPS cost. I now invest in 2 "working" projects instead of keeping 20 "maybe" projects on a $10 server.
Dependency Hell and Bit Rot
Code is fresh the day it's written; it starts to go stale the next day. I didn't update one of my side projects (it was an Android spam blocker app) for 6 months. When I opened the project last week for a bug fix, I saw that the Gradle version was no longer supported, 3 different libraries I used were "deprecated," and the API level had fallen below Play Store standards.
This is the moment when the "pull the plug" decision is most clearly made: When the maintenance cost exceeds the development cost. If you enter a 4-hour dependency hell just to make a simple text change, that project is no longer an asset; it's a shackle. Those 45 critical vulnerability warnings that appear when you run npm install to get the project running are a message telling you, "bury me already."
⚠️ Important Criterion
If a library in your project contains a critical security vulnerability like CVE-2026-XXXX and you're brushing it off saying "who's going to update this now," shut that project down immediately. It's only a matter of time before your server becomes part of a botnet.
In my own systems, especially in Python-based backend projects, I see how the pip freeze output gets cluttered over time. At some point, the incompatibility between versions in the requirements.txt file makes the project "untouchable." Code you are afraid to touch is dead code.
The Domain Renewal Trap: "It Might Be Useful One Day"
We all have a "domain graveyard," I know. I renewed a domain I bought in 2018 thinking I'd do "smart agriculture automation" every year until 2024. I paid a total of $90, but there's neither a sensor nor a single line of code. When the domain renewal email arrives, we say "I'll definitely do it this year" with that momentary rush of adrenaline.
I have a rule now: If there isn't even an index.html running under the domain and I haven't made a single commit to that domain in the last year, I turn off the "Auto-renew" button the moment I see the renewal email. Letting go of the domain is the most concrete step in ending the project in your mind.
As I mentioned in my [related: optimizing VPS costs] post, every unnecessary asset opens an "unfinished business" folder in your mind. The more of these folders you have, the less RAM (brainpower) you can allocate to the tasks you actually need to focus on.
| Criterion | Kill Decision | Keep Decision |
|---|---|---|
| Traffic | Last 90 days < 100 unique visitors | Steady growth or stable audience |
| Security | Unpatched CVEs, old kernel modules | Up-to-date dependencies |
| Cost | Monthly > $10 (if no revenue) | Revenue > Expense or high learning value |
| Motivation | You're afraid to open the code | You're eager to add new features |
Pulling the Plug Protocol: Safe Destruction
When I decide to close a project, I don't just hit the "delete" key. It's a 20-year sysadmin reflex; there must always be an "exit strategy." One day, an algorithm in that code or those 3-5 lines of data in that database might be needed.
The standard "Kill Protocol" I follow is as follows:
- Database Dump: If I'm using PostgreSQL, I take the schema and data with
pg_dump. If the data is small, I also export it as JSON so it's easy to parse if I do something with another language (e.g., Go instead of FastAPI) in the future. - Static Archive: If it's a website, I take a static copy of the site with
wget --mirror. At least to see "what it looked like." - Code Archive: I
tar.gzthe project folder and throw it into a very cheap "Glacier" bucket on S3 or a physical external disk. I mark it as "Archived" on GitHub. - Cleanup: I delete the
systemdunit on the server, clean up Docker images withdocker rmi, and remove the Nginx configuration.
# Example of taking a PostgreSQL backup and compressing it
pg_dump -U mustafa_user -h localhost my_dead_project_db | gzip > my_dead_project_db_$(date +%Y%m%d).sql.gz
# Docker system cleanup (use with caution)
docker system prune -a --volumes
The feeling of lightness that follows this process is priceless. Freeing up an extra 400 MB of RAM on the server and seeing the disk usage drop from 85% to 60% opens up space for new and more sensible projects.
Corporate Software Perspective and "Opportunity Cost"
The biggest mistake I saw while developing a production ERP was the obsession that "every module must always work." There were some reports that a manager had requested 5 years ago; the manager had left the company, but that report continued to run every night at 03:00, straining the SQL server. We make the same mistake with side projects.
You need to understand the concept of "Opportunity Cost" well. Every hour you spend keeping a dead project alive is actually time stolen from a new idea with potential. If I'm working on a production planning algorithm and an alarm goes off because an old "weather bot" failed, repairing that bot is a waste of time for me.
Once, a memory leak occurred in the backend of my own side project. Every 12 hours, the OOM-killer would kick in and kill the process. Since I was lazy, I wrote a cron job that restarted it every 6 hours. This is technical proof that you should pull the plug on a project. If you've started working around the problem instead of solving it, that project has become a burden for you.
Lessons from the Graveyard
Every closed project is not a failure but a data point. When I closed that spam blocker I developed for Android, I learned: "Building a native bridge on the mobile side is very costly; next time I should choose a simpler architecture." Or when I closed a financial calculator: "People want to see results with one click instead of complex forms."
Don't be afraid to clean up your side project graveyard. That graveyard is actually your library of experience. You just need to clear the dusty shelves to make room for new books. I perform a "Project Audit" every 6 months. If a project is stealing from my sleep, my pocket, or my main job, I say goodbye to it.
After all, I've been in this industry for 20 years, and the most successful people I've seen were those who knew what to stop doing, rather than just those who knew what to do. Take a look at that idle docker-compose.yml file on your server; maybe today is its last day.
In the next post, I'll talk about how we build more effective "production-ready" systems with the resources we gained from this cleanup.
Top comments (0)