Community  »  Applications  »  Webmail

Horde Groupware Webmail Edition Performance Guide

Contact: horde@lists.horde.org

Some tips on performance tuning systems for Horde Groupware Webmail Edition. This does not cover hardware tuning or even low level system (network, filesystem, etc) tuning.

Don't apply the following tuning hints blindly. Test your applications before and after the changes under the conditions that are important for you. For some people it's more important to make them as fast as possible for a small user base, others require the applications to scale well under a high load. Some of these hints might even make the applications slower under certain conditions or using a certain hardware.

Linux Tuning

  • Recompile RPMS for your architecture (e.g. i586, i686, athlon, etc). This applies most to your Apache, PHP, IMAP, and POP3 packages.

Webserver/PHP tuning

  • Consider a PHP accelerator program. See for example The Zend Performance Suite, the Alternative PHP Cache, eAccelerator, or XCache. These accelerators speed up access by caching the compiled PHP code, eliminating the need to recompile the code for every single page load. This is probably the easiest way to improve the performance of Horde Groupware Webmail Edition. See Autoloading further down to get even more out of some of those accelerators.

  • Enable PHP output compression in the Horde configuration. Do not enable compression in the PHP configuration (i.e. in php.ini), because certain scripts don't work well with compression and Horde Groupware Webmail Edition takes care of disabling compression conditionally.

  • Keep the include path defined in php.ini as short as possible, with the most frequently used library paths first. You don't need to include the local directory . because Horde Groupware Webmail Edition always uses full paths instead of relative paths.

  • Use an optimized php.ini: start with php.ini-recommended in your PHP dsitribution.

  • Don't run PHP session garbage collection too often if using a slow storage medium (like SQL). (See session.gc_probability in php.ini)

  • If you have a large number of sessions and are using PHP's default file based session handler, consider storing them in hashed directory levels. (See session.save_path at http://www.php.net/session)

  • Consider using a faster storage medium for sessions, such as a tmpfs (if storing sessions locally) or memcache (for storing session information that can be accessed by multiple servers).

  • Only load as many Apache and PHP extensions as needed (to reduce memory usage).

  • Use statically compiled Apache modules, including the PHP module.

  • Use compiler optimizations (--prefer-non-pic, -O3, -march -mcpu, -msse, -mmmx, -mfpmath=sse, etc.)

  • If using SSL with a large site, consider a hardware SSL accelerator.

  • Use shared memory for the Apache SSL cache if possible.

  • To improve caching of static content if accessing Apache SSL with Internet Explorer, try setting longer expiration periods:

    ExpiresActive On
    ExpiresByType image/png "now plus 1 month"
    ExpiresByType image/gif "now plus 1 month"
    ExpiresByType text/javascript "now plus 1 month"
    ExpiresByType application/x-javascript "now plus 1 month"
    ExpiresByType text/css "now plus 1 month"
    

    Note

    You must compile the mod_expires extension into Apache in order to use these directives.

    Warning

    This might cause problems if you upgrade Horde Groupware Webmail Edition and the users' browsers still use the old file versions.

  • Disable DNS lookups in your Apache logging, or use a caching DNS server on the web server host.

    Horde itself will run DNS queries too, so make sure your DNS resolution works correctly and fast.

  • Enable Apache keepalives.

  • You can configure Horde to serve all images, style sheets and/or static javascript files from a different server. This could be a very lightweight server without PHP (and other CGI modules) builtin. If using SSL to serve all pages, the images/js server will also have to serve SSL content or else browsers will complain about non-secure content in a secure page. Since this server does not need to handle dynamic content, it would be wise to use a high-performance server with low memory and/or system resource requirements (this IBM Article can provide further information). You need to set the themesuri and/or jsuri parameters in config/registry.php for all applications and copy all themes and/or js directories in the same directory layout to the other server.

  • Your webserver should use Expires headers to make sure static content can be cached on the user's browser. For example, to make lighttpd set an expiration date on all graphics, javascript files, and stylesheets, add the following to lighttpd.conf:

    $HTTP["url"] =~ "\.(jpg|gif|png|js|css)$" {
        expire.url = ( "" => "access 1 months" )
    }
    
  • Enable caching in Horde Groupware. Several applications make heavy use of caching and, if enabled, you will see a significant increase in performance.

  • Enable caching/compression of javascript and CSS. See Yahoo's Analysis which concludes that "[r]educing the number of HTTP requests has the biggest impact on reducing response time". Caching via filesystem is HIGHLY RECOMMENDED: it is also the only way of caching that reliably works on all browsers. Caching can also be done via horde caching, but the cache-busters used to generate unique URLs when the cached content changes do not work 100% reliably across all browsers.

  • It is highly recommended to install the lzf PECL module to activate compression for certain Horde data (especially in IMP). lzf is a tiny module that does real-time compression. The lzf documentation states that on modern CPUs, compression is as fast as an (unoptimized) memcpy action, making the compression essentially 'free' when compared to uncompressed data. lzf can be installed via PECL (see INSTALL).

