Software Entropy: A Comprehensive List

Oleg Geranin (for Finiata)

Working hard to avoid technical debt is probably the best solution, but it’s likely inevitable that your organization has some. I’ve compiled a relatively comprehensive list of the different types of Technical Debt, or “Software Entropy” that your organization could have or be accumulating.

Examples of technical debt

Lack of tests — unit tests, component tests, contract tests, integration tests, end to end tests

Bad design — wrong design decisions initially made (with the information at hand at that point in time). For example, the code is not easily changeable, incidentally complex, high cyclomatic complexity. Mostly due to lack of knowledge and experience, lack of peer review and professional growth mindset, or laziness

Lack of needed documentation — this includes documentation of the code, a setup readme, reasons for changes, the actual product, test data, troubleshooting, and FAQs

Load issues — the system becomes unusable, slow, or requires a lot of memory or computing resources when there are a lot of concurrent users

Performance issues — specific functionality is slow or requires a lot of memory or computing resources

Ignorant management — pressure for features, not allowing quality work or time

Nondeterministic workflows — for example, the order of events is not guaranteed and cannot be relied on

Pending automated tests — tests that for various reasons are marked to be skipped

Compilation and deprecation warnings — ignoring warnings makes it harder to spot new issues, until things break without notice. There is a reason for these warnings

Manual regression testing as modus operandi — not investing in an automated test suite with reasonable coverage, requires going through slow and expensive manual testing after almost every change we make

Other types of repetitive manual work that could be automated — causing people to do work that a machine could do much at a much lower cost, which would free them to take on higher-level types of work

Bad architecture — not cohesive, too many dependencies, too coupled, not secure enough, doesn’t support required scale, not easily changeable, not reversible, not supporting deferring decisions

Premature optimizations — building things before they are needed, and might not be needed at all, such as scalability or reusability

Immature and unstable libraries — adding immature and unstable libraries, which require frequent mid to large changes as they continue to evolve

Unreadable code — code that is functionally correct and perfectly fine for the machine to execute but is hard for humans to read and change. We read code much more frequently than we write code

Brittleness — certain parts have many bugs, either due to introducing changes or from normal usage of the product

A high number of defects — not enough quality baked in

Outdated workflows — requiring time-consuming workarounds

Tasks that need to be addressed — this includes things like API key rotation

Neglecting specific areas — such as an internal Admin tool that does require maintenance

Code inconsistencies — a lack of or inconsistent coding conventions

Out of date elements — Includes languages / frameworks / libraries

Security issues — in the code, in the infrastructure, or in libraries we use

Lack of mechanisms — specifically for detecting security issues

Build Debt — the build process is either manual, or automated but either slow or not deterministic

Hero culture — get things done, no matter how it happens, leading to knowledge silos and low bus factor

Infrastructure debt — not enough testing environments, not compatible with the needs, no cost optimization, no automation of the infrastructure

Recurring operational issues or reliability — repeating complaints from customers or from internal users forces developers to handle them in an unplanned manner, repeatedly

Process debt — lack of product discovery (validating what we should build for our users), clear development process (including testing, releasing, and monitoring), disaster recovery, incident management

Requirement debt — requirements that contain contradictions, missing business cases, or UI/UX design

Rollout issues — downtime, breaking things on releases, damage to runtime or data, lack of external communication

Slow to release (low velocity) — processes, technology, or lack of knowledge that makes changes slow to release to the market, making the feedback loop very long

Product complexity & dead features — This also includes features that serve a tiny fraction of the users but have a substantial cost of the development maintenance

GDPR and PII violations — for example, exposing employees to real customers data (Personally Identifiable Information) without justification or giving employees permissions to functionality that they do not need

Tooling debt — tools that don’t support needs, out of date, paid but not used

Note: Many organizations use the term “Refactoring” for any technical work, but for precision, it’s worth mentioning that refactoring only refers to changing the code without changing any behavior (usually to make the code more readable or changeable). Bigger initiatives tend to be re-architecture rather than refactoring.

Understanding and managing software entropy

It may seem like software entropy can be found everywhere — and this isn’t entirely false. Avoiding technical debt might sound ideal, but in many cases it is unavoidable. The effects of technical debt on a company, product, or feature vary greatly.

This is especially true in scenarios where you can gain from implementing something quickly to see how it performs, helping you to decide if it’s something worth putting more time, effort, and resources into.

It’s crucial you understand how to identify your organization’s software entropy, then examine how to manage it. If it can’t be totally avoided, it’s vital to ensure that you are paying it back sooner than later.

--

--

--

Happily programming since 1984

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Android Kotlin Coroutine Best Practices

Design pattern Command in a nutshell

Productivity Tips & Tricks

Domain-Driven Design

Android fundamental 03

Type Inference by Example, Part 3

Mastering MVVM on iOS

My experience as Unity3d team lead

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Yaniv Preiss

Yaniv Preiss

Happily programming since 1984

More from Medium

Managing the software development team

Own your technical debt

We need to talk about tech debt — part 2

This Place is a Mess, Rewrite Everything!