Disclaimer: ChatGPT generated document.
If you've spent any time around software engineers, you've probably heard phrases like:
- "Don't test in production."
- "The deployment to production failed."
- "Production is down."
- "We need to fix this in prod."
To newcomers, the terminology can seem odd. What exactly is being "produced"? Software is already written, compiled, and deployed. Why isn't the live environment simply called the "operational" environment?
The answer lies not in software theory itself, but in the history of computing and the evolution of software engineering as an industrial discipline.
Contrary to what many assume, "production" is not a formal concept in computer science or software engineering theory.
Classical software engineering literature focuses on concepts such as:
- Requirements engineering
- System design
- Implementation
- Verification and validation
- Deployment
- Operation
- Maintenance
International standards such as ISO/IEC software lifecycle models distinguish between development, operation, and maintenance. They do not define "production" as a theoretical phase of software.
Instead, "production" emerged from the practical world of computer operations.
To understand the term, we must look back to the era of mainframe computers during the 1950s through the 1970s.
At that time, organizations did not think of software as the product.
Instead, software was a tool that enabled businesses to produce their actual outputs.
Banks produced account statements.
Insurance companies produced claims.
Governments produced tax records.
Manufacturers produced inventory reports.
Airlines produced reservations.
The computer system was viewed as a production machine, much like a printing press or an assembly line.
When software was actively generating the organization's real business output, it was said to be in production.
The distinction was therefore between:
- development systems, where programs were written;
- testing systems, where they were verified; and
- production systems, where they performed real business work.
In this sense, production referred to the environment where the organization conducted its actual operations.
This raises an interesting question.
If the software is simply running, why isn't the live environment called the "operational environment"?
In fact, many formal engineering documents do exactly that.
Standards and academic literature frequently refer to:
- operational software,
- operational systems,
- operation,
- operational environments.
These terms are technically precise.
However, practitioners—especially system administrators, release engineers, and operations teams—adopted the more familiar industrial term "production."
As software engineering matured, the operational vocabulary became standardized within industry:
- Development (Dev)
- Test
- Quality Assurance (QA)
- Staging
- Production (Prod)
Today these names are nearly universal.
The terminology makes more sense if we compare software development to manufacturing.
Imagine a factory producing automobiles.
The design office creates blueprints.
Prototype workshops build experimental models.
Testing facilities verify safety.
The factory floor manufactures vehicles for customers.
Software engineering evolved with a remarkably similar separation.
Development environments are where engineers write code.
Testing environments verify correctness.
Staging environments closely resemble the live system.
Production is where real customers interact with the application.
Although no physical object is being manufactured, the organization is still "producing" its service for customers.
One reason the terminology feels strange today is that software itself has become the product.
Companies like Microsoft, Adobe, Google, Spotify, or OpenAI are fundamentally software companies.
Yet the historical terminology survived.
Originally, the relationship looked like this:
Software → produces business operations
Today, it often looks like this:
Software → is the product
Despite this shift, engineers still speak about "production" because the software is producing the live service experienced by users.
Whether the product is online banking, cloud storage, video streaming, or artificial intelligence, the production environment remains the system delivering the organization's real value.
Modern engineers rarely define production by location.
Instead, they define it by consequence.
A production environment is one where:
- real users interact with the system,
- real business data is processed,
- outages affect customers,
- security matters,
- financial consequences exist.
This definition explains why companies invest heavily in production reliability.
Practices such as:
- automated testing,
- continuous integration,
- continuous deployment,
- monitoring,
- observability,
- incident response,
- rollback strategies,
all exist primarily because failures in production carry real costs.
The famous saying is not merely a joke.
Testing directly in production means experimenting on the system that customers currently depend upon.
Unlike development or staging environments, mistakes in production immediately affect users, revenue, reputation, and trust.
Modern engineering therefore attempts to make production changes predictable through automation while minimizing risk through gradual deployments, feature flags, canary releases, and rapid rollback mechanisms.
The word "production" is one of the oldest surviving pieces of computing terminology.
It did not originate in computer science theory but in the operational culture of early commercial computing, where computers were regarded as production machinery generating payrolls, invoices, reservations, and other essential business outputs.
Although software has evolved dramatically since then—and software itself is often now the product—the historical language remains.
When engineers refer to "production," they are not talking about where software is created.
They are talking about where software creates value.
Production is the environment in which software stops being merely code and becomes a living service that people, businesses, and societies rely upon every day.
The history of the term production reveals an interesting characteristic of software engineering: not all of its most important concepts originate in computer science theory.
Unlike mathematics or physics, where terminology is usually introduced through formal theories and later adopted by practitioners, software engineering has evolved through a continuous dialogue between academia and industry. Researchers develop models, methods, and standards, while practitioners build increasingly complex systems under real-world constraints. As new operational challenges emerge, engineers often invent their own vocabulary long before those ideas are formalized—if they are formalized at all.
The result is that everyday software engineering contains two overlapping languages. One is the language of theory, found in textbooks, standards, and academic literature, with concepts such as verification, maintenance, modularity, and operational environments. The other is the language of practice, rich in metaphors and operational shorthand: production, technical debt, code smell, hotfix, feature flag, canary release, snowflake server, and countless others.
These industry terms are not merely jargon. Each emerged because practitioners repeatedly encountered a phenomenon that lacked a concise name. In many cases, the metaphor proved so useful that it became the de facto standard vocabulary of the profession, even though no equivalent concept existed in the formal theory at the time.
The following examples illustrate some of the most influential concepts that originated in software engineering practice rather than in software engineering theory.
| Industry term | Formal/theoretical counterpart | Origin |
|---|---|---|
| Production (Prod) | Operational environment | Mainframe operations |
| Staging | Pre-operational test environment | Release engineering |
| Hotfix | Emergency corrective maintenance | Software maintenance practice |
| Technical debt | Design trade-offs, maintenance cost | Metaphor introduced by Ward Cunningham |
| Code smell | Symptom of poor design | Martin Fowler / XP community |
| Refactoring | Semantics-preserving program transformation | Industrial practice later formalized |
| DevOps | Organizational/process integration | Industry movement |
| CI/CD | Automated integration and deployment | Build engineering |
| Feature flag | Runtime configuration mechanism | Web-scale deployment |
| Canary release | Incremental deployment strategy | Operations metaphor |
| Blue-green deployment | Parallel deployment architecture | Operations |
| Dogfooding | Internal operational testing | Microsoft slang |
| Observability | Runtime system diagnosability | SRE practice |
| Toil | Repetitive operational work | Google SRE |
| Snowflake server | Non-reproducible configuration | DevOps |
| Yak shaving | Tangential prerequisite work | Hacker culture |
| Glue code | Integration code | Programming folklore |
Some of these have since become accepted in textbooks, but they originated outside formal theory.
Perhaps the most famous example.
Computer science has theories of:
- software complexity,
- maintainability,
- coupling,
- modularity.
But there is no formal theoretical construct called technical debt.
Ward Cunningham coined it in 1992 as a metaphor:
Choosing a quick implementation is like borrowing money. The debt must eventually be repaid with interest.
Today the phrase appears in almost every software organization despite having begun as an engineering analogy rather than a theoretical concept.
No programming language has a syntax rule for a "code smell."
A code smell is simply an observation:
"This code isn't necessarily wrong, but experienced engineers recognize it as a warning sign."
Examples include:
- enormous functions,
- duplicated code,
- long parameter lists,
- excessive nesting.
It is an engineering heuristic rather than a mathematical property.
Interestingly, this term straddles both worlds.
Originally, refactoring was simply a developer practice:
reorganize code without changing behavior.
Later researchers formalized it as behavior-preserving program transformation.
The practical term came first; the theory followed.
There is no branch of theoretical computer science called DevOps.
DevOps concerns:
- organizational structure,
- deployment pipelines,
- automation,
- monitoring,
- collaboration.
It emerged because software engineering became as much about operating systems continuously as building them.
Academically this is just:
runtime conditional configuration.
Practically everyone says:
"Turn the feature flag on."
Large internet companies rely on feature flags to release software gradually without redeploying.
Borrowed from miners carrying canaries underground.
Instead of deploying software to everyone:
deploy → 1% of users
observe
deploy → 10%
observe
deploy → 100%
Nothing in formal software engineering defines this concept.
It is entirely an operational strategy.
A beautiful example of engineering language.
Maintain two identical production environments.
Blue ← users
Green ← new version
Switch traffic instantly.
Again, this is deployment engineering rather than software theory.
One of my favorites.
A snowflake server is:
a server manually modified until no other machine is identical.
Academically we'd describe this as:
loss of configuration reproducibility.
Practitioners say:
"Don't touch it. It's a snowflake."
The metaphor communicates the idea far better.
Microsoft popularized this.
"Eat your own dog food."
Meaning:
Developers use their own software before customers do.
Academically this falls under internal validation or operational evaluation.
No textbook would call it dogfooding.
Google's SRE books gave this term prominence.
Toil is:
- repetitive,
- manual,
- automatable,
- operational work.
Not every maintenance activity is toil.
Only the repetitive kind that engineers should automate.
This concept is absent from classical software engineering despite being central to modern operations.
Classical control theory already had "observability."
Software borrowed the word but changed its meaning.
Today engineers mean:
Can we infer what the software is doing from logs, metrics, traces, and events?
This is much richer than the mathematical definition.
Theory speaks of:
- interfaces,
- adapters,
- wrappers.
Engineers often say:
"It's mostly glue code."
Meaning code whose purpose is connecting systems rather than implementing business logic.
There is a fundamental reason these terms arise.
Computer science studies:
- algorithms,
- languages,
- computability,
- complexity,
- correctness.
Software engineering standards study:
- lifecycle,
- requirements,
- architecture,
- maintenance.
Industry deals with additional realities:
- thousands of deployments,
- millions of users,
- organizational structures,
- outages,
- cloud infrastructure,
- developer productivity,
- operational risk.
Whenever practitioners repeatedly encounter a phenomenon not captured by formal terminology, they invent a name for it. If the name proves useful, it spreads.
Some of these terms—such as refactoring, technical debt, and observability—later acquire more formal definitions. Others remain vivid metaphors that practitioners immediately understand even though they have no precise theoretical counterpart.
This pattern is not unique to software engineering. Medicine, aviation, law, and finance all have rich bodies of professional jargon that evolved from practice before (or instead of) formal theoretical treatment. Software engineering is unusual mainly because the gap between academic theory and industrial practice has historically been especially wide, leading to a remarkably creative and metaphor-rich vocabulary.
