← Back to blog

Magento 2 Static Content Deploy: Strategies and Options

Rodrigo Biazzi

Static content deploy is often the slowest step of a Magento 2 release. On a store with a few themes and several locales it can take longer than everything else combined, and it produces tens of thousands of files. Magento offers three deploy strategies and a set of options to control what gets built. Picking the right ones shortens builds and avoids a store that loads without styles for one language. This guide covers setup:static-content:deploy on Magento Open Source and Adobe Commerce 2.4.8.

What the command produces

setup:static-content:deploy collects CSS, JavaScript, fonts, images and templates from every module and theme, compiles LESS into CSS for Luma based themes, applies minification if enabled, and writes the result into pub/static. The folder structure is:

pub/static/<area>/<Vendor>/<theme>/<locale>/...
pub/static/frontend/Magento/luma/en_US/css/styles-m.css
pub/static/adminhtml/Magento/backend/en_US/js/...

Every combination of area, theme and locale is a separate tree. With two storefront themes and four locales, plus the admin, you deploy at least nine full sets of files. Most of them are identical across locales, which is what the strategies try to deal with.

The command also writes pub/static/deployed_version.txt. Magento uses that value as the version segment in static URLs, such as /static/version1731240000/..., so browsers and CDNs fetch the new files after a deploy. That is static file signing, controlled by dev/static/sign, and it should stay on in production.

The three strategies

You choose a strategy with -s or --strategy.

standard

Deploys every file for every theme and locale combination separately. It is the most straightforward and the slowest. Every locale gets a full copy of everything.

quick

The default. It deploys one locale per theme in full, then for the other locales copies the files that do not depend on the locale and only processes the ones that do. Translated JavaScript dictionaries and some templates differ per locale, most CSS and images do not. This cuts deploy time considerably on stores with several locales, and the output looks the same as standard to the browser.

compact

Instead of copying shared files into every locale folder, compact stores them once in shared base folders and writes map files so each theme and locale knows where to find them. It produces far fewer files and uses less disk. The cost is that URLs for shared files point to the base locations, and some setups, mostly third party extensions that build static URLs by hand, assume the standard folder structure. Test the storefront and admin carefully if you choose it.

bin/magento setup:static-content:deploy en_US pt_BR -s quick -j 4
bin/magento setup:static-content:deploy en_US pt_BR -s compact -j 4

For most stores, quick is the right default. Compact is worth trying when disk space, file count or artifact size is a real problem, for example on many locales.

Parallel jobs

The -j or --jobs option runs deploy work for different themes and locales in parallel processes. More jobs help up to the number of CPU cores. Beyond that, the processes fight over CPU and memory. Each job needs its own memory, so watch the PHP CLI memory limit and the server RAM when you raise it. On a small production server where the deploy runs next to live traffic, keep the job count low so the store does not slow down.

Deploy only what you use

The fastest file is the one you do not build. The command has options to limit the scope.

bin/magento setup:static-content:deploy en_US pt_BR \
  --area frontend \
  --theme Vendor/storefront \
  -j 4

bin/magento setup:static-content:deploy en_US \
  --area adminhtml \
  --theme Magento/backend \
  -j 2

Other useful options:

  • --exclude-theme skips themes, for example Magento/luma when no store view uses it. Do not exclude a theme that is a parent of the theme you use.
  • --exclude-language skips locales.
  • --exclude-area skips an area.
  • Flags like --no-javascript, --no-css, --no-images, --no-fonts and --no-html skip file types. Useful for debugging a slow deploy, rarely for a real release.

Listing locales explicitly matters. Without a locale argument the command deploys only en_US, which is a common reason for a store view in another language loading without styles. The admin locale matters too. If an admin user chose a different interface locale, that locale needs admin static files.

Running without production mode

In developer and default mode, the command refuses to run unless you add -f or --force. That is intended. In developer mode static files are normally generated on demand, and a full deploy is rarely what you want locally. On a build server you usually run in production mode, or pass -f deliberately.

Building without a database

By default the command reads themes and store locales from the database. A CI runner usually has no database. The fix is to dump that configuration into app/etc/config.php:

bin/magento app:config:dump scopes themes i18n

With scopes, themes and locale settings in the versioned file, static content deploy can run on a machine with no database connection. This is the basis of the build stage in the zero downtime deploy guide and the production mode deploy guide.

Minification, merging and bundling

These settings change what the deploy produces. They live under the developer configuration, which the admin hides in production mode, so you set them with config:set and ideally store them in config.php:

bin/magento config:set dev/js/minify_files 1
bin/magento config:set dev/css/minify_files 1
bin/magento config:set dev/template/minify_html 1
bin/magento config:set dev/js/merge_files 0
bin/magento config:set dev/js/enable_js_bundling 0

Minification is generally safe and reduces file size. Merging and the built in bundling are another story. Magento's native bundling puts large parts of the RequireJS module set into a few big files per page type. On a Luma theme that often makes the first page load heavier, not lighter. With HTTP/2, many small files are not the problem they used to be. I keep merge and bundling off by default and only turn on an advanced bundling approach after measuring. The JS bundling guide goes into the options.

Whichever you choose, change these settings before the static content deploy, not after. The deploy writes files according to the current settings.

Hyvä and static content

Hyvä themes do not use RequireJS or LESS in the storefront. Their CSS is built with Tailwind during your theme build step, before static content deploy, and the deploy then copies the compiled output. The command still runs and still produces the admin and any Luma based areas you keep, such as a Luma checkout fallback. The total amount of work is lower, which is one of the practical benefits described in the Hyvä vs Luma comparison.

Troubleshooting

  • Styles missing for one store view: its locale was not in the deploy command, or the theme assigned to it was excluded.
  • LESS compilation errors: the deploy stops with a message pointing at a LESS file. Fix the source. Errors here often come from a third party module's LESS that relies on variables only defined in Luma.
  • Old CSS after deploy: static signing is off, or a CDN cached the old files under the same URL. Check dev/static/sign and that deployed_version.txt changed.
  • Deploy runs out of memory: lower -j or raise the CLI memory limit, for example with php -d memory_limit=4G bin/magento ....
  • Files appear in pub/static during runtime: the store is not in production mode, so missing files are generated on demand.

Before a fresh full deploy, clear the old output to avoid leftovers from removed themes. Delete the contents of pub/static except the .htaccess file, and clear var/view_preprocessed.

FAQ

Which static content deploy strategy should I use?

Quick is the default and the right choice for most stores. Try compact when file count or disk use is a problem, and test the store carefully after switching.

Why does static content deploy only build en_US?

Without locale arguments the command deploys en_US only. List every locale used by your store views and admin users in the command.

Can I run setup:static-content:deploy in developer mode?

Only with the -f or --force flag. In developer mode files are normally generated on demand, so a full deploy is usually unnecessary.

Should I enable Magento JS bundling?

Not by default. Native bundling often makes the first load heavier on Luma. Measure first and consider an advanced bundling setup instead.

I am available for freelance Magento and Adobe Commerce work, including build and deploy pipelines. If you need help with this, get in touch.

Related articles