8

PricingBlog
All posts
engineering

Zero-Downtime Magento Deployment: A Complete Guide

2026-03-15 · Byte8 Team

Share

The most expensive minute in e-commerce is the one where your store shows a 503 maintenance page during a deployment.

For most Magento stores, this means deploying at 2 AM to minimise impact. Your developers are tired, mistakes are more likely, and rollbacks are manual and stressful.

Why Magento deployments cause downtime

Magento's setup:upgrade command needs exclusive database access. During this window, the store can't serve requests. Traditional deployments handle this by enabling maintenance mode — showing a 503 page to all visitors.

The duration depends on your migrations. A simple module update might take 10 seconds. A complex schema change could take minutes.

The atomic symlink approach

Orbit uses a Capistrano-style release structure:

/var/www/
├── current -> releases/20260403_143022  (symlink)
├── releases/
│   ├── 20260403_143022/  (new release)
│   └── 20260403_120000/  (previous)
└── shared/
    ├── media/
    └── var/

The new release is fully prepared in its own directory. Only the final symlink swap is instantaneous — switching current from the old release to the new one.

Cutover hold: the brief 503 you want

The symlink swap is instant, but PHP-FPM's opcache lags a few hundred milliseconds behind it. Requests landing in that window can hit a stale-pointer state — opcache still has the old vendor/, the symlink already points at the new release — and surface as the occasional Class not found 500.

Orbit closes the gap with a flag file. Before the swap, the agent touches shared/orbit/cutover-pending; after cache:flush succeeds, it removes it. A one-line nginx snippet returns 503 Retry-After: 3 while the flag exists. The window is typically 1–3 seconds — CDN retries cover it transparently, browsers honour Retry-After, and Orbit is never standing in for your nginx, never queuing TCP, never holding open connections.

The contract is fail-open: if the agent crashes mid-deploy, a watchdog clears the flag and traffic resumes to PHP-FPM. No nginx -s reload, no daemon to keep alive on port 80.

Honest maintenance windows for migrations

DB migrations are inherently not zero-downtime — you can't write to a table while ALTER TABLE is running. Orbit minimises the exposure rather than hiding it:

  • Composer install, di:compile, and static-content:deploy — the multi-minute steps — run in the new release directory while the site keeps serving from the old one.
  • setup:db:status runs first. If nothing's pending, maintenance mode never flips and the deploy is genuinely zero-downtime.
  • When migrations are needed, the maintenance window covers only setup:upgrade — typically 10–60 seconds.
Every deploy gets a maintenance window class — none, migrations, drift, always, or failed_rollback — rendered as a chip in the dashboard. "Zero-downtime ✓" is a per-deploy claim you can audit, not a product page promise.

Forward-compatible migrations

To keep schema-changing deploys in the "zero-downtime ✓" column, write migrations as two-deploy expand/contract pairs:

1. Expand: add the new column nullable; old and new code paths both read and write the old + new fields. 2. Contract: drop the old path; only the new column is used.

Each individual setup:upgrade finishes in seconds — you never take a multi-minute migration window. Same discipline Adobe Commerce Cloud uses internally; Orbit just makes it cheap to adopt without the $100k contract.

Built in Rust, for fewer wasted minutes

The agent is a single static Rust binary — no runtime to boot, no PHP bootstrap to call out to git or composer. The bigger time-saver, though, is Magento-aware smart-skip detection: CSS-only deploys skip setup:di:compile; PHP-only deploys skip setup:static-content:deploy. Typical deploys drop from ~3 minutes to ~75 seconds — and the shorter the deploy, the smaller every window above gets.

Auto-rollback

Health checks run automatically after every deploy. If the new release fails — HTTP errors, memory spikes, or custom checks — Orbit swaps the symlink back to the previous release, clears any leftover maintenance flag, and flushes cache on the restored release. No manual intervention.

Try Orbit — zero-downtime Magento deploys from $49/mo →


Enjoyed this? Share it with your team.

Share