Load Testing a Home Internet Server

The “new” basement server hosting dalescott.net has been rock solid now for a couple days, so it was time for some load testing.

The server is an HP M7690Y media center with Intel Core2 2.40GHz CPU, 3G of RAM, and connected to the internet through a residential “internet-over-cable” service. I’m using the Apache pre-fork MPM with default configuration (no need to tune for reduced RAM with 3GB).


I ran LoadImpact’s free account-required 50 user / 12 minute test, and monitored server resources while the test was running.

top/htop while while running LoadImpact test

CPU utilization spiked to maximum, but never ran out of RAM, let alone getting into the cache. Increased CPU performance means that http requests aren’t getting queued, resulting in less demand on RAM compared to a single-core CPU with 512MB RAM.

Here is the test summary. The number of VUs, or virtual users, is on the left Y-axis, the VU Page Load Time is on the right Y-axis, and time is on the X-axis.

LoadImpact results


Next, I checked to see if WebPageTest liked the new server any better than the old one.

WegPageTest results


Compared to previous testing on the 1 CPU 512MB vps, the First Byte Time has gone from an F to a D. However, it’s not clear why Compress Images has gone from a B to a D, the servers should have identical WordPress, Apache and PHP configurations.

ISP Speed Test

Finally, I ran my ISP’s Speed Test.

ISP Speed Test

I ran the test from my laptop on the LAN side of a Hitron DOCSIS (“internet over cable”) interface adapter, but the results should apply equally to the server. The server is also connected to the Hitron, but configured on a pass-through to get its own external IP address via DHCP from my ISP.


Performance from the new server far exceeds that of the previous minimal vps droplet, but that is to be expected given the hardware performance. However, it seems performance on a residential ISP service is much more variable than the vps was. I ran the LoadImpact test several times from mid-morning to mid-afternoon, with worst-case VU load times in tens of seconds occurring after lunch with 40+ VUs. Obviously there will need to be changes again when the site starts drawing significant traffic.

FreeBSD and Apache on a $5/month DigitalOcean Droplet VPS

I recently merged dalescott.net and swiftconstructioncompany.net onto a $5/month DigitalOcean droplet (512MB Memory, 1 Core Processor, 20GB SSD Disk, and
1TB Transfer). Afterwards, I wanted to get a measure of server performance. A quick web search came up with some candidates:

  1. Load Impact, claiming “The leading on-demand load and performance testing software-as-a-service.”
  2. Neustar, who claims “We started it all. And we continue to shape the industry.”
  3. WebPageTest, created by AOL for internal use before being open-sourced and now primarily developed and supported by Google.

There are more, but these will be enough to get started with. I had wanted to include Blitz.io, which was referenced in a blog post by Ryan Frankell on using Apache on a small DigitalOcean droplet . However, I couldn’t find any free evaluation capability, and Blitz’s demo is hard-coded to use a Blitz demo site, which eliminated Blitz from consideration.

Tuning Apache

The first step was to tune Apache. 512MB of RAM is low by server standards and also Apache’s default configuration. Some tuning is needed to keep Apache operating in the available RAM, otherwise Apache will gradually consume everything, including swap, and eventually the kernel will start thrashing.


KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5

The FreeBSD apache24 port already sets these as defaults in /usr/local/etc/apache24/extra/httpd-default.conf  (the default MaxKeepAliveRequests is even lower than the recommended 200).



Although Event is reportedly the default MPM in Apache 2.4, Prefork is still the default on FreeBSD 10.x for compatibility with non-thread-safe php/perl/python modules.

MaxRequestWorkers and MaxConnectionsPerChild must be lowered in /usr/local/etc/apache24/extra/httpd-mpm.conf, and the Include line for httpd-mpm.conf in usr/local/etc/apache24/httpd.conf must be un-commented (and Apache restarted).

# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: min number of server processes which are kept spare
# MaxSpareServers: max number of server processes which are kept spare
# MaxRequestWorkers: max number of server processes allowed to start
# MaxConnectionsPerChild: max num of connections a server process serves
# before terminating
#<IfModule mpm_prefork_module>
#    StartServers 5
#    MinSpareServers 5
#    MaxSpareServers 10
#    MaxRequestWorkers 250
#    MaxConnectionsPerChild 0

<IfModule mpm_prefork_module>
 StartServers 5
 MinSpareServers 5
 MaxSpareServers 10
# reduce max number of server processes to not exceed physical memory
# called "MaxClients" prior to v2.3.13 (MaxClients is still supported)
# - uses cache under load when 25
# - appears to not use cache under load when 12
 MaxRequestWorkers 12
