Feature additions and bug fixes coming up in WinCache

We are seeing huge momentum behind adoption of WinCache. In the month of September, WinCache v1 Beta was downloaded more than 13,000 times making it one of the most downloaded IIS extensions in the first month following its release. Many happy customers chose to run it on their production servers despite its beta tag. We got very encouraging feedback from the beta release and we are pushing hard for our next release. Our next release date is approaching fast and I wanted to give an update on new features and bug fixes. If your favorite feature was missing in the beta and is also not in the list below, please email me or post on the forums so that we can consider it for future releases of WinCache.

Bug Fixes

1. We fixed a bug due to which same file was getting included twice even when include_once/require_once was used. Some PHP applications didn’t work due to this bug.
2. Few customers reported crashes when running WinCache on their test servers. This was because file cache component didn’t cache zero-size files properly.
3. One customer didn’t see enough performance improvement when using cakephp. This was because of a bug in opcode cache which caused us to recompile the code every time.
4. One bug caused opcode cache’s total hit count to be negative after first request. Also hit count of different file entries in file cache was one more than expected. Both of these bugs are fixed.
5. WinCache caches compile time errors and warnings generated by PHP engine. We fixed a bug due to which warning/errors caching sometimes caused next request to return 500.

New features

1. We are adding an API “bool wincache_refresh_if_changed()” to force a file change check on a file next time it is used from cache. This is useful if you change a file in PHP code and you want next request to load the file from disk again. You can pass blank or null which tells API to refresh all the files in the cache. An array of absolute/relative paths as argument will make WinCache only refresh these file entries. Please note that file will be reloaded from disk only if a file change is detected. This API enforces a file change check and not necessarily removal of cached entry.
In the next release, users will be able to disable file change checks completely by setting value of wincache.chkinterval to 0. When file change checks are disabled, changed file will be reloaded only when wincache_refresh_if_changed is called or IIS application pool is recycled. Cached files will still get removed by scavenger when the file is not used for a long time causing wincache to load the file again.
Another feature getting added is to enable administrators choose a list of websites for which wincache.ocenabled property is opposite of global setting affecting all the websites. This was requested by a hoster who wanted a safe and quick mechanism to turn-off WinCache for websites which run into some problems.
By default, caching in WinCache will be disabled when PHP is running in CLI (command line) mode. Setting wincache.enablecli to 1 will turn on caching in CLI mode.
5. We will be exposing total_cache_uptime property from wincache_fcache_fileinfo() and wincache_ocache_fileinfo() which will give total cache uptime in seconds.
On popular demand, we are including a PHP script (wincache.php) in WinCache setup which users can use to see cache statistics.

If you haven’t had a chance to test your PHP application with WinCache yet, download and try it out today. We are looking forward to your feature requests, bugs and general feedback to guide us for future releases of WinCache.

Update: WinCache RC release is available now.


How WinCache make PHP run faster

Why WinCache?

Use of PHP accelerators is very common to make PHP run faster. Most of the existing PHP accelerators which are in use today are designed keeping *nix architecture in mind and mostly doesn’t work well on Windows. For example, APC which is very commonly used on *nix doesn’t work on Windows. Xcache does work in ISAPI mode but crashes when PHP is running in FastCGI mode with multiple php processes alive. Absence of a stable PHP accelerator on Windows made people complain about PHP performance on Windows all the time. Another complaint which we heard consistently from customers running PHP on windows was that file operations on Windows were slower than on *nix. Reason being Windows’s CreateFile system call which is much more expensive than a fopen call on *nix as CreateFile goes through a much more complex security check involving ACLs. Windows programmers typically try to reduce CreateFile calls by caching file contents or keeping the open handles around so that security check happens only once. Because PHP opens the file every time it is required, PHP end up performing slower on Windows than *nix. To solve these problems, IIS team started working on an advanced caching solution few months ago which has resulted in the component known as Windows Cache Extension for PHP (WinCache in short). Below are short descriptions of the caching components which are available in WinCache.

Opcode cache

This is a standard opcode cache similar to other existing opcode caches available for *nix which works by overwriting zend_compile_file function pointer so that all compile file requests go through WinCache. WinCache let PHP core compile the PHP file to generate opcodes first time it is executed. It then caches these opcodes in memory which is shared with other PHP processes. When the same file is executed a second time, WinCache directly points to the cached opcodes in memory and skips compilation altogether. Generating opcodes from PHP code is a very expensive operation and major chunk of request processing time is spent here by PHP core. So having a solution like this saves 50%-70% of request execution time. WinCache creates a separate cache for all child processes under one worker process. So different worker processes keep separate caches and is more secure than current caching solutions.

File content cache

WinCache has a file content cache component which caches content of files in memory to avoid opening files every single time. This component works by replacing zend_stream_open_function function pointer so that file open requests go through WinCache. When a file is opened for the first time, we read the file contents into file cache. When the file is opened again, pointer to file contents in memory is returned instead of opening the file from disk. In our testing we saw that file operations are reduced by approx 80%-90% for each request for most of the popular PHP applications like wordpress, drupal, gallery etc. This is a huge win especially when content is on a UNC share. In our testing we found that PHP’s throughput is significantly impacted when content is moved to UNC share. With WinCache, throughput with content on UNC remains almost same as when content is present on the local machine.

Relative path cache

When we first added the file content cache, we relied on PHP engine to resolve relative path to absolute path as PHP has fairly complex logic to resolve relative paths. Given that most PHP applications use relative paths, this path resolution end up doing a lot of expensive file operations. To reduce these file operations we added a relative path cache component to WinCache which keeps relative path to absolute path mapping in memory. In PHP 5.3, all calls to zend_resolve_path goes through this cache and in PHP 5.2 zend_stream_open_function uses this cache to get the full path. Relative path to absolute path mapping is impacted by lot of parameters like current working directory, current executing file, value of include_path etc. We do take all these parameters into account to ensure that path resolution with WinCache and without WinCache is exactly the same. All you get with this cache is way less file operations but same result.

All the three caches are connected so that if a file is changed, file entry in opcode cache, file cache and relative path cache gets removed in one go so that all three caches stay always in sync. We have tested WinCache with PHP 5.2 and PHP 5.3. Read documentation to learn about properties you can set to control behavior of these caches.


Download link for PHP 5.2, VC6, NTS – http://go.microsoft.com/?linkid=9681612
Download link for PHP 5.3, VC9, NTS – http://go.microsoft.com/?linkid=9681610
Forums – http://forums.iis.net/t/1160554.aspx

Please try out WinCache beta release and give us feedback.