pantz.org banner
Apache and other webserver tuning tips
Posted on 07-25-2001 00:13:00 UTC | Updated on 07-25-2001 00:13:00 UTC
Section: /software/apache/ | Permanent Link

Here are some tips to get your Apache webserver running to it's fullest potential. Many of the tips below are generic and apply to any webserver not just Apache.
  1. Upgrade Apache to the newest version. You may want to try Apache 2.X.X. It has worker threaded MPM and other speed enhancements. Benchmark both with your site and see which one is better for you.
  2. In httpd.conf, set "HostNameLookups off" which avoids doing a reverse DNS lookup on every visitor who hits your web site.
  3. In httpd.conf, a good rule of thumb for "MaxClients" is divide your total RAM by 5 megabytes. So a server with 1GB of RAM could probably handle a MaxClients setting of 200. You will have to test this. You might be have to set it higher or lower. Setting it to high would be bad because each Apache process consumes some memory. You can only fit a certain number processes in RAM before the web server begins swap things between RAM and the hard drive in a horrid attempt to make things work. The result is a totally unresponsive server with a thrashing hard disk. Suggestions from Willy Tarreau a 2.4 kernel maintainer in this area are the following. "Observe the average per-process memory usage. Play with the MaxClient parameter to adjust the maximum number of simultaneous processes so that the server never swaps. If there are large differences between processes, it means that some requests produce large data sets, which are a real waste when kept in memory. To solve this, you will need to tell Apache to make its processes die sooner, by playing with the MaxRequestsPerChild value. The higher the value, the higher the memory usage. The lower the value, the higher the CPU usage. Generally, values between 30 and 300 provide best results. Then set the MinSpareServers and MaxSpareServers to values close to MaxClient so that the server does not take too much time forking off new processes when the load comes in."
  4. In httpd.conf, busy websites should set "KeepAliveTimeout" low. Like to 2 seconds. Keeping it low like this gives the client enough time to request all of the files needed for a page without having to open multiple connections, yet will allow Apache to terminate the connection soon enough to be able to handle many more clients than usual. Some people even suggest turning keep-alives off totally. Willy Tarreau a 2.4 kernel maintainer suggests this. He says "First, disable keep-alive. This is the nastiest thing against performance. It was designed at a time sites were running NCSA httpd forked off inetd at every request. All those forks were killing the servers, and keep-alive was a neat solution against this. Right now, things have changed. The servers do not fork at each connection and the cost of each new connection is minimal. Application servers run a limited number of threads or processes, often because of either memory constraints, file descriptor limits or locking overhead. Having a user monopolize a thread for seconds or even minutes doing nothing is pure waste. The server will not use all of its CPU power, will consume insane amounts of memory and users will wait for a connection to be free. If the keep-alive time is too short to maintain the session between two clicks, it is useless. If it is long enough, then it means that the servers will need roughly one process per simultaneous user, not counting the fact that most browsers commonly establish 4 simultaneous sessions! Simply speaking, a site running keep-alive with an Apache-like server has no chance of ever serving more than a few hundreds users at a time."
  5. Serve web graphics (such as jpg,png,gif files) or static files (html,javascript,CSS) from another machine if possible. Try to use a light weight daemon like thttpd for this. Make sure the thttpd version supports keep alives. Set your keep alives low (like 2-3 secs). Doing this will free up Apache for handling the dynamic PHP/Perl stuff if you have it.
  6. Keep your Apache lean and mean. Compile Apache with as few modules as needed. Before compiling (before your run make), edit the /apache_1.x.x/src/Configuration file put a # in front of any AddModule lines you don't need.
  7. If you don't need traffic logs (such as a site that only serves graphics) then use the TransferLog directive in httpd.conf to redirect log entries to /dev/null/
  8. Unless you insist on using .htaccess files to control access to certain directories (there are other ways to do that), in access.conf (or httpd.conf in newer versions of Apache) in the <Directory> section, set "AllowOverride None" so that Apache will not bother looking for an .htaccess file in each directory with each request.
  9. DO NOT serve web pages or write web traffic logs on a networked disk drive (ie. NFS or SAMBA networked disks) -- read and write to local disk drives only. NFS I/O operations incure huge overhead.
  10. DO NOT run Apache (httpd) via the tcpd wrapper in /etc/inetd.conf. Apache can be started when the machine boots by either adding the startup command to your rc.local file or by placing the httpd startup script to your /etc/rc.d/rc3.d/ directory. If you want some mechanism to block requests by IP address then use the "deny from" directive in the Apache's conf files or in a .htacess file.
  11. Avoid using SSI tags if you can.
  12. In CGI scripts:
    • File I/O: Open as few files as possible. Be sure to explicetly close each opened file. Stop reading the file as soon as you found the data you need. Consider structuring data files into fixed-length fields and using read() function to skip ahead to just the part of the file you need to read.
    • Shell Commands: Call shell commands via their full path: eg. use '/bin/date' instead of just `date` in a perl script.
    • If your site is mostly CGI driven, by all means use mod_perl. See http://perl.apache.org/. Mod_perl gives huge Perl speed increases.
    • Perl programmers should study "Effective Perl Programming" by Joseph N. Hall (an Addison Wesley book) and "The Perl Cookbook" by Tom Christiansen (an O'Reilly book) -- two good texts for optimizing perl code. For example, you can preallocate the memory for a hash that will contain 256 items like so: "keys(%names) = 256;".
    • Avoid having more than 1000 files in your web page directory. Organize your web page files into subdirectories. The more files there are in a directory, the longer it takes to locate that file during a request.
  13. Put as few graphics in your web pages as possible. Make sure each image is run through an image compressor.
  14. Stress test your web site. Run Apache Benchmark program (called "ab") in Apache's /bin or /sbin directory. The ab program will simulate heavy traffic by running multiple simultaneous requests on any web page you want for as long as you want then measures the load and response times. Very useful for measuring the effects of your tuning efforts.
  15. The single biggest hardware issue affecting webserver performance is RAM. A webserver should never ever have to swap, swapping increases the latency of each request beyond a point that users consider "fast enough". This causes users to hit stop and reload, further increasing the load. You can, and should, control the MaxClients setting so that your server does not spawn so many children it starts swapping.
  16. I should not have to say this but do not run any extra non-needed processes on the server (X windows,mail,samba, or whatever).
  17. Turn on follow FollowSymLinks (Options -Indexes FollowSymLinks). This saves a few io reads. Apache doesn't have to check if its a symlink, it just goes ahead and traverses. Turn off SymLinksIfOwnerMatch to prevent additional lstat() system calls from being made.
  18. Increase your kernel's tcp/ip write buffers so that most, if not all generated pages can be written without blocking. If the page that Apache generates fits in this buffer, then Apache's write() call returns instantaneously, then Apache hands the socket over to lingerd, logs the hit, and is immediately free for more work. If the page doesn't fit, then write() blocks until the client has acknowledged part of the data, which can take several seconds. To change this, use the SendBufferSize directive from httpd.conf. However, this directive cannot increase the buffer size past the kernel limit. Changing this kernel limit is OS-specific. Under Linux you can set it by echo'ing a larger number (eg. 131072) into /proc/sys/net/core/wmem_max, before starting Apache. If you change wmem_default as well as wmem_max, then the SendBufferSize directive is not needed.
  19. Disable ExtendedStatus unless you're actually debugging. Same goes for mod_info.
  20. Use a reverse proxy cache in front of your server farm. This will return cached contents without hitting the application servers.

Reddit!

Related stories


RSS Feed RSS feed logo

About


3com

3ware

alsa

alsactl

alsamixer

amd

android

apache

areca

arm

ati

auditd

awk

badblocks

bash

bind

bios

bonnie

cable

carp

cat5

cdrom

cellphone

centos

chart

chrome

chromebook

cifs

cisco

cloudera

comcast

commands

comodo

compiz-fusion

corsair

cpufreq

cpufrequtils

cpuspeed

cron

crontab

crossover

cu

cups

cvs

database

dbus

dd

dd_rescue

ddclient

debian

decimal

dhclient

dhcp

diagnostic

diskexplorer

disks

dkim

dns

dos

dovecot

drac

dsniff

dvdauthor

e-mail

echo

editor

emerald

ethernet

expect

ext3

ext4

fat32

fedora

fetchmail

fiber

filesystems

firefox

firewall

flac

flexlm

floppy

flowtools

fonts

format

freebsd

ftp

gdm

gmail

gnome

google

greasemonkey

greylisting

growisofs

grub

hacking

hadoop

harddrive

hba

hex

hfsc

html

html5

http

https

hulu

idl

ie

ilo

intel

ios

iperf

ipmi

iptables

ipv6

irix

javascript

kde

kernel

kickstart

kmail

kprinter

krecord

kubuntu

kvm

lame

ldap

linux

logfile

lp

lpq

lpr

maradns

matlab

memory

mencoder

mhdd

mkinitrd

mkisofs

moinmoin

motherboard

mouse

movemail

mplayer

multitail

mutt

myodbc

mysql

mythtv

nagios

nameserver

netflix

netflow

nginx

nic

ntfs

ntp

nvidia

odbc

openbsd

openntpd

openoffice

openssh

openssl

openvpn

opteron

parted

partimage

patch

perl

pf

pfflowd

pfsync

photorec

php

pop3

pop3s

ports

postfix

power

procmail

proftpd

proxy

pulseaudio

putty

pxe

python

qemu

r-studio

raid

recovery

redhat

router

rpc

rsync

ruby

saltstack

samba

schedule

screen

scsi

seagate

seatools

sed

sendmail

sgi

shell

siw

smtp

snort

solaris

soundcard

sox

spam

spamd

spf

sql

sqlite

squid

srs

ssh

ssh.com

ssl

su

subnet

subversion

sudo

sun

supermicro

switches

symbols

syslinux

syslog

systemrescuecd

t1

tcpip

tcpwrappers

telnet

terminal

testdisk

tftp

thttpd

thunderbird

timezone

ting

tls

tools

tr

trac

tuning

tunnel

ubuntu

unbound

vi

vpn

wget

wiki

windows

windowsxp

wireless

wpa_supplicant

x

xauth

xfree86

xfs

xinearama

xmms

youtube

zdump

zeromq

zic

zlib