# reduce max connections per child to avoid idle processes from holding onto memory
# - memory use seems stable when 200 but could be lower than optimal
# MaxConnectionsPerChild 350
 MaxConnectionsPerChild 200


Load Impact

I first used the free no-login-required test, which loads 25 Virtual Users in 5 minutes, but by creating a free login profile you are allowed 5 (QTY)-five minute tests (executions) up to 100 VUs per month. Here are the results of the Load Impact test with Apache tuned, showing load times in the low seconds for up to 15 users. This can likely be further improved, but the server is stable and adequate for the expected amount of traffic.

2016-08-12 LoadImpact test results



Neustar queued three servers for testing, but the Washington server never ran. Here are the results when I gave up waiting.



WebPageTest concentrates on measuring how fast it takes a page to load, and gives lots of information for digging into the load times for each aspect of the page. I was looking for more of a general load or stress test to see if my server will fail under load, but the information can be valuable none the less.


Server Performance

Here are the result of top while the Load Impact no-login (20 VU) test is running. Although the server can by no means be considered fast, it also is not exhausting swap and stalling. I’m pleased for now, and will be back to review when time permits.



Build a FreeBSD-10 server with Apache, MariaDB, and php using binary packages

It has been traditional for a FreeBSD sysadmin to compile applications from source in the ports tree, but binary packages can now be used for basic needs which saves significant time.

This server is being built for Maestro development. It will be running on my Windows 10 laptop using VirtualBox, although it could just as easily run on bare metal.

Features will include:

  • FreeBSD 10.1-RELEASE Unix-like operating system.
  • Apache 2.4, MariaDB 5.5 and PHP 5.6 AMP stack (using mod_php).
  • Samba 3.6 and rsync (Samba to access Windows file shares as well as share the Maestro file vault to Windows clients, and rsync to synchronize the Maestro file vault to a Windows share).
  • A variety of handy utilities, including git and mdbtools (to import from a Parts&Vendors Jet4 mdb database file).

This post does not include a mail server or gateway, and also will be updated shortly to include infrastructure requirements for Maestro testing (using PHPUnit with Selenium). Maestro is being updated first to use Composer following current best practices, with Composer being used to install PHPUnit. 

Create Virtual Server

Create a new vm and specify BSD OS (FreeBSD) with 256 MB memory and a 20G system drive. Configure the network interface for NAT mode, and forward the IP ports being used from the vm (client) to Windows (host).

HTTPS (secure HTTP) will not be configured at this time. However, it will become the norm in the future.

ssh               host port 2222        client port 22
http              host port 8880        client port 80
mysql-tcp         host port 3336        client port 3306
mysql-udp         host port 3336        client port 3306

Download FreeBSD-10.2-RELEASE-i386.dvd1.iso from FreeBSD.org, boot the vm from the ISO, and perform a standard install (use 64-bit if you prefer, I still tend to create 32-bit virtual machines because I know it works and don’t need the extra address space). I will simply use root to admin the server, and will not create additional users during the install.

After installing the OS and rebooting into the new system, update the system to the latest release if you used an older install ISO, and also update the packages system (pkg, or pkgng in older references).

# freebsd-update upgrade -r 10.2-RELEASE
# freebsd-update install

# pkg update

Edit /etc/rc.conf to specify the hostname and DHCP network config.


# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable

Edit /etc/hosts so that necessary hostnames resolve ( is the default IP address for a VirtualBox vm, substitute if necessary).

I am requiring that the vm never be exposed to the internet by using hostname swiftconstructioncompany.net. A different hostname must be used if the vm will be exposed to the internet.

::1         localhost localhost.local   localhost localhost.local   localhost localhost.swiftconstructioncompany.net   whizzer.swiftconstructioncompany.net whizzer   whizzer.swiftconstructioncompany.net.

Edit /etc/ssh/sshd_config to permit remote root login only, and only using an ssh key (a password can still be used at the console if necessary).

AllowUsers root
PermitRootLogin YES
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM yes

Copy root‘s public ssh key to /root/.ssh/authorized_keys and restart sshd.

# service sshd restart

Install Apache and php

The venerated Apache with mod_php will be used, and installing mod_php will first install Apache 2.x as a dependency.

# pkg install mod_php5

Edit /usr/local/etc/apache24/httpd.conf to specify the server name and when to use php.

# ServerAdmin: Your address, where problems with the server should be
ServerAdmin admin@whizzer.swiftconstructioncompany.net

# ServerName gives the name and port that the server uses to identify itself.
ServerName www.swiftconstructioncompany.net:80

