Sizing profiles
An Elpan server runs on hosts from 3 GB of RAM up. What suits a 64 GB host (eight panel workers, fifty PHP threads, an AI agent always running) does not fit on a 4 GB one, and a memory limit given as a percentage of RAM becomes too small there. The host's profile decides these values in one place.
By default the profile follows the RAM the kernel sees (MemTotal, a
little less than the size the host was sold as):
| Profile | MemTotal | Typical host |
|---|---|---|
| tiny | below 3.25 GiB | 3 GB |
| small | below 6 GiB | 4 GB |
| standard | below 24 GiB | 8 to 16 GB |
| large | 24 GiB and more | 32 GB and more |
install.sh picks the profile the same way; --profile <name> fixes one
and writes it to /etc/elpan/sizing.conf, so it holds whatever the RAM
says later. The installer refuses a host below 2.5 GiB: the core alone
does not fit a 2 GB host. ClamAV needs an 8 GB host and refuses a first
install below 7 GiB (Virus scanning).
What each profile sets
| tiny | small | standard | large | |
|---|---|---|---|---|
| Panel workers, general + async-only | 1 + 1 | 2 + 1 | 6 + 2 | 8 + 3 |
| Panel PHP threads, start / max | 2 / 8 | 4 / 16 | 16 / 50 | 16 / 50 |
| rspamd normal workers per instance | 1 | 1 | one per CPU | one per CPU |
| AI agent | starts on demand, exits after 15 min idle | as tiny | always running | always running |
| Memory cap of a new account | 768 MiB | 1 GiB | 2 GiB | 2 GiB |
| zram swap | on | on | off | off |
| Resolver caches, message / RRset | 8m / 16m | 16m / 32m | 64m / 128m | 64m / 128m |
| Accounts' MariaDB buffer pool | 32M | 64M | the image's (128M) | the image's (128M) |
| Telemetry agent's memory limit | 160 MiB | 256 MiB | 400 MiB | 400 MiB |
The memory cap is what a new account gets; existing accounts keep theirs (Limits).
On every profile, memory floors hold for the units whose percentage limits
would be too small on a small host (the panel's scheduler, workers and web
side, each Apache instance, the resolver, the database, the two rspamd
instances), and the database, DNS, the resolver, the panel and mail run
with OOMScoreAdjust=-500: when the host runs out of memory, the kernel
kills an account's process before the platform's.
What tiny leaves out
Four components are recommended by the elpan package rather than
required. A default install brings them; install.sh --profile tiny
installs without them (dnf install --setopt=install_weak_deps=False elpan), and any of them can be removed from a larger host too. The rest
of the platform works without each, and the panel hides and refuses what
needs a component that is absent.
| Package | Without it |
|---|---|
elpan-ai-agent | No AI assistant. |
elpan-list | No mailing lists, and no mail is routed to a list daemon. |
elpan-haproxy | No HTTP/3: sites are served over HTTP/1.1 and HTTP/2, the edge advertises no h3, the firewall does not open UDP/443. |
elpan-ftp | No FTP, FTPS or SFTP for the accounts; the firewall does not open their ports. |
Adding or removing one later is one dnf install or dnf remove; the
firewall and the edge follow by themselves.
Hosted mail, the panel, DNS, the database and the web servers. A host that cannot hold them is below the floor.
Change the profile
/etc/elpan/sizing.conf holds KEY=value lines; it ships with everything
commented out. profile= fixes the profile (auto, the default, picks
from the RAM), and any value of the profile can be overridden on top:
panel_workers, panel_async_workers, panel_threads,
panel_max_threads, rspamd_normal_workers, ai_agent_idle_exit (seconds;
0 runs the agent from boot), account_memory_default, zram,
resolver_msg_cache, resolver_rrset_cache, userdb_mariadb_buffer_pool
and telemetry_memory_limit_mib. A 4 GB host with more panel work than
mail:
profile=small
panel_workers=3
Then apply it. elpan-sizing is its own root-only command, not an
elpanctl command:
elpan-sizing show
elpan-sizing show --units
elpan-sizing apply
show prints the values in force without writing anything; --units
adds the systemd drop-ins they produce. apply writes
/run/elpan/sizing.env, reloads systemd (the memory limits take effect at
once), stops the panel workers the pool no longer wants and starts those
it now wants, and starts zram when the profile turns it on. It restarts
nothing that carries mail or serves pages, and ends by listing the
services that read their value only at start (the panel's web side for
its threads, the rspamd instances, the resolver, the AI agent, the
telemetry agent): restart those when convenient. Turning zram off takes
effect at the next boot.
A systemd generator writes the profile's values as
40-elpan-sizing.conf drop-ins at every boot and daemon-reload. A
drop-in of your own in /etc/systemd/system/<unit>.d/ whose name sorts
after it (override.conf, what systemctl edit writes) wins, and a mask
wins over any worker link the generator writes.
The man pages elpan(8) and elpan-sizing(8) on the server hold the
full tables, the memory floors and every key of sizing.conf.