Questions

The answers, before you have to ask.

Installing, compatibility, the 7-day trial and the licence, how the cache actually behaves, and what to do when a page looks wrong. If yours isn't here, ask us — the reply usually ends up on this page.

Installing and upgrading

How do I install Nitro?

Upload the archive through Extensions → Installer, then open Extensions → Modifications and press Refresh so OpenCart applies Nitro's patches. Then install Nitro from the module list under Extensions → Extensions → Modules. That install step does the rest itself: it applies the Recommended profile — which turns the master switch and the full-page cache on — writes Nitro's runtime settings file, registers its OpenCart event hooks and adds one guarded line to your storefront index.php. The engine is running by the time Install finishes; opening the settings page afterwards is for tuning, not for starting it.

Do I have to press Refresh under Extensions → Modifications?

Yes — do it straight after uploading. Several of Nitro's fastest paths are ocmod patches rather than event hooks: the query-cache delegate in system/library/db.php, the replacement file-cache internals, the fast image resize, the storefront template engine, and the hook that makes Journal3's own Clear Cache button clear Nitro's cache too. If you skip it, Nitro still installs and the page cache still works, but the Diagnostics tab's Query delegate (db.php ocmod) row will tell you to go and press Refresh. Doing it later is fine — no reinstall needed.

Do I need a cron entry?

Only for the work that runs on a schedule — the storefront serves cached pages without it. The Cron tab prints the exact command with your server's PHP CLI binary already detected, and recommends running it every five minutes. One entry covers all of it: crawling the store as a guest so pages are pre-rendered before visitors arrive, deleting expired entries, trimming the cache to your size cap, recording product views that the cached serve path cannot count, picking up products edited outside OpenCart, and rebuilding the price index if you use it. It refuses to run over HTTP, so there is no token to protect and no request timeout to hit.

How do I upgrade to a new version?

Upload the new archive through Extensions → Installer and press Refresh under Extensions → Modifications again. Do not uninstall first — your settings live in OpenCart's own settings table and are left alone. Nitro notices that its runtime settings file no longer matches what the admin has saved and rewrites it by itself the next time you load any admin page; there is a Re-apply Settings button if you want to force it. A release that adds a new option leaves that option off until you turn it on, so it is worth reading the release notes and looking over the settings page afterwards.

How do I uninstall Nitro, and what does it leave behind?

Uninstall the module from Extensions → Extensions → Modules. That removes its permissions and event hooks, takes its one line back out of your storefront index.php, deletes its settings, drops the price-index table, and deletes its storage and cache directories along with every generated .nitro.css, .nitro.js and bundle it wrote beside your theme. Then remove Nitro under Extensions → Modifications and press Refresh so the ocmod patches come off your core files. Three things stay on purpose: the extension's own files until you delete them, the .webp copies in image/cache, and anything you applied from the Database tab — added indexes and InnoDB or utf8mb4 conversions are not reversed.

Licence, price and trial

What does Nitro cost?

49€, paid once, for one storefront domain — forever. There are no subscriptions, no renewals, no tiers and no seat counts. One payment covers every system the extension ships — page cache, query cache, assets, images, firewall, warmer, database tools — on that domain, for as long as the store runs it.

Is there a trial?

Yes — 7 days, and there is nothing to sign up for and no card to enter. Each storefront domain gets exactly one trial, ever, so reinstalling the extension or moving it to a different OpenCart install on the same domain does not start a second one. The trial is the whole product: nothing is held back for the paid version.

What happens when the trial ends?

Nitro stops accelerating that domain. Nothing breaks — the store falls through to exactly the way OpenCart served it before you installed Nitro: same pages, same theme, same checkout, just without the cache in front. Every setting you configured is still there in OpenCart's settings table, so licensing the domain picks up precisely where the trial left off, with no reconfiguration.

I was told no trial is available, but I have never installed Nitro on this domain.

Please get in touch — that message is often not about your domain at all. Our licence server limits how many brand-new trials one network address may start in a day, and a shared host puts many unrelated shops behind a single address. Once that day's quota is used, the next new domain coming from that address is told no trial is available even though it has never had one. It is a false negative, we can see it in our logs, and we can clear it for your domain by hand — so do not conclude the domain was already used.