# as per message from pkg install mod_php56
<FilesMatch "\.php$">
    SetHandler application/x-httpd-php
<FilesMatch "\.phps$">
    SetHandler application/x-httpd-php-source

Edit /etc/rc.conf to start Apache at boot:


Use the provided production PHP configuration file (or use the production file to suppress warnings and errors).

# cp /usr/local/etc/php.ini-development /usr/local/etc/php.ini

Edit php.ini to specify the server timezone.

# add default date timezone
date.timezone = "America/Edmonton"

# uncomment session.save_path
session.save_path = "/tmp"

Confirm that the PHP comnmand line tools were installed correctly (no errors means things are good).

# php -r "phpinfo ( );"

Test the Apache configuration and start Apache.

# service apache24 configtest
# service apache24 start

Test that Apache will serve HTML by browsing http://localhost:8880 to see the default Apache install page.

Test that Apache will execute PHP by displaying the output from phpinfo() in a web page. I like to explicitly configure Apache for each site or page served to avoid the possibility of accidentally creating a security risk. First create /usr/local/www/phpinfo/index.php, the PHP code for the “phpinfo website”.


Next, create an Apache configuration file /usr/local/etc/apache24/Includes/phpinfo.conf.

Alias /phpinfo "/usr/local/www/phpinfo"

<Directory "/usr/local/www/phpinfo">
 Require all granted

Finally restart Apache,

# service apache24 restart

and browse to http://localhost:8880/phpinfo to confirm all is ok.

This post will be updated shortly to include the infrastructure for Maestro testing using PHPUnit and Selenium.

Install MariaDB

Install the MariaDB database server (and the mysql command line client). I haven’t tested Maestro with MariaDB v10.x yet, so will use MariaDB v5.5, which retains full compatibility with MySQL 5.5.

# pkg install mariadb55-server

Use the my-medium.cnf config file:

# cp /usr/local/share/mysql/my-medium.cnf /var/db/mysql/my.cnf

and edit it to default to InnoDB tables:

# Uncomment the following if you are using InnoDB tables
innodb_data_home_dir = /var/db/mysql
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = /var/db/mysql
# You can set .._buffer_pool_size up to 50 - 80 %
# of RAM but beware of setting memory usage too high
innodb_buffer_pool_size = 16M
innodb_additional_mem_pool_size = 2M
# Set .._log_file_size to 25 % of buffer pool size
innodb_log_file_size = 5M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50

Install MariaDB’s management database and setup grant tables:

# cd /usr/local/
# mysql_install_db --user=mysql --basedir=/usr/local --basedir=/usr/local --datadir=/var/db/mysql

The –datadir option should not be necessary but must be specified if mysql_install_db cannot determine datadir (aka ldir) correctly.

Edit /etc/rc.conf to start MariaDB at boot.


Start MariaDB.

# service mysql-server start

Configure the MariaDB root password:

> mysqladmin -u root password 'appleton'
> mysqladmin -u root -p -h localhost password 'appleton'
> mysqladmin -u root -p -h whizzer.swiftconstructioncompany.net password 'appleton'

If desired, grant root permission to connect remotely (e.g. to connect to MariaDB on the vm directly from the Windows host, or some other “remote” server).

> mysql -u root -p
mysql> grant all privileges on *.* to 'root'@'%' identified by 'appleton' with grant option;
mysql> exit;

Restart MariaDB to read the edited my.cnf file:

# service mysql-server restart

Run mysql_secure_installation as a double-check that all is ok.

# mysql_secure_installation

Install Samba and rsync

The venerable Samba v3 will be used for simple CIFS file sharing.

# pkg install samba3

Create the Maestro share directory.

# mkdir -p /usr/home/maestro
# chmod ugo+w /usr/home/maestro

Edit /usr/local/etc/smb.conf to configure Samba.

#======================= Global Settings =====================
workgroup = WORKGROUP
server string = Maestro Share
security = share
passdb backend = tdbsam
#======================= Share Definitions =====================
comment = Maestro Share
path = /usr/home/maestro
public = yes
read only = no

Edit /etc/rc.conf to start Samba at boot:

# samba3

Start Samba:

# service samba start

Install rsync.

# pkg install rsync

Install Utilities


Git is used to clone the Maestro project repository.

Install Git.

# pkg install git

Configure git with your username and email. I prefer plain text without color-coding.

# git config --global user.name "Dale Scott"
# git config --global user.email "dale@dalescott.net"

# git config --global color.ui false
# git config --global color.diff false
# git config --global color.status false
# git config --global color.branch false
# git config --global color.interactive false


