Principle · Technology and AI

Make it Work, Make it Right, Make it Fast.

Source: Kent Beck, Extreme Programming Explained (1999), Addison-Wesley. The phrase is widely attributed to Beck and to Donald Knuth's related teaching in The Art of Computer Programming on premature optimization.

The Principle

Engineering work has three phases, in this order: make it work, make it right, make it fast. The first phase produces a version that returns the correct output, even if the code is ugly, the structure is wrong, and the performance is bad. The second phase keeps the behavior the same and cleans up the structure: better names, better separation of concerns, fewer special cases. The third phase optimizes for speed or cost, only after the first two are settled.

The temptation is to compress the three phases or to reorder them. Compressing produces buggy, unclean, slow code that has to be rebuilt anyway. Reordering, especially trying to make it fast before making it work, is worse. Knuth's famous formulation, "premature optimization is the root of all evil," names the trap. You cannot optimize what does not yet behave correctly. You will optimize the wrong path, encode the wrong assumptions, and bury the actual bug under a layer of clever code.

The reason the order is fixed is that each phase reveals what the next one needs to know. Making it work tells you what the actual problem is. Making it right tells you which parts of the design are stable. Making it fast tells you which parts to invest in. Skipping or reordering hides this information and produces work that has to be redone later, slower than if you had just done it in the right order.

Why It Matters Here

Technology and AI is the department where the temptation to skip phases is strongest. The pressure to ship fast and the desire to look impressive both push toward "let me build the elegant, optimized version first." That is how systems end up taking three times as long to ship and breaking in production. The CAIO who holds the discipline of work, then right, then fast, ships systems that hold up. The CAIO who skips it ends up rewriting from scratch, often more than once.

Signals (When to Apply)

How to Apply

Examples

Applied well A team needs to ship a new content-summarization automation. Day one, the engineer writes a script that loops through three test files and prints summaries. The script has hardcoded paths, no error handling, no concurrency, and is ugly. It works. Day two, the engineer extracts the summarization step into a function, adds basic error handling for the file-not-found case, and runs it against twenty real files. It is now correct on real inputs. Day three, the engineer profiles a run on a hundred files and discovers that the LLM call is the bottleneck. They add concurrency to that step. Total time to a production-quality system: three days, with each phase building cleanly on the last.
Misapplied The same team starts day one by designing the architecture. By day three, they have a beautiful diagram with five services, message queues, retry logic, and observability hooks. They have not yet run a single summarization. By day seven, they have built three of the five services, and the first integration test reveals that the summarization step itself does not produce the output they need. They start over. Total time to a production-quality system: three weeks, and the team is exhausted.

When to Break It

Further Reading