Help
Frequently asked questions
General
What is ScalWS?
Scale Web Server (ScalWS) is a multi-tenant web and application server for Linux, written in Rust. One process serves static files, reverse-proxies to upstreams, and runs PHP-FPM, Node.js, Python (ASGI and WSGI) and container applications as managed, supervised runtimes.
You organise sites as tenant → application → domains. Each tenant can get cgroup v2 limits for CPU, memory, pids and disk I/O. Other features:
- a response cache in memory and on disk
- ACME certificates
- deterministic security rules and a deterministic worker optimizer
- correlated diagnostics
- an admin API, used by
scalwsctl - an optional local AI advisor that only explains and never acts
The programs:
| Program | Role |
|---|---|
scalwsd | The server. |
scalws-controller | Runs several scalwsd instances on shared listening sockets: the Adaptive Runtime. |
scalwsctl | The operator CLI. |
scalws-console | The web administration. |
See ../ARCHITECTURE.md and cli.md.
Which operating systems does it run on?
Linux on x86_64. The packages support:
- AlmaLinux, Rocky Linux and Oracle Linux 8, 9 and 10 (for 10 see the
EL10 note), and Fedora 44:
.rpmfrom the signed dnf repository; - openSUSE Leap 16.0 and 15.6, SLES 16.0 and 15 SP7: the same
.rpmand repository, with zypper; - Debian 12 and 13, Ubuntu 22.04, 24.04 and 26.04:
.debfrom the signed apt repository; - Alpine Linux 3.24:
.apkfrom the signed apk repository, with OpenRC services (Alpine Linux).
One build serves all of them except Alpine (glibc 2.28 or later); Alpine gets a static
musl build of the same source. On the RHEL family and SUSE 16 ScalWS runs with SELinux
enforcing under its own policy module. On SUSE 15 (AppArmor or no security module) no
SELinux module is loaded and there is no AppArmor profile: ScalWS runs unconfined, as on
Debian and Ubuntu. On Alpine there are no systemd units: the services run with the same
user and capability limits and with --service-sandbox (a Landlock write fence and a system
call deny-list), without a private /tmp, private devices or namespaces, and scalwsctl status says so (Alpine Linux). No control panel supports
SUSE or Alpine. On EL8, tenant limits need a switch to cgroup v2. See installation.md; for servers
with a control panel, see the panel and system matrix.
The code builds on other systems for development, but Linux-only features such as cgroups, signal-based reload, Unix-socket upstreams and the controller are not available there.
Should I run scalws-controller or scalwsd.service?
The package provides both units. They exclude each other: enable one.
scalws-controller(the default) supervises severalscalwsdinstances and can scale them. ScalWS Console manages the server through it. Under the controller, applications must be external endpoints: PHP through an existing PHP-FPM pool (php: {fastcgi: ...}), and everything else throughproxy.scalwsd.serviceruns one process. Use it when you want ScalWS to start and supervise PHP-FPM pools, Node.js or Python processes, or containers itself (managed runtimes).
See ../adaptive-runtime.md and troubleshooting.md.
How does it compare with nginx and Apache?
It covers similar ground with a different design:
- Configuration is one validated YAML file, optionally with one short file per site. It is checked completely before every reload and swapped atomically. A bad reload never replaces the running configuration.
- Application runtimes (PHP-FPM, Node.js, Python) are started and supervised by the server, with readiness checks, crash backoff and draining. With nginx you would add separate process managers.
- Tenancy is built in: cgroup v2 limits and per-tenant accounting
(
scalws-highcpu,scalws-limitram, …). - Operations are built in too: an admin API,
scalwsctl diagnose, the optimizer journal, and Prometheus metrics. - Apache features: there are no Apache modules. Apache’s
.htaccessis supported for a common subset. See below.
Performance. The benchmark of the 1.0.0 release is ../benchmarks/2026-11-12-xeon-1.0.0.md. More reports are in the benchmark reports.
The setup of that run:
- One bare-metal machine with 2× Xeon E5-2650 v2. The server ran on six CPUs of one
socket: the published 1.0.0
.debunderscalws-controller, three instances of two CPUs each, with the service sandbox on (what a new install gets). - Load came from
ohawith 64 connections. 5 runs of 30 s each; the tables show medians. - Two ScalWS columns:
defaults(the package as installed) andown HTTP/1, which turns on both opt-in experimental settings: the own HTTP/1 server and the own upstream client.
The ratios to nginx 1.31.6, with the defaults (own HTTP/1 in parentheses):
| Result | Scenarios |
|---|---|
| Ahead | cache hits 1.54× (1.70×), HTTPS/HTTP/2 small static files 1.29× (1.27×), PHP 1.06× (1.06×) |
| About level | small static files 0.98× (1.03×), 1 MB static files 0.99× (0.99×), Node.js 0.98× (0.96×), Python 0.97× (0.90×) |
| Behind | fixed responses 0.86× (0.93×), proxy 0.83× (0.98×) |
Peak server memory was 109 to 120 MiB for the controller and its three instances together, against 103 to 131 MiB for nginx.
Keep these caveats in mind:
- The gap with the default settings on fixed responses and proxy comes from the default HTTP/1 server and client (hyper’s); the report shows how it was measured.
- These are one machine’s results for these synthetic scenarios, not a general guarantee.
- LiteSpeed Enterprise is not in this run: its trial licence had run out.
Read the report itself before you draw conclusions.
Migration
Can I move my nginx or Apache sites?
Yes. scalwsctl migrate reads the existing configuration (it is never modified) and writes
one ScalWS site file per virtual host:
sudo scalwsctl migrate nginx --dry-run # /etc/nginx/nginx.conf and its includes
sudo scalwsctl migrate nginx
sudo scalwsctl migrate apache # /etc/apache2/apache2.conf or /etc/httpd/conf/httpd.confIt converts these directives:
- server names and aliases, and
www.handling - port-80 hosts that only redirect to HTTPS (into
https_redirect) - document roots and index files
- PHP-FPM
fastcgi_passandSetHandler proxy: proxy_passandProxyPass- redirects
AllowOverride, which becomeshtaccess: true
Everything else is written into the site file as # TODO: lines with the source file and
line. The new files are checked together like a reload, and the whole run is undone if the
check or the reload fails.
Stop nginx or Apache only after scalwsctl site list shows every site. Then let ScalWS take
ports 80 and 443. See ../sites.md.
Do my .htaccess files work?
Yes, for the common directives, if you enable it per application with htaccess: true, or
scalwsctl site add --htaccess. ScalWS reads .htaccess files from the application’s
root down to the requested directory. Edits take effect within 2 seconds.
Supported directives:
- mod_rewrite
RedirectandRedirectMatchRequireandOrder/Allow/Deny<Files>and<FilesMatch>ErrorDocumentandDirectoryIndexHeaderandExpires
Lines that are not supported or are refused are skipped and logged with the file name.
These include php_value, [P] proxy rules, SetHandler, and look-around regular
expressions. See ../OPERATIONS.md and
../adr/0031-htaccess.md.
Applications
Can I run several PHP versions?
Yes, per application.
- Managed pools (
scalwsd.service): set the PHP-FPM binary of each application, for examplephp: {fpm: {binary: /usr/sbin/php-fpm8.2}}. Withoutbinary, ScalWS uses the firstphp-fpmfound onPATH, else the newest versioned one (php-fpm8.4,php-fpm84). - External pools (any setup, and the only option under scalws-controller): point each
site at the socket of the PHP-FPM version it needs, for example
php: unix:/run/php/php8.2-fpm.sockin one site andphp: unix:/run/php/php8.3-fpm.sockin another.
See applications.md.
Are WebSockets supported?
Yes. Proxy runtimes tunnel WebSocket upgrades by default (websocket: true on the proxy).
Managed Node.js applications tunnel them too.
Upgraded connections are limited by server.limits.max_upgraded_connections, and closed
after server.limits.upgraded_idle_timeout without traffic. When an instance drains under
the controller, each tunnel gets a 1001 Going Away close frame, so clients reconnect to an
instance that stays.
Is HTTP/3 supported?
Yes. Every package (.deb, .rpm, .apk) includes HTTP/3, and it is off until you turn
it on: set http3: true on a TLS listener, reload (under scalwsd.service: restart), and
open UDP 443 in the firewall (the package does not). The commands are in
installation.md, the setting in
tls.md.
HTTP/3 works under scalws-controller through its QUIC demux, with the default
listen: inherited. It is refused with listen: reuseport and with scalwsd --reuseport.
Not supported over HTTP/3: WebSockets (they stay on HTTP/1.1 and HTTP/2) and 0-RTT.
A scalwsd built from source without --features http3 refuses the setting:
http3: true needs a build with the `http3` feature (cargo build --features http3)See ../adr/0019-http3.md and ../http3-multi-instance.md.
Can it run containers?
Yes. runtime: {type: container} runs an image with podman (the default) or docker as a
supervised application. Install podman and catatonit on the host. With podman and cgroup
enforcement, containers run under the tenant’s cgroup, so tenant limits include them.
Containers are a managed runtime, which has two consequences:
- they are refused under scalws-controller
- they are refused for tenants that have a Unix
user
See ../OPERATIONS.md and ../adr/0020-container-runtime.md.
Can I run ScalWS in Kubernetes?
Yes. It runs as the web server pod of an application (Kubernetes), as an Ingress controller and as a Gateway API implementation. Multi-node coordination of plain servers is not available; its design is in ../adr/0021-multi-node-control-plane.md.
Can ScalWS replace the web server of cPanel, DirectAdmin or Plesk?
Yes, on the systems each panel supports (see the
panel and system matrix). On a panel server the first install of the package switches the panel’s web server to
ScalWS (scalwsctl panel enable <panel>; install with --panel=none to skip it). ScalWS
then serves the panel’s domains, subdomains and aliases with their PHP versions, webmail and
certificates, and a panel change (a new domain, a renewed certificate, a suspension) reaches
it within seconds. sudo scalwsctl panel disable gives the ports back to the panel’s web
server. See Control panels.
Configuration and operation
Where does the configuration live?
| Path | Content |
|---|---|
/etc/scalws/scalws.yaml | The server configuration (0640 root:scalws, kept on upgrade). |
/etc/scalws/sites.d/*.yaml | One file per site, included by include: sites.d/*.yaml. |
/etc/scalws/controller.yaml | scalws-controller’s configuration. |
/etc/scalws/console/credentials | ScalWS Console accounts (0600). |
/usr/share/doc/scalws/examples/scalws.yaml | The full reference configuration. |
/var/lib/scalws | ACME account and certificates. |
/var/lib/scalws-controller | Configuration generations and instance logs (logs/web-<n>.log). |
/var/lib/scalws-console | Console history, audit log and TLS material. |
/run/scalws/admin.sock | Admin socket of scalwsd.service. Under the controller, each instance has /run/scalws/web-<n>/admin.sock. |
See configuration.md and ../sites.md.
How do I apply a configuration change?
- Run
sudo scalwsctl check. - Reload:
- under scalws-controller:
sudo scalws-controller reload - with
scalwsd.service:sudo scalwsctl reloadorsystemctl reload scalwsd
- under scalws-controller:
A reload that fails keeps the running configuration. scalwsctl rollback (on
scalwsd.service) or the console’s history (under scalws-controller, which has no rollback
command) returns to an earlier configuration. Some changes need a restart; see
configuration.md.
How do I see what is wrong?
Run scalwsctl diagnose, read the logs, and see troubleshooting.md.
Is there a web interface?
Yes: ScalWS Console, on https://<host>:8090. It manages the server through
scalws-controller. The installer creates the user admin with a random password, which is
stored in /etc/scalws/console/credentials. See
../console-operations.md. scalwsd also serves a read-only
dashboard at /dashboard on its loopback metrics listener.
How do I back up a server?
scalwsctl backup /var/backups/scalws-$(date +%F)This copies the configuration and the certificates and keys it references. Document roots
and application data are not included. To restore, run scalwsctl restore <dir> --apply.
Also back up /var/lib/scalws-console if you use the console.
Licence
Under which licence is ScalWS released?
The workspace manifest (Cargo.toml) and the package metadata declare Apache-2.0.