Migrating FastCGI configuration from IIS 5.1/6.0 to IIS 7.0/7.5


As you know FastCGI functionality on IIS 5.1 and IIS 6.0 is provided by FastCGI ISAPI extension which is available as an independent download. On IIS 7.0 and beyond, FastCGI functionality is provided by IIS FastCGI module which comes with the operating system. These components use different configuration stores to store the settings that affect their behavior. FastCGI ISAPI uses an INI file named fcgiext.ini as its configuration store whereas FastCGI module keeps configuration in applicationHost.config in xml format with rest of IIS configuration. Before, migrating from IIS6 to IIS7 involved migrating fcgiext.ini configuration to FastCGI module manually as there was no automated way to do that. MSDeploy only had functionality to migrate metabase configuration but because FastCGI ISAPI configuration is kept separately in an INI file, that wasn’t possible.


MSDeploy v1 RTW which is released today include a new provider named fcgiextConfig to automate task of migrating FastCGI ISAPI INI configuration to FastCGI module section. FcgiextConfig provider accepts a path which can be “APPHOST” or ”INI”. When path “APPHOST” is specified, configuration from system.webServer/fastCgi section in applicationHost.config is read. Path “APPHOST” should only be used on systems running FastCGI module (i.e. IIS7 and beyond). When path “INI” is specified, this provider reads the configuration from file “%windir%\system32\inetsrv\fcgiext.ini” and produce xml which looks like FastCGI module configuration. Once INI settings are mapped to produce the xml, msdeploy engine can compare configuration of FastCGI ISAPI with FastCGI module and make changes to FastCGI module configuration as required. Again, path “INI” can only be used on a machine which is running FastCGI ISAPI.


Dump command to dump INI settings looks like following.
        msdeploy –verb:dump –source:fcgiExtConfig=ini –xml
        msdeploy –verb:dump –source:fcgiExtConfig=apphost –xml

Sync command to move INI settings to FastCGI module section is following.
        msdeploy –verb:sync –source:fcgiExtConfig=ini –dest:fcgiExtConfig=apphost -whatif


  Here is how INI settings are mapped to system.webServer/fastCgi settings. For each entry   “<extension>:<optionalsiteid>=<sectionname>” under [Types] section of fcgiext.ini, we read the settings under section [<sectionname>]. If optional site id is present, we look for an entry for the same extension but without site id. If an entry is found, we use configuration under this entry as base set of settings for the site specific entry. So if “php=basephp” and “php:1=site1” entries are present in INI, settings under section [basephp] provide base values and then settings under section [site1] override base settings to generate configuration for “php:1” process pool. If a property is not present in the INI file, we assume the default value as assumed by FastCGI ISAPI extension. A FastCGI process pool entry is created for each INI entry with a valid ExePath. Various INI file settings are mapped to a FastCGI process pool as below.

fcgiext.ini configuration setting system.webServer/fastCgi/application property
ExePath fullPath
Arguments arguments
QueueLength queueLength
MaxInstances maxInstances
IdleTimeout idleTimeout
ActivityTimeout activityTimeout
RequestTimeout requestTimeout
InstanceMaxRequests instanceMaxRequests
FlushNamedPipe flushNamedPipe
Protocol protocol
RapidFailsPerMinute rapidFailsPerMinute
EnvironmentVars environmentVariables
ResponseBufferLimit Ignored
IgnoreExistingFiles Ignored
IgnoreDirectories Ignored
UnhealthyOnQueueFull Ignored

If the source version is FastCGI ISAPI 1.5, some additional properties get picked and mapped as below.

StderrMode stderrMode
MonitorChangesTo MonitorChangesTo
SignalBeforeTerminateSeconds signalBeforeTerminateSeconds

If FastCGI ISAPI version on source and FastCGI module version on destination are not compatible, fcgiextConfig provider will block the migration. Note that fcgiextConfig provider doesn’t take care of migrating the relevant IIS ScriptMaps. You can migrate ScriptMaps using a separate msdeploy migrate operation.

Hope this helps.

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.