The Economic Benefit of Refactoring
The Economic Benefit of Refactoring
Author: Giles Edwards-Alexander
CTO for Europe, Middle East, and India at Thoughtworks
Giles brings over a quarter-century of expertise in technical leadership and engineering, spanning industries from healthcare and fintech to retail, and technologies ranging from AI to mobile development.
This article is part of a broader series where Thoughtworks experts investigate the application of generative AI within the software development lifecycle.
The Genesis of an Agentic Application
On July 30, 2026, while exploring the capabilities of agentic engineering, I developed a tool to assist in my professional duties. This wasn't a simple script, but a comprehensive application featuring:
- A high-end web UI with and capabilities.
- Integrated modals and external system connectivity.
- Advanced text analysis and machine learning components.
- Backend job processing and a fully automated deployment pipeline.
The codebase totaled roughly 150,000 lines of code (LoC), broken down as follows:
- Rust:
- TypeScript & Terraform: The remaining
Interestingly, I adopted a hands-off approach: I meticulously reviewed every line I barely read any of the code, only glancing at it occasionally out of curiosity.
Identifying the "Code Smell"
During the build, I noticed some red flags. While watching a terminal update, I saw an edit occur at line 4,000 of a single file. Upon investigation, I discovered a massive 17,155-line file that served as the entire data access layer.
The code was highly redundant. Every single read or write operation repeated the same:
- HTTP request configuration.
- JSON encoding logic.
- JSON decoding logic.
There was a distinct lack of function extraction, no internal domain language, and almost no use of classes to deduplicate logic.
The Hypothesis: Refactoring for Token Efficiency
In the realm of agentic coding, the goal of refactoring shifts. It is no longer just about human readability; it is about token economics.
The Theory: By spending tokens now to refactor the code, we can reduce the token consumption required for future feature implementations.
The Experimental Design
Because AI agents do not "learn" or remember across fresh sessions, I could run a controlled experiment. I would prompt a brand-new agent to perform the exact same change after every refactoring stage. This ensured the results weren't skewed by the agent's "memory" of previous steps.
The Execution Plan:
- Develop a comprehensive refactoring strategy based on strict discipline.
- Establish a baseline cost: Use a sub-agent to execute a specific change and report token usage.
- Apply a refactoring step.
- Use a fresh sub-agent to execute the same change and record the new cost.
- Log all metrics: token counts, execution time, and total LoC.
Technical Note on Token Counting
Since Claude's live token reporting can be inconsistent, I implemented a workaround using tiktoken. The sub-agent reported character counts, which were then converted to approximate tokens:
# Approximation logic used in the experiment
tokens = character_count / 4
Experimental Results
The following table tracks the evolution of the data access layer through 15 stages of refactoring.
| Step | Data Access LoC | Largest File LoC | Total Rust LoC | Input Tokens | Output Tokens | Time (s) |
|---|---|---|---|---|---|---|
| Baseline | 17,155 | 17,155 | 50,359 | 159,564 | 1,705 | 342 |
Step 1 (FirestoreClient) | 16,706 | 16,706 | 49,910 | 155,205 | 1,723 | 530 |
Step 2 (extract_doc_id) | 16,562 | 16,562 | 49,766 | 159,227 | 2,105 | 574 |
| Step 3 (link-query helpers) | 16,567 | 16,567 | 49,771 | 154,054 | 2,105 | 524 |
Step 4 (FakeStore predicates) | 16,577 | 16,577 | 49,781 | 154,146 | 2,060 | 654 |
| Step 5 (value ctors) | 16,469 | 16,469 | 49,673 | 171,251 | 2,036 | 1,353 |
Step 6 (FieldsBuilder) | 16,469 | 16,469 | 49,673 | 171,251 | 2,036 | 1,353 |
Step 7 (queries.rs) | 16,474 | 15,670 | 49,678 | 151,850 | 1,800 | 587 |
Step 8 (traits.rs) | 16,508 | 13,845 | 49,712 | 132,558 | 1,723 | 446 |
Step 9 (traits/ split) | 16,508 | 13,845 | 49,712 | 132,558 | 1,723 | 446 |
Step 10 (codec.rs) | 16,521 | 12,846 | 49,725 | 131,871 | 1,750 | 540 |
Step 11 (fake_store.rs) | 16,535 | 11,122 | 49,739 | 133,016 | 2,460 | 600 |
Step 12 (store/ split) | 16,550 | 9,269 | 49,754 | 104,080 | 2,050 | 490 |
| Step 13 (co-locate tests) | 16,550 | 9,269 | 49,754 | 104,080 | 2,050 | 490 |
Step 14 (complete fake_store) | 16,553 | 7,225 | 49,757 | 107,205 | 2,453 | 523 |
Step 15 (store/ split) | 16,608 | 3,695 | 49,812 | 27,360 | 2,113 | 454 |
Analysis of the Findings
The most critical metrics are the size of the largest file and the volume of input tokens.
Key Observations:
- LoC Stability: The total lines of code in the data access layer remained relatively constant.
- The "Token Cliff": Input tokens stayed flat for several steps. However, once the largest file was broken down significantly, token consumption "fell off a cliff."
- The Bottom Line: Input tokens for the same task plummeted from to .
Financial Impact
Using the pricing for Sonnet 5 (\3$ per million tokens), the cost reduction per change is calculated as:
Every subsequent modification to the data access layer now saves approximately 39.7 cents per request.
Final Conclusion
This experiment proves that aggressive refactoring can yield significant financial savings in agentic workflows. However, there is a caveat: simply splitting files randomly is not the solution.
The savings were realized because the agent could successfully identify and read only the smallest necessary subset of files. The "thinking" logs from Claude Code confirmed that as the architecture improved, the agent read smaller, more relevant sections of code.
Strategic Refactoring Better Context Selection Lower Token Cost.