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:

ProgramRole
scalwsdThe server.
scalws-controllerRuns several scalwsd instances on shared listening sockets: the Adaptive Runtime.
scalwsctlThe operator CLI.
scalws-consoleThe 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: .rpm from the signed dnf repository;
  • openSUSE Leap 16.0 and 15.6, SLES 16.0 and 15 SP7: the same .rpm and repository, with zypper;
  • Debian 12 and 13, Ubuntu 22.04, 24.04 and 26.04: .deb from the signed apt repository;
  • Alpine Linux 3.24: .apk from 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 several scalwsd instances 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 through proxy.
  • scalwsd.service runs 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 .htaccess is 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 .deb under scalws-controller, three instances of two CPUs each, with the service sandbox on (what a new install gets).
  • Load came from oha with 64 connections. 5 runs of 30 s each; the tables show medians.
  • Two ScalWS columns: defaults (the package as installed) and own 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):

ResultScenarios
Aheadcache hits 1.54× (1.70×), HTTPS/HTTP/2 small static files 1.29× (1.27×), PHP 1.06× (1.06×)
About levelsmall 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×)
Behindfixed 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.conf

It 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_pass and SetHandler proxy:
  • proxy_pass and ProxyPass
  • redirects
  • AllowOverride, which becomes htaccess: 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
  • Redirect and RedirectMatch
  • Require and Order/Allow/Deny
  • <Files> and <FilesMatch>
  • ErrorDocument and DirectoryIndex
  • Header and Expires

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 example php: {fpm: {binary: /usr/sbin/php-fpm8.2}}. Without binary, ScalWS uses the first php-fpm found on PATH, 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.sock in one site and php: unix:/run/php/php8.3-fpm.sock in 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?

PathContent
/etc/scalws/scalws.yamlThe server configuration (0640 root:scalws, kept on upgrade).
/etc/scalws/sites.d/*.yamlOne file per site, included by include: sites.d/*.yaml.
/etc/scalws/controller.yamlscalws-controller’s configuration.
/etc/scalws/console/credentialsScalWS Console accounts (0600).
/usr/share/doc/scalws/examples/scalws.yamlThe full reference configuration.
/var/lib/scalwsACME account and certificates.
/var/lib/scalws-controllerConfiguration generations and instance logs (logs/web-<n>.log).
/var/lib/scalws-consoleConsole history, audit log and TLS material.
/run/scalws/admin.sockAdmin 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?

  1. Run sudo scalwsctl check.
  2. Reload:
    • under scalws-controller: sudo scalws-controller reload
    • with scalwsd.service: sudo scalwsctl reload or systemctl reload scalwsd

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.