Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
title: "The Hard Part of Software Has Never Been Code"
description: "Why software slows as systems age, and why the real challenge is changing live systems with care through migrations and partial rollouts."
createdAt: 1770156760883
updatedAt: 1770156760883
authors: ["david"]
category: "DEVELOPER EXPERIENCE"
editors: ["velimir"]
abstract: "A long-form look at why the hardest part of software is not writing code but changing live systems without breaking the business. The essay explains how partial migrations, coexistence between old and new systems, and real-world constraints make \"best practices\" fail. It outlines practical questions leaders should ask about safety, rollback, and recovery, and argues that AI can accelerate code but not replace judgment."
image: "/images/gitops-is-it-the-right-choice-for-your-devops.png"
draft: false
---

Code is cheap, and writing software is easier than it has ever been. Engineering teams still hesitate to deploy and freeze subsystems while "temporary" fixes last for years.

That happens because changing the system feels unsafe.

Teams can prompt out a service and wire up infrastructure in days. The slowdown shows up later, once the system is in production and carrying years of questionable technical bets. Progress slows and no one knows how to ship without breaking some other part of the system.

## Software becomes a liability

Every system, no matter how well it is designed, reaches a moment when deploys need to be organized rather than just done, small changes cause visible problems for users, and billing logic becomes too risky for developers to touch. From then on, software is no longer about shipping features and starts being about limiting damage when things go wrong.

We have worked with systems where the frontend was rewritten twice and the backend three times. On paper, each iteration brought the new code that was better, cleaner, and easier to maintain.

The riskiest moment was never the new code itself. The danger is the period in between, when the old system and the new system have to exist at the same time.

Data needed to be synchronized. Users moved back and forth between old and new screens. Edge cases appeared that were never documented. Small logical oversights caused confusing bugs and broken workflows.

Every serious technical plan runs into the same question: what happens when this is only half done? In real life, projects pause, priorities change, teams change, and budgets move. If a plan only works when it is 100% complete, it is a dangerous plan.

## "Best practices" quietly fail

Engineering best practices assume teams can stop feature work and freeze production, just so they can fix large parts of the system in isolation. In the real world this does not happen, and organizations that wait for that perfect moment usually end up never fixing the system at all.

Revenue depends on systems working nonstop. Teams still need to ship new features, fix bugs, and support users, while they try to fight the bad bets they made and technical debt that is accumulated.

**System improvment has to live with delivery.**

## AI does not solve this

AI is excellent at churning out code, but it is far less helpful when two systems need to coexist indefinitely, data models evolve mid migration or when subsystems behave wildy different than expected.

Human reason can't and shouldn't be automated away.

## What real progress looks like in practice

Teams that systems forward do things that feel uncomfortable. They tolerate temporary duplication and extra complexity. They plan exits before committing to start implementing so they can stop or roll back when needed.

Massive zero downtime changes are rarely clean or fast, but they do work.

For engineering leaders, useful question to ask here are purely practical ones. How safely can changes ship? How easy is rollback? How quickly can the team recover? How confident do people feel deploying to production?

Teams that can answer these questions keep shipping, even under pressure. Teams that can't... slow down until nothing moves.

## The advantage teams underestimate

The best engineering teams don't use cutting edge tools or default doing big rewrites. They build systems that can be worked on and maintained by real devs, under real pressure, with real money on the line.

This confidence comes solely from experience: migrations that took longer than expected, rewrites that didn't pay off, infrastructure failures, and production incidents where the cost of a wrong decision is enormous.

The hardest part of software was always how to change an existing system without putting the business at risk, and choosing that path even when it looks slower.

At CroCoder, this mindset shapes how we work as software development consultants.

We don't champion a particular framework or push a rewrite. We start by understanding the constraints: what must keep running, where risk truly lives, and how much change the system can safely take without breaking. From there, we help CTOs make technical decisions in real conditions: live users, active revenue, existing teams, and limited tolerance for mistakes.

In practice, this usually means working incrementally. We test plans against production, prioritize changes so progress is visible, and make sure each step is reversible. For growing companies, this preserves momentum without quietly accumulating risk nor debt. For enterprises, it moves them forward without destroying what already works.