Panellicense

WHM packages and feature lists: structure tiered hosting plans

How to build cPanel packages and feature lists that map cleanly to tiered hosting plans — quotas, LVE, defaults, and the failure modes when wiring into Blesta or WHMCS.

8 min readUpdated 2026-05-24whm · cpanel · packages · feature-lists
schema: HowToschema: FAQPage

Packages and feature lists are the two primitives cPanel gives you to differentiate plans. Get them right once and provisioning, upgrades, and renewals become declarative — change the package, every account on it inherits the new limits. Get them wrong and you end up patching individual accounts by hand for years.

This article covers the model, a tier layout that works for most shared and reseller hosts, and the rough edges that surprise people the first time they wire packages up to a billing platform.

What packages and feature lists actually do

A package is a quota and infrastructure profile — disk quota, bandwidth quota, addon domain count, MySQL database count, FTP and email account counts, mailing list count, dedicated IP toggle, shell access, CGI access, theme, language, locale, and (when CloudLinux is installed) the LVE limits referenced by a package extension. WHM stores these under /var/cpanel/packages/<name> as flat key=value files.

A feature list is the UI surface for that account in cPanel — which icons and links the user sees. WHM stores these under /var/cpanel/features/<name>. Hiding a feature does not disable the underlying service; a determined user can still hit the cPanel API directly. Feature lists are for the cPanel UI only — security boundaries belong in the package (quotas, shell access, CGI) or at the system level.

Packages and feature lists are independent. Multiple packages can reference the same feature list (e.g., all shared tiers can share a shared-default feature list and differ only in quotas), and you can override the feature list per account from WHM > Modify an Account.

A tier layout that scales

Most shared hosts can model their entire catalogue with three packages and one feature list. Start there and only add more when a real product reason appears.

TierDiskBandwidthAdd-on domainsMySQL DBsLVE CPULVE EPPMEM
Starter10 GB100 GB15100% (1 core)201 GB
Pro50 GB500 GB1025200%402 GB
Business200 GBunmeteredunlimitedunlimited400%804 GB

A few notes on this layout:

  • "Unlimited" in WHM means 0. Set the field to 0 and cPanel treats it as unmetered. Most billing platforms display "unlimited" to the customer but pass 0 over the wire.
  • LVE values are per-account, not per-cPanel user. A reseller's child accounts each get their own LVE; the reseller package itself does not need higher limits unless you sell reseller-tier hosting separately.
  • Bandwidth quotas in WHM are advisory. cPanel will not block a site over quota; it flags the account in WHM > List Accounts and the bandwidth usage report. If you need hard cutoffs, write a WHM standardized hook on the Whostmgr::Accounts::bwlimit event.

For the LVE specifics see CloudLinux LVE tuning — the defaults above are conservative starting points for a 4-vCPU, 16 GB shared node, not target values.

Build the package once, version the file

Create the package from WHM > Packages > Add a Package, then dump it to disk and put it in git:

cat /var/cpanel/packages/starter

You should see a flat key=value file with QUOTA, BWLIMIT, MAXADDON, MAXSQL, MAXPOP, MAXFTP, MAXSUB, MAXLST, MAXPARK, IP, CGI, HASSHELL, CPMOD, and so on. Commit these to a repository on the server. Every package change goes through git → cp file /var/cpanel/packages/<name>whmapi1 verify_users_in_conf to validate. When you onboard a new node, copy the directory across instead of clicking through WHM.

For LVE limits inside the package, edit the _PACKAGE_EXTENSIONS field to reference a CloudLinux extension file. See CloudLinux reseller limits in WHM for the syntax — the extension model is the only sane way to keep LVE in the package rather than overriding per-account after creation.

Build the feature list

The default feature list (named default) enables almost everything. Clone it and disable features you do not want exposed in the shared tier:

  • File Manager > Java Upload — obsolete, dead weight
  • Logs > Awstats — heavy on busy accounts, prefer the built-in dashboard
  • Software > Perl Modules and PHP Pear Packages — confusing for shared users, often broken under CloudLinux's PHP Selector
  • Email > Calendars and Contacts (CalDAV/CardDAV) — only enable if you actually run the CCS service
  • Advanced > Cron Jobs — leave on, but pair with LVE cron throttling to stop runaway crons
  • Preferences > Change Style / Change Language — harmless, leave on