One OpenCart install serves several storefront domains. How many licences do I need?

One per storefront domain, not one per OpenCart install. Three storefronts on one codebase means three licences. They do not have to be bought together: unlicensed domains on that install are not blocked or broken, they simply run as stock OpenCart while the licensed ones are accelerated, so you can license them as you go.

Does www.example.com count as a second domain?

No. A domain and its www twin are one licence — the host check pairs example.com with www.example.com in both directions, so whichever one a visitor lands on is covered. If you want one of the two to be canonical, Nitro's optional Canonical Domain Redirect will 301 the other to it, which also stops the cache holding two copies of every page.

I am moving the store to a different domain.

Get in touch before you switch. The build you were sent is sealed to your domain, so on a new hostname it goes quiet and the store serves as stock OpenCart — no error page, no broken checkout, just no acceleration. Tell us the new domain and we will issue the licence and a build for it. Nothing is lost meanwhile: your settings stay in OpenCart's settings table and Nitro starts accelerating again the moment the right build is in place.

How do I pay, and can I get an invoice?

There is no card checkout on this site yet. Get in touch with the domains you want licensed and we will issue them and arrange payment directly. Ask for an invoice in the same message — automated invoicing and VAT handling arrive with the payment gateway, so until then invoices are issued by hand, which is no slower for you.

What data does Nitro send about my store?

None. There is no telemetry, no usage statistics and no analytics of any kind — that is a product decision, not an option you have to find and switch off. The only HTTP requests the extension makes are to your own storefront: the cache warmer fetching your pages as a guest, and the background refresh of a page that has gone stale. The one outbound lookup it does make is DNS: when bot throttling is on, a visitor claiming to be Googlebot or Bingbot is verified by reverse DNS using the procedure those crawlers themselves document.

Cache and content updates

I changed a product in the admin and the storefront still shows the old page.

It should already be gone. Saving a product, category, information page, manufacturer, option, attribute or review in the OpenCart admin fires an event that hard-deletes that item's own cached page — every language, currency and device variant of it — and marks the rest of the cache stale so listings rebuild on the next visit. If you are still seeing the old page, paste the exact address into Purge URL in Nitro's Cache section; it reports how many cached files it removed. If it answers that the URL is not in the cache, what you are looking at is your browser's own copy, not Nitro's.

I edited products with an ERP, a feed script or SQL, and the pages did not update.

Writes that bypass the OpenCart admin fire no OpenCart event, so nothing tells Nitro to drop those pages. The cron picks them up instead: every run compares each product's date_modified against what it last saw and purges the pages of anything that changed, plus anything that was deleted, then re-warms them in the same run. If you have no cron entry yet, that is the fix — the Cron tab prints the command. Until it runs, Purge URL or Clear Cache does it by hand.

My CSS or JavaScript edits are not showing on the storefront.

Nitro writes a minified copy beside each of your theme's .css and .js files and regenerates it as soon as the source file is newer, and the ?v= on the URL is a hash of the minified content — so an ordinary edit appears on its own. The exception is bundling: a bundle is named after its sources' URLs and file sizes, so an edit that leaves a file exactly the same length — changing #fff to #eee, for instance — reuses the existing bundle. Press Clear Cache: it deletes every *.nitro.css, *.nitro.js and bundle directory under catalog/view, and they are rebuilt on the next page view.

How do I clear the whole cache?

Clear Cache, in Nitro's admin. It returns immediately however large the cache is: the cache is renamed aside so the store is logically clear at once, and the files are deleted afterwards — a little on the way out, the rest by the cron. If you need the disk space back this minute, Clear Cache + Reclaim Disk does the deleting there and then, which can take minutes on a large cache. Either button clears cached pages, cached query results and the generated CSS and JS together.

How do I remove one specific URL from the cache?

