A storefront that launched clean gets harder to work on every year. Small changes take longer than they should, a fix in one place breaks something unrelated, and nobody wants to be the person who runs the upgrade. The usual explanation is that the theme "got messy," which isn't an explanation at all.
Here's what's actually happening. Nothing in your theme decays. Files on disk are exactly as you left them — that's the problem. What decays is the distance between each customization and the file it replaced, because the platform underneath kept moving while your copy stood still.
The takeaway up front: your theme holds four different kinds of customization, they age at wildly different rates, and only one of them fails silently. That one is where your maintenance effort belongs. Most of the routine sold as store maintenance touches none of them.
What actually degrades
A child theme works by taking ownership of specific files. You copy a template, adjust it, and from then on Magento serves yours instead of the module's. That's the correct pattern — the child theme approach exists precisely so your work survives updates — but it has a consequence people underestimate at the time.
Taking ownership of a file means you stopped receiving updates to it.
Every module update afterwards ships improvements to the original: a new block for a feature, an added form field, corrected output escaping, a fixed accessibility attribute, a change in how a price or a stock status renders. Your copy gets none of it. There is no conflict, no warning, and no error — Magento does exactly what you told it to do. The gap just widens, quietly, one release at a time.
So the real question for maintenance is not "is anything broken?" but "which of my overrides has the parent file grown past?"
The four kinds of override, ranked by how badly they age
1. Template (.phtml) copies — the silent one
This is where the damage lives, and it deserves most of your attention.
A copied template is a snapshot of one module's markup on the day you copied it. When that module later adds a hidden input the controller now expects, or changes how a value is escaped, your snapshot carries on rendering the old version. The page still loads. Nothing logs an error. The symptom appears somewhere else entirely — a checkout step that rejects a submission, structured data missing a field, a stock message that stopped reflecting reality — and it appears months after the update that caused it, which is why it's so rarely traced back.
Checkout, cart, and customer account templates are the worst offenders, because those are the areas that change most and the areas where a silent failure costs money directly.
The routine that helps: diff every copied template against the current version of the file it replaced, at least once per upgrade cycle. Not to re-apply everything — most changes won't matter to you — but to make it a decision rather than an accident.
2. Layout XML — safer, but it accumulates
Layout instructions age better because most of them are additive: you're referencing a block and adding, moving, or removing something. When a target still exists, your instruction still works.
The rot here is different. Over years you accumulate instructions referencing blocks and handles that no longer exist, left behind by removed extensions and abandoned features. Magento is largely tolerant of an instruction whose target is gone, which is why nobody notices — and also why the files become unreadable, so the next developer daren't delete anything.
The other layout-specific decay is duplication: three separate <referenceBlock> entries doing overlapping things to the same block because three people solved three problems without reading each other's work.
The routine that helps: treat layout XML as code that gets deleted, not only added to. When an extension is removed, remove the layout that talked to it in the same change.
3. LESS and CSS overrides — cheap, cosmetic decay
Style overrides fail visibly and locally. The parent theme changes a class name or restructures a block, your rule stops applying, and you see it on the page. Annoying, but self-announcing — the failure mode is the good kind.
The cost here is accumulation rather than breakage: overrides written to defeat earlier overrides, long selector chains and !important declarations, and rules targeting components deleted years ago. It bloats the compiled stylesheet and makes every future change slower to reason about, but it rarely breaks anything.
The routine that helps: low priority. Prune when you're in the file anyway.
4. JavaScript mixins and RequireJS config — fails loudly
A mixin extends a component's behaviour rather than replacing it, which is the more durable pattern. When the underlying component changes in a way your mixin can't handle, you generally get a console error and a visibly broken widget.
Loud failures are inconvenient but cheap: someone notices, someone fixes it. The real risk is the reverse case — a mixin that keeps running against a component whose responsibilities have moved, so it's now decorating something that no longer does the job it used to.
The routine that helps: check the JS console on your key flows after every upgrade. It takes minutes and it catches this whole category.
The fifth thing, which isn't an override at all
Removed extensions leave residue in the frontend: layout XML referencing gone blocks, RequireJS mappings pointing at absent files, template overrides for a module nobody has installed, and stylesheet rules for components that no longer render. Uninstalling a module doesn't clean the theme that was customized around it, because the theme is yours and the platform won't touch it.
This is one of the more common contributors to a storefront that got slower without anyone changing anything — related to, but distinct from, the causes covered in what actually slows down a Magento store.
Seeing the drift: a routine that takes an afternoon
You cannot maintain what you haven't listed. Most stores have no inventory of what their theme has taken ownership of.
Start with the list:
find app/design/frontend/Acme/storefront -name "*.phtml"
Then, for each one, compare it against the file it shadowed. The override path mirrors the module's own path, so the pair is always mechanical to find:
diff vendor/magento/module-checkout/view/frontend/templates/cart/form.phtml \
app/design/frontend/Acme/storefront/Magento_Checkout/templates/cart/form.phtml
Read the diff with one question in mind: is the difference still the change I intended, or has the parent grown things mine doesn't have? Intended differences are fine. Everything else is drift, and each item gets one of three outcomes:
- Re-apply — port the upstream change into your override.
- Re-base — start from the current parent file and re-apply your customization to it. Usually cleaner than patching a stale copy.
- Delete — the platform now does what you were overriding for. This is more common than people expect, and it's the best possible outcome.
Do this per upgrade cycle rather than continuously. Do it before the upgrade, not after, so it informs the pre-upgrade audit described in upgrading without breaking the store instead of becoming an emergency during it.
Maintenance that is theatre
Several routines feel like diligence and change nothing. They're worth naming, because they consume the attention the diffing routine needs.
- Flushing the cache on a schedule. Clearing caches is a debugging step, not maintenance. A store that needs regular flushes has an invalidation problem, and flushing hides it while making every subsequent page load slower for real customers.
- Manual reindexing as a ritual. Indexers are meant to be scheduled and to run themselves. Reindexing by hand every week doesn't improve anything; it papers over a cron configuration that should be fixed once.
- Toggling minification and merging to "see if it helps". These settings interact with your theme's asset structure in ways that differ per store. Flipping them without measuring the same page before and after produces an opinion, not a result.
- Speed tests with no baseline. A monthly score screenshotted into a report tells you nothing without the same page, the same conditions, and the previous number beside it. Trend or nothing.
- Updating extensions because updates exist. Every update is a chance for the drift above to bite. Update for a fix you need or a security patch; a version bump for its own sake is risk with no return.
- Reviewing "unused CSS" reports. Storefront stylesheets legitimately carry rules for pages the report never visited. This one generates work rather than finding it.
None of these are harmful in themselves. They're harmful because they get counted as maintenance, and then the actual maintenance doesn't happen.
When to stop patching an override
Some customizations should not be carried forward at all. Three tests, and one "yes" is enough:
- Is the parent file now doing substantially more than your copy? If upstream has moved on significantly, you're maintaining a fork. Re-base from the current file or drop the customization.
- Could this be a layout instruction or a plugin instead? A copied template that exists to remove one element, change one label, or reorder two blocks is nearly always better expressed as layout XML or an interceptor — both of which keep receiving upstream updates while yours doesn't.
- Does anyone still want it? Overrides outlive the campaigns, promotions, and stakeholder preferences that created them. If nobody can say why it's there, deleting it is the cheapest maintenance available.
If the honest answer is that half your overrides fail these tests, the problem may be upstream of maintenance entirely: a theme that fought you from the start produces more overrides than one that fit, which is exactly the calculation in choosing a Magento theme.
FAQ
How often should I review my theme's overrides?
Tie it to your upgrade cycle rather than the calendar, and run it before the upgrade rather than after. Reviewing overrides is how you find out what an upgrade will actually change for you, so doing it first turns a discovery problem into a planned one.
Do template overrides break during a Magento upgrade?
Usually they don't break — that's the difficulty. A stale template renders happily while missing whatever the module added since you copied it, so the failure appears later and somewhere else. Loud breakage is the easy case; the silent case is what the diffing routine is for.
Is it better to override a template or use layout XML?
Layout XML wherever it can do the job, because it keeps receiving upstream updates to the template while still applying your change. Reserve template overrides for markup changes that genuinely can't be expressed as adding, moving, or removing blocks.
Why does my store get slower over time with no new features?
Frequently it's accumulation rather than any single cause: leftover layout and RequireJS entries from removed extensions, stylesheet rules for components that no longer render, and asset bundles carrying files nothing uses. Removing a module doesn't clean the theme that was customized around it.
Should I clear the Magento cache regularly as maintenance?
No. Regular flushing is a symptom that something is invalidating the cache or that an uncacheable block is disabling it for a page. Find that cause instead — routine flushing just moves the cost onto your customers' page loads.
The bottom line
A theme doesn't rot; the gap between it and the platform widens. Inventory what you've taken ownership of, diff the templates against the files they replaced once per upgrade cycle, delete the overrides the platform has made redundant, and clean up after every extension you remove. Skip the cache-flushing rituals and the baseline-free speed tests — they cost attention the real work needs. For more on building and maintaining Magento storefronts that stay workable, visit Magetique.