Anyone who reflexively runs cache:flush after every deployment clears more than necessary and drives up load through needless cache regeneration. Precise cache invalidation after a release is a technical decision, not a habit.
A build job on production is not a deployment, it is an uncontrolled experiment on the live system. Artifacts from isolated CI jobs bring reproducibility, speed and safety at the same time.
When the pipeline is not fast enough, teams fall back on manual deployments. That is acceptable, but only if it produces complete documentation, a rollback path is prepared in advance, and the hotfix is cleanly folded back into the normal process afterward.
A release artifact that has been altered without anyone noticing is more dangerous than a build that visibly fails. SHA256 checksums, GPG signatures and automated verification steps in the GitLab pipeline close this silent attack surface for Magento deployments.
Zero downtime is promised often and defined rarely. This article explains honestly where a symlink switch truly works without any outage, and where database migrations unavoidably require a short maintenance window.
setup:upgrade is the only command in the Magento deployment process that directly changes the production database. It does not run in the build job, it is not a test, it runs on the live system. A team that does not secure this step is building a deployment process that regularly needs luck when database migrations are involved.
Cron jobs and queue consumers still running during a deployment are an underestimated source of errors. A consumer that runs against the old release code while the symlink switches to the new release can cause data consistency problems. This article explains how to reliably control cron and consumers in the GitLab deployment process.
The symlink switch is not the end of a zero-downtime deployment: it is the start of a critical phase in which Redis, RabbitMQ, and OpenSearch must be compatible with the new code base. These three services are too often treated as peripheral details, even though they are frequently the root cause of post-deploy failures.
Choosing the right runner type is not a matter of convenience, it is a security decision. Shared runners are practical, but their security model is often not sufficient for Magento production deployments involving SSH keys and database credentials. This article shows where the limits lie and what self-hosted runners can deliver.
No other part of a zero downtime deployment fails as often as database migrations. Renaming a column, dropping a table, adding a NOT NULL constraint: these are operations that are simply not compatible with code that is still running. This article explains the expand/contract pattern, when it works, and when a maintenance window is the more honest answer.