Paste the full address into Purge URL in Nitro's Cache section. It removes every cached variant of that page — desktop, mobile and tablet — and tells you how many files it deleted, or that the URL was not cached at all. If you are already looking at the page on the storefront with the speed panel on, its Purge this page button does the same thing. From code it is one call: \Nitro\Page::purge($url).

How do I clear the cache from code, or on a schedule?

Two lines, anywhere OpenCart's constants are defined:

require_once DIR_SYSTEM . 'library/nitro.php';
(new \Nitro())->flush();

That clears the page cache, the query cache and the generated CSS and JS. It is exactly what Nitro's own hook into Journal3's Clear Cache button runs, so it is a well-travelled path. Put it in a small PHP script and schedule that if you want a clear on a timer. Nitro's own cron entry deliberately never clears: it prunes what has expired, trims the cache to your size cap and warms it back up, which is what you want on a schedule almost every time.

How long does a cached page stay cached?

Twenty-four hours by default, with per-route overrides seeded at install: specials one hour, the home page six, categories and products twelve, manufacturers twenty-four, information pages a week. On top of that, stale-while-revalidate is set to one hour, so a page past that point is still served instantly while it rebuilds in the background — a visitor never waits for a rebuild. Expiry is staggered across the last fifth of each page's lifetime, so a cache warmed in one pass does not all fall due at the same moment. Catalog edits clear pages immediately regardless of any of this.

How do I turn on WebP images?

Serve WebP is on in every profile, so it is almost certainly already running. It needs GD compiled with WebP support — the Diagnostics tab has a GD WebP row that says plainly whether your PHP has it, and the option quietly does nothing if it does not. When it is on, a .webp is written next to each resized image as pages are visited or warmed, and the image URL in the HTML is rewritten to it wherever the file exists — so it works on any server, with no .htaccess content negotiation. Changing Image Quality deletes the existing .webp copies so they regenerate at the new setting, leaving the thumbnails themselves alone.

Something is wrong

Nitro says it is inactive, or that its settings file is missing or stale.

Nitro's runtime settings file — system/storage/nitro/config.json — is what the pre-framework engine reads on every request, and it is missing or out of step with what the admin has saved. Click Re-apply Settings to rewrite it. If the warning comes back, system/storage/nitro either does not exist or is not writable by PHP; the Diagnostics tab's Cache dir writable row shows the exact path it is trying. Nothing is broken meanwhile — an unreadable settings file makes every feature read as off, so the store runs as plain OpenCart rather than failing.

Nitro warns it could not write the storefront index.php hook.

The page cache and the firewall run before OpenCart boots, and that needs one line in your storefront index.php. Nitro adds it automatically when you save settings; this warning means the file was not writable. Make it writable and save again, or add the line yourself immediately above // Startup:

if (is_file(DIR_SYSTEM . 'library/nitro/boot.php')) { require_once DIR_SYSTEM . 'library/nitro/boot.php'; }

The Diagnostics tab's index.php hook row is where to confirm it took — worth checking right after installing, because the install step writes the hook without reporting a failure.

Nitro says it is not licensed for this domain.

The build you installed is sealed to a different hostname, so on this one every feature stays off and the store serves as stock OpenCart. You can still open and save settings; they simply will not take effect. This is what you see after moving to a new domain, or after installing a build meant for another shop. Get in touch with the hostname the store is actually served on and we will issue a build for it.

Another admin user cannot see Nitro in the menu.

Installing the module grants access and modify on extension/module/nitro to the user group of whoever pressed Install, and to nobody else. Add both permissions to the other group under System → Users → User Groups. Without access, the admin header widget and the settings page stay hidden entirely; without modify, the page is visible but every action — saving, clearing the cache, purging a URL, exporting settings — is refused.

I am locked out of the admin with "Too many failed login attempts".

That is Nitro's firewall, not OpenCart. Ten failed admin logins from one IP within fifteen minutes lock that IP out of the login page for fifteen minutes with an HTTP 429, and a successful login clears the tally immediately. Wait it out, or delete your IP's lock file under system/storage/cache/nitro/admin_lock/. It only ever counts failures — it never bans an IP permanently, and it does not touch the storefront.

Something broke right after I changed a setting. How do I get back quickly?