mdbtools is used by Maestro export data from Parts&Vendors, which uses a Microsoft Jet v4 database (colloquially called an Access database).

# pkg install mdbtools


flip is useful for converting the occasional pesky Windows-format text file.

# pkg install flip



Hosting PHP Apps on Apache using PHP-FPM

Here are notes from some research I did a while back on using php-fpm with Apache and Nginx. dalescott.net will likely never reach traffic levels where it would benefit, so I’m staying with Apache 2.2 and mod_php for now.


  • http://php-fpm.org
    • project site, code now included in php
  • http://php.net/manual/en/install.fpm.php
    • discusses fpm but does not include specific install or config instructions (some posts though)


  • Google: apache+mod_proxy+fcgi+php
  • Google: apache+php+php-fpm+freebsd
  • TODO: add references etc to blog post on same topic

Project docs

  • http://wiki.apache.org/httpd/PHP-FPM
  • http://httpd.apache.org/docs/current/mod/mod_proxy_fcgi.html
  • http://httpd.apache.org/docs/current/mod/mod_proxy.html

Blogs, tutorials, and forums

  • http://www.howtoforge.com/using-php5-fpm-with-apache-2.4-mod_proxy_fcgi-module-on-fedora-18
  • http://garajau.com.br/blog/2013/12/apache-2-4-and-php-fpm-using-mod_proxy_fcgi
  • http://www.binarytides.com/setup-apache-php-fpm-mod-proxy-fcgi-ubuntu
  • http://jkroon.blogs.uls.co.za/it/security/using-php-fpm-and-mod_proxy_fcgi-to-optimize-and-secure-lamp-servers
  • http://www.rodrigocalado.com.br/famp-instalando-o-apache-2-4-php-5-5-mysql-5-6-no-freebsd-9-x-9-2-release/
    • Need to translate (Spanish? Italian?)
  • http://www.janoszen.com/2013/04/29/setting-up-apache-with-php-fpm/
  • http://forum.nginx.org/read.php?3,172673
    • nginx forum, but discusses Apache2, php-fpm, FastCGI
    • also see referenced post http://forum.nginx.org/read.php?3,131665,144226#msg-144226
  • http://www.hosting.com/support/linux/configure-apache-to-use-php-fpm/
    • Configure Apache to use PHP-FPM
  • http://funcptr.net/2010/11/14/apache-mod_fastcgi-and-php-with-php-fpm/
  • http://harold.internal.org/tag/freebsd/
    • Apache with PHP-FPM, chroots and per-vhost UIDs
  • http://www.yiiframework.com/doc/guide/1.1/en/quickstart.apache-nginx-config
    • tcp port


Google: nginx+PHP+php-fpm+freebsd

Blogs, tutorials, and forums

  • http://arstechnica.com/series/web-served
    • nginx, php, php-fpm, ….
    • VERY detailed
    • uses tcp port to communicate with php-fpm
  • http://blog.bobbyallen.me/2013/01/05/install-nginx-mysql-php-apc-and-memcached-on-freebsd-9-0
    • uses tcp port to communicate with php-fpm
    • provides nginx.conf file (downloadable)
    • intended use FuelPHP framework
  • http://blog.secaserver.com/2011/07/freebsd-nginx-php-fastcgi-installation
    • uses tcp port with php-fpm
  • http://fendyhussain.wordpress.com/2012/11/23/freebsd-nginx-with-php5
    • uses fastcgi (not fpm)
  • http://till.klampaeckel.de/blog/archives/44-Nginx+PHP+FastCGI-Testing-your-web-application-with-bleeding-edge-PHP.html
    • uses fastcgi
  • http://www.defcon1.org/html/nginx.html
    • installing nginx with PHP FPM on FreeBSD 8.x-9.0
    • uses fastcgi
  • http://www.howtoforge.com/installing-nginx-with-php5-and-php-fpm-and-mysql-support-lemp-on-debian-wheezy
    • discusses both unix sockets and tcp port config with fpm
  • http://www.howtoforge.com/installing-nginx-with-php5-and-php-fpm-and-mysql-support-lemp-on-ubuntu-12.10
  • http://www.yiiframework.com/wiki/153/using-yii-with-nginx-and-php-fpm
    • describes unix sockets on BSD for better performance (but must use tcp sockets with Linus due to kernel bug/issue)
  • http://www.yiiframework.com/doc/guide/1.1/en/quickstart.apache-nginx-config
    • tcp port
  • http://bin63.com/how-to-install-nginx-and-php-fpm-on-freebsd