===================================================
 Horde Kolab Edition Performance Guide
===================================================

:Contact: horde@lists.horde.org

.. contents:: Contents


Some tips on performance tuning systems for Horde Kolab 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 Kolab Edition**.

* 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 Kolab 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 Kolab 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.

* Enable Apache keepalives.

* You can configure Horde Kolab Edition 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. Good lightweight servers that support SSL include lighttpd_ and
  Hiawatha_. If using a Horde Kolab Edition installation that
  doesn't use SSL (or only uses SSL for logins), good choices for servers
  include thttpd_ or Boa_. 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).

.. _`The Zend Performance Suite`: http://www.zend.com/horde.php
.. _`Alternative PHP Cache`: http://www.php.net/apc
.. _eAccelerator: http://eaccelerator.net/
.. _XCache: http://xcache.lighttpd.net/
.. _`lighttpd`: http://www.lighttpd.net/
.. _`Hiawatha`: http://hiawatha.leisink.org/
.. _`thttpd`: http://www.acme.com/software/thttpd/
.. _`Boa`: http://www.boa.org/
.. _`Yahoo's Analysis`: http://yuiblog.com/blog/2006/11/28/performance-research-part-1/


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 for more persistent connections.  Some IMAP proxies
  are up-imapproxy_ and Perdition_.  To make sense, the proxy should be
  installed on the server running Horde Kolab Edition, and this
  server needs enough CPU power to handle the additional load.  If using
  up-imapproxy, make sure SELECT caching is turned off.

* Some IMAP servers (or IMAP mailbox store formats) perform better than
  others.  Consider switching to a faster format if needed.

* Follow the IMAP servers' performance hints:

  - Cyrus: http://asg.web.cmu.edu/cyrus/download/imapd/install-perf.html
  - Dovecot: http://wiki.dovecot.org/PerformanceTuning

.. _up-imapproxy: http://www.imapproxy.org/
.. _Perdition: http://www.vergenet.net/linux/perdition/


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


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 Kolab Edition can use persistent caching on the server
  side to store information about user's messages.  This results in much
  reduced IMAP 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.

  To use this caching, you must have a ``Cache System`` configured in Horde's
  ``Administration/Setup`` screen and have the relevant settings enabled in
  IMP's setup screen (``Administration/Setup/Webmail/Mailbox and Fetchmail``.
