Imagine two development teams.
The first is preparing a new version of the application.
The developer finishes a task. Someone reviews the code. Then the tests need to be run. Someone prepares the package. Someone else logs in to the server. Next, a few manual steps need to be performed, the configuration checked, and the system monitored after deployment. If everything goes well, the new version becomes available.
The second team works differently.
The code goes to the repository. Tests, quality analysis, and security checks run automatically. The system builds the application version, deploys it to the test environment, performs further checks, and after certain conditions are met, it may deploy it to production. If something goes wrong, the deployment is stopped or the system can roll back to the previous version.
Both teams create software.
But only one of them has built a repeatable software delivery process.
And that is exactly what CI/CD is about.
"It works in production" is not yet a mature process
Many companies measure success with a very simple metric: the application works.
That is, of course, a basic requirement.
But as the system grows, more questions arise:
- How quickly can we deploy a fix?
- How often can we release new features?
- How many manual steps do we perform with each deployment?
- Can every developer run the deployment process according to the same rules?
- Do we know which version is currently running?
- Can we roll back to the previous version?
- After deployment, do we automatically check whether the system works correctly?
- Do we have monitoring?
- Do we know that the deployment caused a problem before the customer reports it?
These are questions about software delivery, not just programming itself.
CI and CD - two parts of one process
CI, or Continuous Integration, means continuous integration of changes.
In practice, this means changes are frequently pushed to a shared repository and automatically checked.
A typical pipeline may run, among other things:
-
compiling or building the application,
-
unit tests,
-
integration tests,
-
linting,
-
static code analysis,
-
dependency scanning,
-
security checks,
-
building deployment artifacts.
Thanks to this, a problem can be detected before the code reaches production.
CD, or Continuous Delivery or Continuous Deployment, concerns the next stage - delivering changes.
Depending on the chosen model, the system can prepare a ready-to-deploy version or automatically deploy it after passing certain checks.
This is an important distinction.
Continuous Delivery does not have to mean automatically deploying every change to production.
It can simply mean that every version is prepared for deployment in a repeatable way.
Why do manual deployments become a problem?
A manual deployment does not have to be bad.
In a small project, it may be completely sufficient.
The problem starts when the process grows along with the application.
At first, there is one person who knows how to deploy the system. Then a second server is added. Later, a test environment. Then a database, cache, queues, storage, several services, and external APIs. On top of that, there are different configurations for development, testing, and production.
After a few years, the process may look roughly like this:
"First run X, then change parameter Y, then restart service Z, but before that make a database backup. And if an error appears, call the person who deployed it last time."
That is no longer a process. It is knowledge hidden in a person's head. And that is exactly when risk increases.
Automation is not just for the convenience of developers
CI/CD is often presented as a tool that improves developer comfort. That is true, but it is only part of the picture.
Delivery automation primarily increases process repeatability.
If a human performs the deployment, there is a chance that each time they will do something a little differently.
If a pipeline does it, you can define an exact sequence of steps.
The same version.
The same tests.
The same checks.
The same rules.
This is especially important in projects developed by several people or several teams.
Tests before deployment are more important than deployment speed
Automation without tests may only make errors appear faster.
That is why a well-designed pipeline should not be just a mechanism: "code → production".
It should be a quality control system.
Depending on the project, it may include:
- Unit tests - checking individual pieces of logic.
- Integration tests - checking how components work together.
- End-to-end tests - simulating real user scenarios.
- Security tests - checking, among other things, dependencies and known vulnerabilities.
- Performance tests - needed where handling a specific load is important.
Not every application needs all of these layers to the same extent.
And that is important.
CI/CD is not about stuffing as many tools as possible into the pipeline.
It is about choosing checks appropriate to the risk of a specific system.
What happens when a test fails?
This is one of the most important questions in the entire process.
A mature pipeline should have clearly defined rules.
If a critical test fails, the version should not be treated as ready for deployment.
If a security scan detects a certain level of risk, the pipeline can stop the process.
If the build fails, there is nothing to deploy.
It sounds trivial. But it is precisely these automatic "gates" that make quality depend not only on a person's memory and accuracy.
And what if the deployment still fails?
Even the best process does not eliminate all errors. That is why the second element of mature delivery is the ability to roll back a change in a controlled way.
Rollback may mean returning to the previous artifact, container image, or application version. But an important problem appears here. Rolling back code does not always mean rolling back data.
If the new version changed the database structure, the situation becomes more complicated.
Therefore, database migrations should be designed so that the entire process is as safe and reversible as possible, or at least compatible with the previous version of the application.
This is one example showing that professional CI/CD is an architectural problem, not just a tool configuration issue.
Blue-green, canary, and other deployment strategies
In more demanding systems, there is no need to switch all users to the new version right away. Different deployment strategies can be used.
Blue-green deployment
Two versions of the environment are running.
One handles traffic, the other is being prepared to take over the traffic.
After successful verification, the switch occurs.
Its advantage is the ability to quickly return to the previous environment.
Its disadvantage may be higher infrastructure usage.
Canary deployment
The new version is first rolled out to a small portion of users or traffic.
If monitoring does not show any problems, the deployment scope can be gradually increased.
This limits the potential impact of an error.
However, it requires appropriate infrastructure, monitoring, and traffic management.
Feature flags
A feature can be deployed to the system but remain turned off for users.
This makes code deployment and feature release two separate processes.
This provides greater control, especially for large changes.
However, this does not mean that feature flags are a solution for every project. Too many of them can also increase system complexity.
Post-deployment monitoring
All tests can be run. You can have a great pipeline. You can deploy a new version without any errors. And a few minutes later the application may start behaving differently under real load.
That is why the process should not end with deployment. Observability is needed, meaning the ability to understand what is happening inside the running system.
Depending on the architecture, it includes among other things:
-
logs,
-
metrics,
-
tracing,
-
infrastructure monitoring,
-
application monitoring,
-
alerts,
-
error information,
-
business metrics.
It is not about collecting everything. It is about being able to answer important questions based on data.
Is the application working?
Is it running slower than before?
Has the number of errors increased?
Which service is causing the problem?
Does the problem affect all users or only some of them?
100 deployments a day are not always the goal
The title of this article talks about 100 deployments a day, but the point is not to set that number as a target.
In an internal system updated once a month, there is no point in artificially aiming for hundreds of deployments. In a highly actively developed system, however, such a frequency may be technically possible.
The key is the ability to deliver changes safely, not the number of deployments itself. That is a fundamental difference.
The maturity of the process is measured not by how often we deploy, but by how predictably and safely we can do it.
When can CI/CD be overkill?
Not every application needs a complex deployment infrastructure.
If we have a small application, a small team, and a few deployments a year, an elaborate pipeline may cost more than the problems it solves.
The same applies to very specific systems where deployment requires manual control for security, regulatory, or infrastructure-related reasons.
That is why delivery architecture should result from the system's needs. Not from trends.
When does deployment automation bring particularly much value?
It is worth considering especially when:
-
the system is developed regularly,
-
several people work on the code,
-
there is more than one environment,
-
deployments are frequent,
-
manual deployments introduce errors,
-
the system is critical to the business,
-
we need a fast rollback,
-
the application has many components,
-
audits or a change trail are required,
-
the time to deliver a feature matters to the business.
In such cases, a well-designed pipeline can be one of the most important elements of the software development process.
CI/CD will not fix a bad architecture
This is also worth emphasizing.
You can build a great pipeline for a bad application.
Automatically test bad code.
Automatically deploy a bad architecture.
Automatically scale a poorly designed system.
Automation therefore does not replace architecture, testing, or the team's competence.
It strengthens the existing process.
If the process is good, it helps scale it.
If the process is bad, it may simply make bad things happen faster.
What does a mature process look like?
There is no single universal pipeline.
But a mature process should have several basic properties.
Repeatability - deployment is performed according to defined steps.
Automation - machines perform as much of the repetitive work as possible.
Testability - changes are verified automatically.
Security - the process includes appropriate security checks.
Observability - after deployment, you know what is happening with the system.
Reversibility - there is a planned way to respond to an unsuccessful change.
Change tracking - it is known which version was deployed and what it was built from.
Access control - not everyone can deploy anything to production at will.
This is what makes up a professional software delivery process.
The most important change starts with a different question
Companies often ask: "How quickly can we build this feature?"
It is worth adding a second question: "How quickly and safely will we be able to deliver the next 50 features?"
A single deployment can be done manually. You can even manually deploy an application for several years. But as the product, the team, the number of users, and the number of changes grow, the cost of such an approach also grows.
That is why CI/CD, automated tests, monitoring, and controlled deployments are not just solutions for large corporations.
They are elements of the process infrastructure that make it possible to develop software without adding unnecessary risk to each subsequent change.
And in the end, that is exactly what it is about.
Not about 100 deployments a day.
Not about trendy tools.
Not about the most complicated pipeline.
Only about being able to say:
"We have a change. We checked it. We know what we’re deploying. We know how to observe it. And we know what we’ll do if something goes wrong."
