Choosing a web server
This page is for product managers and system administrators at hosting companies who have to decide what serves
the Exponential sites on a plan. It answers: which servers and engines are possible, which questions decide between
them, what each choice means for operations, and how to write the decision down. The facts come from
Chapter 8: Serving the site, Operating system support
and the repository's README.md.
Warning
.htaccess slows down every request. When .htaccess files are enabled (AllowOverride anything but None), let alone
used, Apache looks for them and reads and evaluates them on every request, in every directory of the path, and
page loading times go up drastically (measured). The only real fix is to switch the feature off for
the virtual host: AllowOverride None in the HTTPS virtual host, and the rules in the virtual host's own
configuration as mod_rewrite rules. That is far faster in production speed tests and well worth the time it takes
to optimize a production configuration. Switch over right away: copy the rules of the
example HTTPS virtual host into your virtual host (with the static cache, also
staticcache_offload.conf), set AllowOverride None, run apachectl configtest, reload Apache and
test the site. The same rules for other servers: nginx, LiteSpeed,
Caddy, IIS, Velocity (built in); where virtual host rules go in a control
panel: Plesk, cPanel, DirectAdmin, ISPConfig.
On LiteSpeed or OpenLiteSpeed, the server's own page cache can also answer anonymous visitors and crawlers without PHP: Page caching with LiteSpeed and OpenLiteSpeed.
Contents
- The choice in one table
- Five questions that decide it
- By hosting model
- Isolation between customers
- What each choice costs you in operations
- Mixing servers
- A decision record to copy
- Checklist
The choice in one table
Taken from Chapter 8, The choice in one table:
Exponential Velocity (qbix) | FrankenPHP (through Velocity) | Apache + PHP-FPM | nginx + PHP-FPM | |
|---|---|---|---|---|
| Role | recommended for every stage | production-ready alternative | traditional | traditional |
| PHP | 8.0 or later (from Velocity 0.0.4.54) | the PHP built into the binary | 8.0 or later | 8.0 or later |
| Separate web server needed | no | no (Caddy is built in) | yes | yes |
| Separate HTTPS or certificate tool needed | no: own certificates, self-signed fallback, ACME | no: your certificate or a self-signed one | yes (mod_ssl plus certbot or a panel) | yes |
| Application kept in memory between requests | yes (persistent workers) | no (clean state per request) | no | no |
| Response cache in front of PHP | yes | not yet | no (the kernel's own caches only) | no |
| Rewrite rules | built in | generated Caddyfile | .htaccess_root (exp:setup:htaccess --apply) | written by you |
| Suits shared hosting | usually not | usually not | yes | rarely |
Other servers that can rewrite a URL to index.php work as well. The README lists LiteSpeed and OpenLiteSpeed,
Caddy, Microsoft IIS, lighttpd, H2O and Traefik (the last usually in front of another server), and says plainly:
"All of these work. Exponential does not require any particular one." Operating system
support puts LiteSpeed, Caddy with PHP-FPM, IIS and lighttpd in tier 3, expected to
work.
Note
PHP's built-in server (exp:velocity start --engine=php) is the shipped default engine only because it needs
nothing installed. It is for development, has no TLS and must never face visitors.
Five questions that decide it
| Question | If the answer is ... | Then |
|---|---|---|
| May a customer's site run a long-lived process on this plan? | no (typical shared hosting) | Apache or LiteSpeed with .htaccess. "Shared hosting usually will not" allow one (README.md) |
| Is the machine's PHP 8.0? | yes (the stock PHP of Red Hat Enterprise Linux 9 and its rebuilds) | any engine; Velocity runs on 8.0 from its release 0.0.4.54, with the el9 rpm or Composer (Chapter 2) |
| Must customers on one machine be isolated from each other by the operating system? | yes | one Velocity per site, each as its own user, or one PHP-FPM pool per site |
| Do you already run a tuned Apache or nginx you want to keep? | yes | keep it; Velocity can sit behind it or beside it |
| Do you want the fastest answer for repeat pages without adding a cache server? | yes | Velocity with its response cache |
These are the conditions chapter 8 names for a traditional server: "when your hosting does not allow long-running processes, when you already run a tuned Apache or nginx you want to keep, when the machine only has PHP 8.0 ... or when several customers on one machine need operating-system isolation from each other".
By hosting model
| Hosting model | Usual choice | Why |
|---|---|---|
| Shared hosting with a control panel | Apache (or LiteSpeed) with PHP-FPM and .htaccess | no long-running customer processes; the rules ship as .htaccess_root |
| VPS or dedicated server per customer | Velocity | one site per machine, root available for ports 80 and 443 |
| Several customers on one VPS or dedicated server | Velocity per site (own user, own ports, a proxy in front) or PHP-FPM pool per site | operating-system isolation |
| Containers | Velocity or FrankenPHP in the container | one process tree per site; images exist for Velocity (Velocity packages and binaries) |
| Windows hosting | IIS or Apache with FastCGI PHP | pcntl and posix do not exist on Windows (Operating system support) |
The models themselves are compared on Choosing a hosting model.
Isolation between customers
The README is explicit: "A single server process serving several sites is a routing convenience, not a security boundary — the process that serves one site can read every file the others hold." For a plan that puts several customers on one machine:
- Velocity: run one Velocity per site, each with
[ServerSettings] UserandGroupset to that customer's user, on its own ports, behind a proxy. See Velocity beside Apache or nginx. - PHP-FPM: give each site its own pool running as the site's user. See Apache with PHP-FPM and Per-customer users and pools.
The security side is on Multi-tenant isolation.
What each choice costs you in operations
| Velocity | FrankenPHP | Apache or nginx with PHP-FPM | |
|---|---|---|---|
| Install | composer require se7enxweb/exponential-velocity, then exp:velocity start | exp:velocity install downloads and verifies the binary | distribution packages or the panel |
| After a PHP class or INI change | exp:velocity deploy (restart included) | exp:velocity deploy (the same command, --engine=frankenphp) | reload the PHP-FPM that serves the site, or exp:velocity deploy --no-velocity |
| Certificates | Velocity itself, including ACME | your files or self-signed; renewed by you | mod_ssl or nginx plus certbot or the panel |
| Boot service | a systemd unit you write (chapter 8 gives a derived one) or the engine's own units | the same | the distribution's units |
| What to monitor | exp:velocity status --json, /Q/health, the logs in var/vc/qbix/ | status, Caddy's JSON logs in var/vc/frankenphp/log/ | the server's and PHP-FPM's logs |
Warning
Under Velocity the workers keep classes, INI values and compiled templates in memory. A changed class or setting
reaches them only after a restart. Train support staff on exp:velocity deploy before you sell Velocity plans
(Chapter 8, Deploying a change).
Mixing servers
The choices are not exclusive. A common shape is Velocity serving the site while Apache or nginx stays in place on
the same files during a migration; both then share var/, the caches and the sessions, so they must write as the
same user. exp:velocity deploy brings both up to date in one run because it also reloads the PHP-FPM that serves the
site. Details: Velocity beside Apache or nginx.
A decision record to copy
Plan name: <plan>
Server or engine: Velocity (qbix) | FrankenPHP | Apache + PHP-FPM | nginx + PHP-FPM | other: ...
PHP version and source: <version>, <distribution package | panel | binary>
Long-running processes allowed: yes | no
Isolation between customers: one machine per customer | one Velocity per site | one FPM pool per site
TLS terminated by: Velocity | FrankenPHP | Apache/nginx | load balancer or CDN
Response caching: Velocity response cache | kernel caches only | proxy in front
Who restarts after a deploy: <role>
Tested on staging on: <date>, by <role>Checklist
- To do: The plan's answer to "may a long-running process run?" is written down.
- To do: The PHP version on the machine is 8.0 or later, also where Velocity is offered.
- To do: Isolation between customers decided: per machine, per Velocity instance or per PHP-FPM pool.
- To do: The four routing checks of Web servers and engines pass.
- To do: Support knows how a PHP change reaches the server (
exp:velocity deploy, or the FPM reload). - To do: A tier 3 server was tested on staging before it was sold.
Related pages
- Web servers and engines
- Velocity for hosts
- Apache with PHP-FPM
- Choosing a hosting model
- Choosing hosting, database and operating system
- Setting up .htaccess and config.php from the console: which servers read
.htaccess - Free documentation: this page is free to copy, translate and improve under the GNU FDL 1.3.
Become an Exponential Partner
Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.