Invite-only beta · 9 free places left · Managed hosting on AWS

AceMedia HostRequest invite

OPERATIONS · 22 OCTOBER 2026

Why we run nginx, and when Apache still wins

AceHost is built on nginx with PHP-FPM. That was a platform decision, not a verdict on Apache, which is still the right answer for plenty of sites. Here is how I think about the choice.

People sometimes ask why AceHost runs nginx rather than Apache, usually expecting a story about one being much faster than the other. The honest answer is less dramatic. AceHost runs on CloudPanel, and CloudPanel's web layer is nginx with PHP-FPM. Everything we built on top of it assumes that stack. So nginx was a platform decision first, and the reasons it suits us came after.

I want to be clear about one thing before going further. I have not benchmarked nginx against Apache on identical hardware, and I am not going to pretend otherwise. Apache with the event MPM and PHP-FPM is a perfectly good way to run PHP sites. Several client projects I look after run exactly that, and they run well.

What is actually answering

If you are not sure which server is in front of a site, the response headers usually tell you, unless the server has been told to stay quiet about it or a CDN sits in front.

Terminal: which web server is answering
curl -sI https://example.com | grep -i '^server'
server: nginx
# On the server itself
nginx -v
apache2 -v

Behind Cloudflare you will see server: cloudflare, which tells you about the edge rather than your origin. Checking on the box itself is the reliable way. On RHEL family systems the Apache binary is httpd rather than apache2.

Where nginx fits us

It is what the control panel speaks

The biggest reason is the least exciting one. CloudPanel generates and manages nginx configuration, and our own control plane builds on that. Swapping the web server underneath would mean fighting the tool we chose to build on. If your panel is built around Apache, the same logic points the other way.

Configuration is a plain text template per site

Each site gets its own nginx configuration, generated from templates. That means every site starts from the same known shape, and a change to the template is a change I can review, track and roll out deliberately. Nothing is hidden in a file a site owner edited three years ago. Apache can be run this way too, but nginx pushes you towards it, because there is no per directory override to fall back on.

Many connections, little memory each

nginx is event driven. A small number of worker processes each handle a large number of connections, and an idle or slow connection costs very little memory. On a busy shared server that serves many sites, that matters: slow clients, long keep alive connections and bursts of traffic do not tie up a process each. Apache's event MPM narrows this gap a great deal compared with the older prefork model, which is one reason I recommend it in my Apache tips.

Static files and proxying

nginx is very comfortable serving files straight from disk and passing everything else on to something else, whether that is PHP-FPM or a cache. For WordPress we run Varnish and a Redis page cache alongside PHP-FPM, so that repeat visits rarely reach PHP at all. I wrote up how those two caches stay in step in Varnish and Redis together. nginx sitting at the front of that, handing requests to the right place, is the job it was designed for.

Rate limiting and maps

nginx has request rate limiting built in, through limit_req, and a map directive that lets you decide which requests a limit applies to. That is useful for things like login pages, or for capping how quickly crawlers can hit expensive URLs such as shop filter pages, without slowing down ordinary visitors. A minimal example looks like this.

Terminal: a simple nginx rate limit
# In the http block: only filtered URLs get a key
map $args $filter_key {
    default         "";
    ~*(^|&)filter_  $binary_remote_addr;
}
limit_req_zone $filter_key zone=filters:10m rate=2r/s;

# In the server block for example.com
location / {
    limit_req zone=filters burst=10 nodelay;
    try_files $uri $uri/ /index.php?$args;
}

An empty key means the request is not counted, so only URLs with a filter_ argument are limited. Behind a proxy or CDN, make sure nginx sees the real visitor address first, or every request will appear to come from the same few addresses. I covered that side in lock your origin to Cloudflare.

HTTP/2, HTTP/3 and Brotli

nginx serves HTTP/2 and HTTP/3 over QUIC, and with the Brotli module it compresses text more tightly than gzip. Apache supports HTTP/2 and Brotli as well, but HTTP/3 is not something stock Apache offers, so if you want it at the origin, nginx is the simpler route. Many sites get HTTP/3 from their CDN anyway, so this matters less than it sounds.

