Moving to PHP on 64 bit… the isssues & challenges

So your current website – if running PHP – and it seems to work just fine. I am however working on a project, where the new servers are running on a 64 bit version of the OS. This change seem to cause a number of potential issues, and as there didn’t seem to be a resource collection the issues, I’ll try to post a few notes on the experience. Please feel free to add applicable notes and links in the comments.

Our first experience was that all our scripts seemed to use a lot more memory than it did on the old server, but there are also number of other 64 bit challenges, you should be aware of. This post is trying to provide an overview of these changes.

The Integer issue

On a 32bit OS, PHP uses 4 bytes (of 8 bit) to define an integer. On a 64 bit system, PHP uses 8 bytes (of 8 bit) to define an integer and thus allows it to store a far langer range of numbers.

You can test this with a simple script such as this:

1
2
3
4
5
 echo 'The integer size on this system is: ';
 echo PHP_INT_SIZE. '<br>';
 
 echo 'The maximum value you can save in an integer is: ';
 echo PHP_INT_MAX;

On 32 bit, the script will output:

The integer size on this system is: 4
The maximum value you can save in an integer is: 2147483647

On 64 bit, the script will output:

The integer size on this system is: 8
The maximum value you can save in an integer is: 9223372036854775807

Generally¬†speaking the only drawbacks of this approach is an increased memory usage and maybe a lower performance – given you script doesn’t need the etra 32 bits provided on a 64 bit system.

This simple little script can simply illustrate the increased memory use:

1
2
3
4
5
6
7
$test = array();
 
for ($counter = 0; $counter < 10000; $counter++) {
  $test[$counter] = $counter;
}
 
echo "Memory peak usage: ", memory_get_peak_usage();

On a 32 bit system the number output from the script is (roughly):
810020.
On a 64 bit system the number output from the script is (roughly):
1517960.
That’s an increase of memory usage of more than 80% on a simple integer array!

Time and dates

Beware that many time related functions in PHP works with integers – such as mktime, strtotime and others uses integers as return values. As long as you use and work with these within the 32bit boundaries, you should be fine.

On 64 bit systems, they are able to handle much larger ranges, which could cause issues, if you allow that to happen.

Memory and performance

As the data volumes being moved around is increased, you could expect a performance penalty. On sites with low traffic volumes, it’s probably not an issue, but if you’re hosting a high volume site, it might be to some extend.

The extra memory seems to be a much larger issue to be aware of. While you may only assume you use a small number of integers, PHP itself does use them many places. When you’re creating arrays – they probably are indexed by integers and many functions return integers as control codes. While the required memory doesn’t double, do expect an overhead of 25-50% depending on what the script does – from the initial experiences; it does seem to be the case.

Bit shifting

Generally speaking, you should be aware every where you use bit shifting operations, as they by their very nature, is quite dependent on the number of bits in the variables available.

Handling Hashes

If you’re using hashes for checksums, beware. Some 64 bit issues may occur.

We’ve seen this issue on the crc32-function. If the result of the CRC32 is a positive number (on a 32 bit system), it will be the same on a 64 bit system. If the CRC32 results in a negative number however, the return result on a 64 bit sytem will be different.

This script:

1
2
3
  echo "<p>Letters 'ab'<br>";
  echo crc32('ab');
  echo "</p>";

Produces the following output on a 32bit system:

Letters 'ab'
-1635563411

But on a 64 bit system, it produces this output:

Letters 'ab'
2659403885

Note the returned hash is always the same, so if you’re using the crc32-hash on a completely 32bit setup OR a complete 64 bit setup, you’re might see any issues, whereas a mixed environment probably will cause issues.

Hash functions such as MD5, SHA1 and others – will always produce the same result no matter what system they’re running on.

PHP, MySQL and 64 bit

Mysql handles integers different than PHP. An integer in mysql has always the same size no matter if it’s running on 32 or 64 bit systems. An integer is always 32 bit. If you need to store a 64bit integer, mysql has an explicit data type – BigInt for this purpose, which is a 64 bit Integer (see mysql manual on Numerical types).

How to handle mysql seems to depend on what kind of PHP solution you’re building. If your application is deployed across several servers (which may be a mix of 32 and 64 bit systems), to two core strategies – is to either handle it in PHP or in Mysql.

Handling the issue in PHP would probably suggest, that you some how “range check” the PHP integer values and make sure the value is within the range allowed by a 32 bit integer.

Handling the issue in Mysql, would mean to just change the integers in the database to BigInts. This would always work, but for all 32 bit system be a less efficient solution.