Wire packages into Blesta or WHMCS

Both billing platforms model the cPanel package as a string field on the product. The provisioning module passes that string to the WHM createacct API, which fails loudly if the package does not exist on every server in the cluster. Two failure modes hit nearly every host eventually:

  1. Package exists on the primary server but not on a failover node. Treat /var/cpanel/packages/ as configuration, not state. Rsync the directory across the cluster after every change, or run it from a systemd timer.
  2. Package name changes between renewal cycles. A customer on starter-2023 will not auto-upgrade to starter-2025 just because you renamed the product in billing. Either keep the old package alive forever, or run a whmapi1 changepackage migration in a maintenance window. See Blesta cPanel provisioning setup for the module-side mapping.

If you sell reseller hosting, the package's MAXSUB, MAXPOP, and other count fields cap what the reseller can create — but you also need a separate ACL list controlling what WHM features the reseller can use. Covered in WHM reseller accounts and ACLs.

Common pitfalls

  • Editing the default package. It is the fallback for any account created without an explicit package and for any account whose package is later deleted. Leave it at conservative defaults and never reference it from your billing platform.
  • Setting "Dedicated IP" in the package. This is a one-time allocation, not a renewable resource — when the account is created cPanel grabs an IP from the shared pool. Removing the flag later does not return the IP. Manage dedicated IPs as a billing add-on, not a package attribute.
  • Mixing shell access into a shared tier. If even one shared tier has HASSHELL=y, CageFS containment is materially weaker for that tier. Keep shell access in a separate package (typically the Business or Reseller tier) and use jailshell rather than bash — see the cPanel shell access documentation for the chsh flow.
  • Forgetting that new WHM versions add fields you didn't set. After an update, run whmapi1 listpkgs --output=jsonpretty | jq and look for any package missing the keys present in default. Backfill them explicitly so the next update doesn't introduce drift.
What's the difference between a cPanel package and a feature list?+
Packages control quotas, infrastructure, and LVE limits — what the account can actually do on the server. Feature lists control which icons appear in cPanel. Hiding a feature does not stop a user from calling the underlying API; for security boundaries use the package or system-level controls.
Can I change a package without affecting existing accounts on it?+
No. cPanel packages are referenced by name from each account's user file. Editing a package updates every account assigned to it on the next quota or LVE recalculation. If you only want to move specific accounts, create a new package and use 'whmapi1 changepackage' on those accounts.
How do I export cPanel packages between servers?+
Copy /var/cpanel/packages/ and /var/cpanel/features/ from the source to the destination, then run 'whmapi1 verify_users_in_conf' on the destination. There is no built-in cluster sync — most hosts use rsync in a systemd timer or a config-management tool like Ansible.
Does deleting a package break accounts assigned to it?+
Accounts continue to function, but their package field reverts to 'default' on the next modification call from WHM or the API. Always migrate accounts off with 'whmapi1 changepackage' before deleting.
Can I set CloudLinux LVE limits inside a cPanel package?+
Yes, via the _PACKAGE_EXTENSIONS field, which references a separate extension file containing the CPU, EP, IO, and PMEM limits. The extension stays in sync with the package across account creation and migration.
What is 'unlimited' in WHM actually set to?+
Zero. WHM treats 0 as unmetered for disk quota, bandwidth, addon domains, MySQL databases, email accounts, and most other count fields. Billing platforms display 'unlimited' to customers but pass 0 to the createacct API.

Next steps

For volume cPanel licensing across multiple shared nodes, see cPanel license tiers explained or contact us. Activating a cPanel license takes about ten minutes end-to-end.

Switch in an afternoon

Switch from your current reseller — free.

We migrate active cPanel, Plesk, LiteSpeed and CloudLinux licenses from any reseller. We prorate the first month so you never pay twice, and your customers see zero downtime during the swap.