Turn the master switch off and save: Nitro then does nothing at all and OpenCart runs normally, which tells you in seconds whether it is the cause. To narrow it down without switching anything off, use Start Bypass — it opens the storefront with the page cache, query cache and asset rewriting all skipped, for your browsing session only, so you can compare a raw page against the optimized one. If it turns out to be an asset option, switching the profile to Safe leaves full-page caching and the riskier HTML rewrites off. Errors inside Nitro never take the store down by design — it falls through to stock OpenCart instead.

What does Nitro need to be able to write to?

Four things. system/storage/nitro/ holds the settings file and runtime state; system/storage/cache/ holds cached pages and query results; the storefront index.php needs to be writable once, so Nitro can add its pre-framework line; and your theme's asset directories under catalog/view/theme/ need to be writable if you want minified or bundled CSS and JS, since those are written beside the originals. The Diagnostics tab checks the first three and names the exact paths it is using.

Product thumbnails come out broken or missing.

Large source images are the usual cause: OpenCart resamples straight from the full-size file, and on a big photo that can hit the PHP execution timeout and leave a half-written or missing thumbnail. Nitro's Fast Image Resize shrinks the source in one cheap step first, so the quality resample works on something small — the same result for a heavy downscale, far less work. It is on in every profile, but it is an ocmod patch, so it does nothing until you have pressed Refresh under Extensions → Modifications.

Speed and diagnosis

Why are add to cart, login and checkout still slow?

Those pages are never cached, deliberately. Checkout, cart, account, login, register, logout, the API and payment routes are excluded outright — serving a shared copy of any of them would show one customer another's session. Beyond that, a guest who has put something in the basket, started a wishlist or comparison, or switched currency or language gets fully live pages from then on so the header is always right, and logged-in customers get live pages unless you deliberately enable caching for them. Those live pages are still faster than stock OpenCart, because the query cache, the optimized template engine and the asset work all still apply — they just do not skip the render.

How do I find out why a particular page is slow?

Turn on the Page Speed Panel and open the link it gives you. Every storefront page then carries a small badge saying whether it was a HIT, STALE or MISS, how long it took, how big it was, its cache key and which device bucket it landed in — with a button to purge that page and reload. A page that is always a MISS is being excluded or bypassed, and the dashboard's bypass counters say by which rule. If it is a HIT and still slow, the time is going somewhere in front of Nitro. Start Bypass shows you the same page with Nitro off entirely for comparison, and Track Slow Queries logs storefront queries over your threshold while you investigate. The panel link contains a secret — treat it like a password.

The dashboard shows a low cached-page hit ratio.

The dashboard breaks bypasses down by reason, which is where to look. Dynamic means visitors arriving with a cart, wishlist, comparison or login. Untrusted means requests on a hostname that is not in your OpenCart store table — the cacheable-host list is derived from that table and never hand-edited, so a storefront domain missing from System → Settings shows up here. Pattern means a URL matching an exclude rule. Cookie means one of your No-cache Cookies was present, and a high count there usually means a consent or A/B cookie was listed that every visitor actually has, which disables the cache for everyone.

Hosting, themes and proxies

Which OpenCart versions does Nitro support?

OpenCart 3.x. Nitro is built against OpenCart 3's file layout, controller naming and template engine, so it does not load on 2.x or 4.x — those are different enough that it would be a different extension, not a compatibility flag.

OpenCart 4: if there is enough demand, a version built for 4.x may follow. If you run 4.x and want it, tell us — that demand is what decides whether it gets built.

OpenCart 2.x and 1.5: not supported, and not planned. We would only look at an individual case in exceptional circumstances, by arrangement.

Which PHP version should I run?

The newest one your host offers that your store and its other extensions are happy on. Moving up a PHP major version usually buys more than any single extension can, and Nitro is faster on a modern PHP too. Nitro's Diagnostics tab shows the version you are running and tells you when moving up is worth it. Enabling OPcache matters at least as much — Nitro prints a ready-made PHP settings block, OPcache included, to paste into your host's PHP configuration.

Does it need ionCube or any special PHP extension?

