Why Does Working Code Break?
You wrote a deployment script 3 years ago. It worked perfectly. You haven't changed a single character since. Today, you run it, and it fails. Did the bits on disk decay? Did cosmic rays flip a bit in your source file? Almost certainly not. The code didn't change, but everything around it did.
Software Rot (also called bit rot, code decay, or software entropy) is the phenomenon where software degrades over time despite not being modified. The term is deliberately borrowed from physical decay because the effect is the same: something that once worked gradually stops working, not because of any action taken on it, but because of the passage of time and changes in its environment.
The four primary causes of software rot:
1. Dependency Drift
Your code depends on libraries, APIs, and services maintained by other people. Those people don't stop working just because you do. A dependency version you pinned years ago can get yanked from its package registry, or a newer transitive dependency it relies on can drop support for the Python or Node version you're still running — either way, a fresh install of the exact same lockfile that worked before now fails.
2. Environment Drift
The operating system, runtime, and infrastructure your code runs on are continuously updated — often automatically. A script written against an older language version can start failing outright once that version's standard library removes a module the script quietly depended on, or once deprecation warnings the language used to tolerate become hard errors.
3. Data Drift
The data your code processes changes in volume, shape, or distribution over time.
- Your database grew from 1GB to 1TB. Your
SELECT *query now times out. - Your log parser assumed log lines were under 1KB. A new microservice emits 50KB log lines.
- Your ML model was trained on 2021 user behavior. Users behave differently in 2024.
4. Security Rot
A special and critical form of software rot. Code that was secure when written becomes vulnerable as new attack vectors are discovered. A TLS version that was perfectly acceptable a few years ago can become disabled by default in modern clients, so an endpoint that never changed suddenly starts rejecting connections from anyone using an up-to-date browser or library.
Preventing Software Rot — The Practical Toolkit:
| Problem | Prevention Tool |
|---|---|
| Dependency drift | Lock files (package-lock.json, Pipfile.lock), Dependabot, Renovate |
| Environment drift | CI scheduled runs (not just on commits), Docker image pinning |
| Data drift | Performance regression tests with realistic data volumes |
| Security rot | Automated CVE scanning (Trivy, Snyk), regular dependency audits |
Code is not a diamond; it is a garden. If you do not tend it — updating dependencies, testing against new environments, monitoring performance as data grows — it decays. Scheduled CI runs (e.g., a nightly pipeline that runs your full test suite even when no code changed) are one of the most underused tools for detecting software rot early, before it becomes a production incident.
When asked "How do you ensure long-term reliability of infrastructure code?" a strong answer includes: pinning dependency versions with lock files, running CI on a schedule (not just on commits) to detect environment drift early, using tools like Dependabot or Renovate for automated dependency updates, and treating infrastructure code with the same maintenance discipline as application code. Mentioning "software rot" by name and explaining the four causes — dependency drift, environment drift, data drift, and security rot — signals systems-level thinking that distinguishes senior candidates.
Key Point: Software rot is the strongest argument against the "if it ain't broke, don't touch it" philosophy. Code that isn't actively maintained is already breaking — you just haven't noticed yet. The cost of continuous maintenance is always less than the cost of discovering three years of accumulated rot during an emergency at 2am. Scheduled maintenance sprints and automated dependency updates are not busywork; they are the immune system of your codebase.