This page lists several tricks to tune your ejabberd and Erlang installation for maximum performance gains. Remark that some of the described options are experimental.

Erlang Ports Limit: ERL_MAX_PORTS
Erlang consumes one port for every connection, either from a client or from another Jabber server. The option ERL_MAX_PORTS limits the number of concurrent connections and can be specified when starting ejabberd:

erl -s ejabberd -env ERL_MAX_PORTS 5000 …

Maximum Number of Erlang Processes: +P
Erlang consumes a lot of lightweight processes. If there is a lot of activity on ejabberd so that the maximum number of proccesses is reached, people will experiment greater latency times. As these processes are implemented in Erlang, and therefore not related to the operating system processes, you do not have to worry about allowing a huge number of them.

erl -s ejabberd +P 250000 …

ERL_FULLSWEEP_AFTER: Maximum number of collections before a forced fullsweep
The ERL_FULLSWEEP_AFTER option shrinks the size of the Erlang process after RAM intensive events. Note that this option may downgrade performance. Hence this option is only interesting on machines that host other services (webserver, mail) on which ejabberd does not receive constant load.

erl -s ejabberd -env ERL_FULLSWEEP_AFTER 0 …

Kernel Polling: +K true

The kernel polling option requires that you have support for it in your kernel. By default, Erlang currently supports kernel polling under FreeBSD, Mac OS X, and Solaris. If you use Linux, check this newspost. Additionaly, you need to enable this feature while compiling Erlang.

Enables or disables the kernel poll functionality if the emulator has kernel poll support. By default the kernel poll; functionality is disabled. If the emulator doesn’t have kernel poll support and the +K flag is passed to the emulator, a warning is issued at startup.

If you meet all requirements, you can enable it in this way:

erl -s ejabberd +K true …

Mnesia Tables to Disk
By default, ejabberd uses Mnesia as its database. In Mnesia you can configure each table in the database to be stored on RAM, on RAM and on disk, or only on disk. You can configure this in the web interface: Nodes -> ‘mynode’ -> DB Management. Modification of this option will consume some memory and CPU time.
Number of Concurrent ETS and Mnesia Tables: ERL_MAX_ETS_TABLES
The number of concurrent ETS and Mnesia tables is limited. When the limit is reached, errors will appear in the logs:

** Too many db tables **

You can safely increase this limit when starting ejabberd. It impacts memory consumption but the difference will be quite small.

OTP-9990 Fix returned error from gen_tcp:accept/1,2 when running out
of ports

The {error, enfile} return value is badly misleading and
confusing for this case, since the Posix ENFILE errno value
has a well-defined meaning that has nothing to do with Erlang
ports. The fix changes the return value to {error,
system_limit}, which is consistent with e.g. various file(3)
functions. inet:format_error/1 has also been updated to
support system_limit in the same manner as
file:format_error/1. (Thanks to Per Hedeland)