No ionCube, and nothing to compile or install. Nitro uses what an ordinary PHP already has: GD for images, zlib for gzip, cURL for the cache warmer, and fastcgi_finish_request for background refreshes where it exists. Each of those is checked on the Diagnostics tab and each is optional — the WebP option simply does nothing without GD's WebP support, and background refresh falls back to the cron warmer without fastcgi_finish_request.

Does it work behind Cloudflare or another proxy?

Yes. Set Client IP Source to Cloudflare (CF-Connecting-IP), or True-Client-IP on Enterprise, so the firewall log and the failed-login lockout key on the real visitor rather than on Cloudflare's edge — the wrong choice there can lock out everybody at once. If TLS terminates at the proxy, turn on Trust Forwarded HTTPS so cached pages and Nitro's own cookies use the right scheme. There is nothing to whitelist and nothing to purge at the edge: Nitro sends cached HTML as Cache-Control: private, max-age=0, must-revalidate with an ETag, so Cloudflare will not hold your pages — the page caching happens on your own server, before OpenCart boots.

Does it work on shared hosting?

Yes, and a fair amount of the code exists because of it. The cron lock is kept inside the store's own storage directory, because shared hosts often put the system temp directory outside open_basedir and a lock nobody can open would kill every run. The Cron tab detects the right PHP CLI binary from the Plesk, cPanel, CloudLinux and Webuzo layouts rather than assuming /usr/bin/php. The warmer pauses while the server's load average is high so it does not compete with real visitors — raise its ceiling if the load on your box never drops far enough for warming to start.

Will it break my theme, or change my theme files?

Nitro caches and rewrites the HTML your theme produces; it never edits your theme's own files. It does write generated files beside them — a minified .nitro.css next to each stylesheet, and a nitro/ directory per theme for bundles — all of which uninstalling removes. The rewrites that can genuinely upset a theme (bundling JavaScript, deferring scripts, content-visibility, moving Journal3's CSS out of the page) are off in the Recommended profile, and CSS and JS bundling are separate switches so a theme that trips on one can keep the other. If something looks wrong after you turn one on, turn that one off — nothing else changes with it.

Does it work with VQMod?

Yes. Nitro's one line in the storefront index.php has to run before OpenCart boots, and on a VQMod store the usual anchors in that file are renamed and the startup require is wrapped — so Nitro looks for VQMod's own bootstrap and inserts itself above that instead. If your index.php has been customised past recognition, Nitro refuses to guess: it reports that it could not write the hook and gives you the exact line to paste in yourself.

Journal3

Is Journal3 supported?

Yes, specifically — several parts of Nitro exist only for Journal3. Its inline theme CSS, 350-450 KB of <style> in the head of every page and inside every cached copy of every page, can be lifted out into cached files. Its filter, facet and product read models get their own result cache, because their NOW() price subqueries make the generic query cache skip them. And the per-device cache carries a shim so a page rendered for one phone is not served to another with the wrong browser classes baked in.

Which settings should I change for Journal3?

Per-Device Cache is turned on for you when Nitro is installed on a store that has Journal3, because Journal renders different HTML per device on the server and a shared cached page would send a phone the desktop markup. Leave it on. Journal3 CSS to Files is the other one worth turning on, since it takes Journal's inline theme CSS out of every page — but check the storefront afterwards, as it is the one Journal-specific rewrite that touches how the page is styled. Nothing else needs changing.

Does clearing Journal3's cache also clear Nitro's?

Yes. Nitro patches Journal3's own clearCache() so that pressing Journal's Clear Cache also flushes Nitro's page cache, query cache and generated assets — you never have to clear both. It is an ocmod patch, so like the rest of them it starts working once you have pressed Refresh under Extensions → Modifications.

Do I need Journal3 for Nitro to be worth it?

No. Journal3 is one theme Nitro knows especially well, not a requirement. Everything else — the full-page cache, the query cache, the firewall, image and asset work, the warmer and the database tools — works on the default theme and on any other OpenCart 3 theme. The Journal-specific patches are marked optional in the modification file, so on a store without Journal3 they are simply skipped.