---
title: "A one-line change should not take three weeks"
description: "When a small change to an internal tool takes weeks, the cause is usually architecture: coupled queries, scattered logic, and no shared data model."
canonical: "https://stackdrop.co/blog/internal-tools-slow-to-change-architecture"
published: "2026-06-29T09:00:00.000Z"
updated: "2026-06-29T09:00:00.000Z"
authors: ["John Miniadis"]
topics: ["Rescue and migration", "Production"]
readers: ["builders", "operators"]
---

# A one-line change should not take three weeks

The request was to rename "Pending" to "Awaiting review" on the refunds screen. It shipped three weeks later, along with a fix for two tables that stopped rendering after the first attempt.

When small changes take that long, the engineers are rarely the cause. The structure makes every change risky, so each one starts with an investigation.

## Where the time goes

Writing the change is quick. Finding out what it will break is not. Say a query is wired straight into a button, and the same query feeds a table three components away. Editing the button means tracing every place that query is read. The engineer spends a day mapping dependencies and an hour editing.

The pattern shows up in builds where the first version shipped fast and was never restructured. A field is renamed in the database, and four components stop rendering, each referencing the old name in its own place. Nothing flagged it, because the tool has no single layer that knows the shape of the data.

Live data raises the stakes. Changes land on screens the operations or support team uses all day, so the engineer moves carefully. Given the structure, that caution is rational.

## Three decisions that make a tool expensive to change

All three come down to coupling: parts that should move independently are tied together.

**Queries wired into the interface.** The data fetch lives inside the component that displays it, so data and presentation cannot change separately.

**Logic scattered across components.** A rule about who can approve a refund sits in one button's event handler. A slightly different copy sits in another, and neither is the official version.

**No written model of how the tool behaves.** The only record of the logic is the running code. Every engineer who touches it rebuilds the picture from scratch, and usually only the first builder holds it. [Why your internal tools behave the way they do](https://stackdrop.co/blog/systems-logic-internal-tools) covers mapping that logic before the build.

In a Retool app, the common version is rules living in component event handlers instead of in named queries. It works on the first pass. By the tenth change, the rules are spread across the canvas with no index. Retool gives the build what it needs to avoid that: named queries, a shared query library, and source control. Moving the logic there gives each rule one place to change.

## Change problem or effort problem?

Look at where the time goes on a small request, rather than how long it took overall.

An effort problem looks like a queue. The change is straightforward, the engineers understand it, and it waits behind other work.

A change problem looks like a one-line edit that takes a week. Most of the week goes on reading existing code to see what the edit will affect. The signals:

- Engineers call routine changes risky.
- A label change needs a full regression check.
- Only the original builder can make changes safely.

That last signal is a property of the build. The knowledge lives in one head because the structure never recorded it.

Backlog pressure hides all of this. A slow tool reads like a staffing gap, so the team adds engineers. The new engineers face the same investigation cost, because the cost sits in the structure. The queue moves, and each change costs what it did before.

## What makes a tool cheap to change

Three properties, all forms of separation:

- **Data, interface, and logic kept apart.** A query can change without touching the components that read it. A component can change without rewriting the fetch beneath it.
- **Logic in named, source-controlled queries.** The next engineer reads the structure instead of reverse-engineering it.
- **A data model that describes the tool.** One place knows the shape of the data, so a rename is caught before it ships.

Built this way, access rules, audit logging, and source control are part of the structure. They give engineers a safe way to make and review changes on live systems, which removes most of the reason for caution. Added afterwards, the same controls slow each release, because they sit on a structure not designed to carry them.

The same separation keeps a tool fast, because a query can be tuned without rewriting a screen. [Keeping internal tools fast as they grow](https://stackdrop.co/blog/performance-architecture-internal-tools) covers that side.

## Low-code or custom code?

The problem appears in both. Hand-written React and a low-code build slow down the same way when queries, interface, and logic are coupled. A disciplined Retool build with named queries and source control is easier to change than tangled custom code. The platform changes how coupling looks. The build decides whether it costs you.

## Our view

We recommend fixing the structure before adding people, because more engineers on a coupled tool pay the same investigation cost on every change. Usually that is a refactor in place. Move the logic out of component handlers into source-controlled queries, remove duplicate queries, and write the data model down.

A full rebuild is the exception, for tools whose data model itself is wrong. Which path to take is the product owner's call, made with the dependency map in hand. [How to build internal software that still works as the business grows](https://stackdrop.co/blog/build-scalable-internal-software) covers the principles behind it.
