Apache, PHP and Firebird Performance Tuning

In the last post I commented that I had a test-bed application, based on Apache, PHP and Firebird, and once the problem with the images was solved I could finally start doing the actual performance testing/tuning that I originally wanted to do.

The only major changes from the last post is that I’ve now upgraded the database engine to the “Firebird v2.5 Alpha 1” that supports SMP, and that the application now contains more base data in the tables.

The test-bed application

The Test-bed application is a very simple one, but represents a fairly common situation for a web-application, where users log in to an application, browse pages and then logout.

The application has been designed so that the web-sessions are maintained with cookies, but not using the PHP built-in session-manager, but instead it uses a custom-made one that stores everything in the DB.

This enables Load-Balancing for the application so that it can be distributed over several instances in the backend, without needing any changes. I’ve chosen this path because I know that the bottleneck will not be the database, but the apache+php installation.

My test-case is as follows:

  • Navigate to the Welcome/Login page
  • Login to the application (with false credentials)
  • Login to the application with correct credentials
  • Browse to another page in the app
  • Logout from the app

Each page refers to a .css file and has one/two images associated with it. The pages that are accessed after the login verify the users cookie against the database, updates the expire time, and updates the session-information in the db to match the cookies new values. The logout page clears the session from the DB and returns an expired empty cookie.

Performance Tests

From the tests I will only post the Pages/Sec, Hits/sec, CPU usage and response times. Other values may be obtained by contacting me if anyone is interested.

Note: These values are not meant as fixed reference points, but rather as indicators of how different things affect the performance. These tests are only meaningful when compared to each other!

Also all the tests are executed on the same hardware:

  • ThinkPad T61p (Laptop), with Intel 2.2 GHz DualCore (T7500)
  • Windows XP SP2, 4 Gig’s RAM
  • Apache v2.2.9 (Win32) / PHP v5.2.6
  • Firebird “WI-T6.3.0.20343 Firebird 2.5 Alpha 1”

The database Page Size is 8192, and Page Buffers is 65535, and some of the fields in tables contain indexes to speed up searching (Like TABLE Accounts, has an index on aUsername).

Also the “CpuAffinityMask” was set to “CpuAffinityMask = 3” in the firebird.conf file to enable the SMP on the DualCore machine.

Results summary

I’m updating the results all the time, but added this section here as a quick reference.

Test Set Pages/Sec Hits/Sec Avg.CPU (Web/DB)
Avg. Response Time
Set 1, Test 1
Forced writes ON
91 210 73% / 27% ~1.2 sec
Set 1, Test 2
Forced writes OFF
105 250 72% / 23% ~800 ms
Set 2, Test 1,
81 195 65% / 35% ~2 sec
Set 3 – Test 1
Separate Web & DB Servers
120 260 88% / 72% ~850 ms

The test sets

In the 1st set I want to test the difference between using FORCED WRITES ON or OFF for the database. In enterprise environments it’s almost guaranteed to be a power-outage safe environment so the FW OFF switch could be useful. This test will use IBASE_PCONNECT in PHP (assumed to be faster).

In the 2nd set I want to test the difference between “IBASE_CONNECT” and “IBASE_PCONNECT” in PHP. This so that I will know if there is a significant difference here.

In the 3rd set I want to test how separating the DB to another machine affects the performance. The DB machine is an older T43 Thinkpad,

Test set 1 – Conclusions

From the results above I’m drawing the conclusion that setting Forced Writes = Off gives me a slight performance increase of about 14 pages/sec for this specific web-application. Also the response times are a little smaller, probably due to the fact that the database is responding a little faster to the updates. On the downside I got some errors from the app (Socket Connection Refused), but that could be due to Windows XP not allowing more simultaneous connections.

Both tests took 100% CPU from the host machine, with the same division of approximately 75% for Apache and 25% for Firebird.

If the load would have been increased there might have been drastic drops in performance, and I will try that another day since I want to know what happens when I increase the load over the capacity of the server!

Test set 2 – Conclusions

From the results it is clear that IBASE_CONNECT allows significantly less load through the system than with the the IBASE_PCONNECT method.

Test set 3 – Conclusions

Based on the results I can assume that not having the network as an obstacle, I would get 130 pages/sec with this configuration. That’s another 15 pages/sec more than when I executed everything on one machine.

During the test I saw that Apache’s log had the “winnt_accept: Asynchronous AcceptEx failed” error in it, so I added the “Win32DisableAcceptEx” directive to the httpd.conf to alleviate the log-error and restarted the test (read this off articles about the error).

I also changed the ThreadsPerChild to 300 for this test.


4 thoughts on “Apache, PHP and Firebird Performance Tuning

  1. You said, “I know that the bottleneck will not be the database, but the apache+php installation.” Why did you so sure about this? You’ve made error assumption on KeepAlive feature, not surprise if you’ll make it again. In database application, I’m sure the database IS the biggest bottleneck. The higher load on Apache+PHP is unrealistic, compare with Firebird. “IBASE_CONNECT allows significantly less load”, with the longest Avg. Response Time? I don’t get it.

  2. My “I know” assumption was based on experience with other Apache+PHP apps. Also during my tests on the local machine the CPU was divided 73% for Apache and 23% on Firebird processes, and also the last test shows that when Apache is using up 88% on the webserver FB was using only 72% on the DB machine (see tale in post).

    These numbers suggest the app is taking more CPU resources than FB, in the tested scenario. My scenario was simple in the fact that it delayed between 1 and 3 seconds for every click (pageload). The 1-3 seconds was chosen since otherwise I would not reach high enough pageloads/sec with the testing software (LoadRunner). A more realistic scenario where users would browse at lower speeds (say 10 secs/click in avg.) the pageloads/sec would not be very high, thus nullifying the purpose of the test.

    One might argue that “there will not be more users than x at any given time” but performance testing not only tests the expected loads, it also finds where the breaking point is, a little like Mythbusters 🙂 I have yet to see an application perform as expected under expected loads in the wild, so stressing the apps beforehand and knowing their limits is in my opinion critical.

    The IBASE_CONNECT test indicates that FB needs to work more for the same amount of load (Ser 1 Test 2) by taking more CPU. If this is unclear I will try to explain in more detail. The DB machine was also a single CPU (HT) at only 1.8 GHz running on Windows XP SP2. If you want to compare the Web+DB on same machine vs. Web+DB on separate machines please have a look at More Apache+PHP+Firebord results.

    As for the KeepAlive I was hasty and didn’t look into the issue deep enough. Still the net effect remains the same: KeepAlive Must be kept OFF for this application.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s