Where Apache is the better answer

Site owners who need .htaccess

This is the big one. Apache reads .htaccess files in each directory, so a site owner can add redirects, rewrite rules, access rules or caching headers without touching the server configuration. On hosting where customers do not have root, that is genuinely valuable. nginx has nothing equivalent. Every change goes through the server configuration, which means through whoever manages the server.

Apps that ship rewrite rules in .htaccess

Plenty of PHP applications and plugins assume Apache. They ship an .htaccess file and expect it to work, or they write rules into it when you change a setting. On nginx those rules are ignored silently. WordPress itself is easy to translate, but some plugins and older applications are not, and keeping them in step by hand is ongoing work.

Apache modules

If you rely on mod_security with a particular rule set, or on another Apache module with no direct nginx equivalent, staying on Apache is usually the sensible choice. Some modules have nginx versions or alternatives, but they are not always drop in replacements.

Habits and tooling

Shared hosting grew up on Apache. A lot of documentation, support answers and team experience assume it. If your team knows Apache well and your sites are happy, that knowledge is worth more than a theoretical gain from switching.

Gotchas when moving to nginx

No .htaccess means translating rules

Every rewrite rule, redirect and access rule in every .htaccess file has to be found, translated into nginx configuration and tested. Look in subdirectories too, not just the site root. Redirects are where mistakes hurt most, because a broken redirect can lose search traffic quietly. Test the old URLs you care about after the move, not just the home page.

Location matching order

nginx picks one location block per request, and the rules for which one wins are not the order you wrote them in. Exact matches come first, then the longest prefix match, unless a regular expression location matches, in which case the first matching regular expression wins unless the prefix match was marked with ^~. Most surprises after a migration come from a rule that never runs because a different block caught the request.

try_files

try_files replaces the usual Apache front controller rule that sends anything that is not a real file to index.php. Get it wrong and you will see 404s for pretty permalinks, or PHP files served as downloads. The line in the example above is the common WordPress form.

Different defaults

Upload size limits, timeouts, directory listings, how the trailing slash is handled and which files are hidden all behave differently out of the box. If something worked on Apache and fails on nginx, check the defaults before assuming the application is at fault.

Test before you reload

Both servers can check their configuration before you apply it. Make it a habit. A reload with a broken file can leave you with an error page across every site on the server.

Terminal: test configuration before reloading
# nginx
sudo nginx -t && sudo systemctl reload nginx
# Apache on Debian or Ubuntu
sudo apache2ctl configtest && sudo systemctl reload apache2

With Apache it is also worth checking which configuration is actually in force, since included files and enabled sites can surprise you. I wrote about that in check the Apache configuration that is actually loaded.

Upgrades replace the binary

When you upgrade nginx, the package replaces the binary in place. The running processes keep the old code until nginx is restarted or upgraded on the fly, so check what is running, not just what is installed, and run nginx -t afterwards in case a module or directive changed.

A short checklist for choosing

  • What does your control panel or platform expect? Go with it unless you have a strong reason not to.
  • Do site owners need to change rules without server access? If yes, Apache and .htaccess are hard to beat.
  • Do your applications depend on .htaccess or Apache modules? Count the rules and modules before deciding, not after.
  • Is PHP run through PHP-FPM? On either server, it should be. Apache with the event MPM and proxy_fcgi rather than mod_php is a solid setup.
  • Do you want configuration managed centrally from templates? nginx suits that well.
  • Do you need HTTP/3 at the origin? nginx makes that easier, though a CDN may already give it to you.
  • What does your team know? A well run server you understand beats a fashionable one you do not.

For us, nginx is the right fit because the platform is built around it and we manage every site's configuration centrally. If your situation looks different, Apache is not a compromise. It is a mature, capable server, and with a few sensible settings it will serve you well for years.

More hosting tipsTalk about your hosting

INVITE-ONLY BETA

Tell us about your site.

Nine free beta places remain for projects that will help shape the service. Tell us what you’re building; we’ll reply personally. Fields marked * are required.

Please do not send passwords or private customer data. We’ll use these details to reply. Privacy notice.

Prefer email? Write to [email protected].