8

PricingBlog
All posts
engineering

How Orbit Cuts Magento Deploy Time from 3 Minutes to 75 Seconds

2026-06-11 · Byte8 Team

Share

A CSS tweak and a full re-platform cost a traditional Magento deploy roughly the same amount of time. That's the part nobody mentions: the slow phase of a Magento deployment isn't your change — it's the build steps that re-run unconditionally every single time, whether or not their inputs moved.

Three commands dominate the clock:

  • composer install — resolves and installs dependencies.
  • setup:di:compile — compiles the dependency-injection graph into generated/.
  • setup:static-content:deploy — renders every theme × locale into pub/static/.
On a real store these routinely add up to around three minutes. static-content:deploy is usually the worst offender — it regenerates assets for every locale from scratch, even when you only touched a PHP service class that has nothing to do with the storefront's CSS.

The insight: most deploys don't change most inputs

A CSS-only change doesn't alter the DI graph, so di:compile is wasted work. A PHP-only change in app/code doesn't alter any frontend asset, so static-content:deploy is wasted work. A redeploy of the same git ref changes nothing — yet a naive pipeline still burns three minutes proving it.

Orbit's smart-skip detection turns that observation into a deploy strategy: fingerprint each build phase over its specific input set, and skip the phase when the fingerprint matches the last successful deploy — hardlink-copying the previous release's artifact instead of regenerating it.

phase            fingerprint inputs                         on match
--------------   ----------------------------------------   ---------------------------
composer         composer.json, composer.lock               refresh autoloader only
di:compile       app/code PHP, di.xml, etc/*.xml, modules   hardlink-copy generated/
static-content   themes, CSS/LESS, JS, layout XML, .phtml   hardlink-copy pub/static/

The hardlink copy is the trick that makes a skip safe: the new release still gets a complete, self-contained generated/ and pub/static/ directory — it's just assembled from the previous release's already-correct output in milliseconds instead of rebuilt in minutes.

Per phase, in practice

Composer defaults to lock-changed: Orbit runs a full composer install only when composer.lock actually changed, and otherwise just re-dumps the autoloader — about 25 seconds saved on the common case. You can force always (install every deploy) or skip (never invoke composer, for teams who commit vendor/ to the repo for fully predictable deploys).

di:compile is skipped when nothing in the DI input set moved. A theme-only deploy leaves the compiled graph identical, so Orbit hardlink-copies the previous generated/ and moves on.

static-content:deploy is skipped when no frontend asset changed — the row we care about most, because it's the slowest phase. A PHP-only release reuses the previous release's pub/static/ wholesale rather than re-rendering every locale.

The hard part is correctness, not speed

Skipping work is easy. Skipping work without ever shipping a broken release is the actual engineering problem, and it's where naive "did composer.lock change?" checks fall down.

Two cases bite teams constantly:

  • Committed vendor patches. Plenty of stores carry a hotfix directly in vendor/ — say a patched .less file in vendor/magento/theme-frontend-luma. composer.lock doesn't move, so a lock-based check would skip static content and ship the old asset. Orbit fingerprints tracked vendor content via git's own object hashes, so a committed vendor patch is detected and triggers the static rebuild automatically.
  • New module or theme registration. setup:db:status only reports pending schema migrations — it's blind to a newly-added module.xml or theme.xml that needs rows registered before its static content will compile. Orbit fingerprints the registration-critical files (module.xml, theme.xml, app/etc/config.php, composer.lock, plus tracked vendor) on every deploy and runs setup:upgrade automatically when they drift — so a new theme registers and compiles cleanly with no manual step.
The whole detector is deliberately biased toward running: a false skip ships a possibly-broken release, while a false run wastes about 50 seconds. When in doubt, Orbit rebuilds. And every skip phase has a per-environment toggle in the dashboard's Build tab — disable composer skip, di:compile skip, or static-content skip independently if you ever want to take detection out of the loop.

What it adds up to

A typical CSS or PHP change lands in roughly 75 seconds instead of three minutes. A no-op redeploy of the same ref finishes in about 30 seconds — almost all of which is health-checking, not building.

For fleets, Orbit goes one step further with artifact mode (source_strategy = artifact): your CI builds the release once — vendor/, generated/, and pub/static/ all baked in — publishes it with a sha256, and every host downloads, verifies, and extracts it. All three build phases are skipped on every host because the work was already done once, upstream.

The shorter the build, the smaller every other window in your deploy gets too — including the cutover and any migration maintenance window. Fast deploys aren't just convenient; they're what makes deploying at 2pm on a Tuesday a non-event.

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


Enjoyed this? Share it with your team.

Share