Sending Mail

  • Generally using a local sendmail command to send mail will result in better peformance than using a SMTP connection.
  • Some MTA servers may be faster or more efficient than others. Consider switching to a faster format if needed.

IMAP tuning

  • Consider an IMAP proxy to allow persistent connections.

    imapproxy is HIGHLY RECOMMENDED - especially versions 1.2.7rc1 and greater which contains features used internally by Horde Groupware Webmail Edition to speed up access to the remote server.

    NOTE: if your installation connects to multiple imapproxy instances, you MUST configure your Horde Groupware Webmail Edition installation to persistently connect to a single backend over the course of a session. If this is not possible, you must remove support for imapproxy's advanced features by adding 'XIMAPPROXY' to the 'capability_ignore' parameter in your local configuration.

  • Use an IMAP server that supports CONDSTORE (RFC 4551) and/or QRESYNC (RFC 5162).

    These extensions are required to properly cache data and to properly keep the dynamic display synchronized. It is impossible to do otherwise, and the UI experience will be limited without these extensions. Additionally, if these IMAP extensions are available, Horde Groupware Webmail Edition is able to cache servers which signficantly saves on client/server IMAP interactions.

    Technical information can be found here:

    http://lists.horde.org/archives/imp/Week-of-Mon-20110523/052285.html

  • Some IMAP servers perform better than others. The Horde Project recommends either Cyrus or Dovecot as these servers are actively developed, implement advanced IMAP protocols, and use server-side caching to speed performance.

  • Consider switching to a faster mailbox storage format if needed. This may also require switching the underlying filesystem.

    Further information can be found here:

    http://wiki2.dovecot.org/MailboxFormat

  • Follow the IMAP servers' performance hints:

PostgreSQL tuning

  • Do a VACUUM command periodically to tune your database.
  • Increase shared_buffers and sort_mem memory settings.
  • If web server and database is on the same unix host, use unix sockets instead of network connections for database access.

MySQL tuning

  • If web server and database is on the same unix host, use unix sockets instead of network connections for database access.

  • Enable mysql query cache if you have sufficient RAM. Edit your my.cnf file and add the following to the [mysqld] section (change the memory size to meet your needs):

    set-variable = query_cache_size=128M
    

Horde tuning

Autoloading

  • Horde Groupware Webmail Edition automatically loads PHP source files on demand which relies on the PHP autoloading feature introduced with PHP 5 and the Horde Autoloader library. Both allow to limit the set of source code files pulled into the system to the minimal amount required to answer the current request. This saves memory and time but at the same time the Autoloader library has to map each class name to the path of the corresponding PHP file that holds the class definition. This procedure is expensive and can slow the system down. Fortunately the mapping is fixed unless files are added or removed which usually only happens during an upgrade.

    Thus Autoloading is amenable to caching and an easy way to improve the performance of the Horde Autoloader library, is to install the Autoloader Cache extension:

    pear install horde/horde_autoloader_cache
    

    This library is not installed by default because it will unconditionally use any of the following cache backends and does not allow for any further configuration: Alternative PHP Cache, XCache, eAccelerator, or the local temporary filesystem.

    It also doesn't detect the rare case when the file paths of any PHP class in Horde changes. In this case you either need to use the provided script to empty the cache:

    horde-autoloader-cache-prune
    

    or empty the cache manually, e.g. by restarting the web server or deleting the cache file from the temporary directory.

VFS

  • Configure Horde Groupware Webmail Edition to use a VFS filesystem-based backend. Presently, the SQL VFS backend uses ~5 times the amount of memory as a filesystem-based backend, so users attaching larger files to outgoing mail messages may cause PHP out-of-memory errors to occur.

Application tuning

  • Some applications contain advanced features that might have a certain impact on the performance. These features can usually be turned off in the application's configuration and are explicitly described as being a performance hit in the configuration web frontend.

Webmail tuning

  • Horde Groupware Webmail Edition can use persistent caching on the server side to store information about user's messages. This results in much reduced mail server traffic and requires the server to parse the structure of every message only once. The tradeoff is your cache backend must be able to handle the potentially large amounts of cached data this option will produce. However, cache storage is potentially cheap when compared to the performance gained by using caching.

    If CONDSTORE/QRESYNC is available on the server, IMAP flags can be cached.

    To use this caching, you must have a Cache System configured in Horde Groupware Webmail Edition's Administration/Configuration screen and have the relevant settings enabled in the Mail module's configuration screen (Administration/Configuration/Mail/Mailbox).