ColdFusion Performance Tuning
This article describes how to maximize the performance of your ColdFusion web applications.
4 factors affecting Performance
- Hardware and Software Configuration
- Database Design
- Web Server Performance
- ColdFusion Application
Hardware and Software Configuration Issues
Independent of ColdFusion, there are a number of critical configuration options that are fundamental to creating a high performance application. In fact, developing a coherent hardware configuration architecture is more than likely the single most important thing an administrator can do to ensure high-availability and high-performance Web applications.
CPU vs. Memory Intensive Applications
Dynamic web applications that use engines such as ColdFusion and back-end databases are often referred to as "CPU" bound services. By this we mean that ColdFusion application logic processing and database query are CPU-intensive processes as opposed to memory-intensive processes. With this in mind, scaling a server may often be a function of having more processors (CPUs) available to the ColdFusion application and database servers. Of course, with the ability to use 'application' and 'session' variables to store persistent data, it is also possible to use RAM as a critical lever in increasing performance. Hardware investments should reflect both the nature of the application (database/query intensive versus application logic intensive, etc.) and use of memory resources.
Based on this, if applications require substantial database processing and application logic, consider multiple CPUs with large amounts of RAM, using the memory to store persistent database information or other global variables.
Segmenting Server Logic
Another important architectural choice is the number and function of machines used to handle a ColdFusion application. In most cases, a high-performance application will require segmenting the Web application server from the database server with each server dedicated to its respective tasks. More often than not, the database server will use a high performance engine such as SQL Server or Oracle.
Beyond a two-server segmentation, it is also possible to introduce a third server as an "object server". This server hosts and executes distributed objects built with high performance languages such as C/C++.
Isolating Web Application Server Infrastructure on the Network
As one moves to a distributed server infrastructure, it becomes necessary to ensure that servers are configured on a physically separate network from other servers, reducing bandwidth or network congestion problems introduced from other machines using the network. It is important to segment the Web application infrastructure from other servers using a bridge, switch or router, and ensure that the Web application server is the first available server on the network.
Redundant Servers and Dynamic Load Balancing
Finally, and most critically in terms of hardware scalability options, is the need to create a configuration of mirrored or redundant servers and use dynamic load balancing to handle incoming load. The majority of very large and very high volume Web sites use mirrored servers to handle incoming user requests. Each server keeps a complete copy of the site or application, ensuring that the user experience is the same across all machines.
This scenario requires a router that supports dynamic load balancing or "round-robin routing". This technique uses a single IP address across multiple machines, creating the illusion to the end user that they are accessing one machine. The router keeps track of the load - the number of current IP connections - open on each server, and dynamically routes users to the most available server. This same technique can be used to balance load against multiple database back-ends, so long as the data in the database servers is mirrored or truly redundant.
An ultra-high performance architecture will typically involve 3-4 machines, each with substantial CPU power (2-4 processors), significant amounts of RAM (>256MB) and redundant servers (2-3 application servers). This kind of configuration can scale to support millions of users per day.
RAM, hard drive access time, and number of CPU's will all affect performance.
Our experience shows that the number of processors may be the more critical element, depending upon the type of application running. If you have less process intensive applications, then elements like the disk and memory will increase template access performance and will likely give a healthy boost in performance.
NT4.0 Server Settings and tips
- Set the paging file size to 2X physical memory (but no larger than 512 MB). Configure it so that both the initial and maximum values are set to this figure.
- Split the paging file across multiple physical disks, if possible.
- Configure the Server service (via Control Panel - Network - Services tab) to be optimized for the machine's intended role. For CF, we suggest 'Maximize Throughput for Networked Applications'.
- Set the foreground application boost to 'none' (via Control Panel - System - Performance tab).
- Only use low end screen savers, preferably the 'Default Logon' saver. OpenGL screen savers should be avoided as they are very CPU-intensive. This one can sneak up on you and slow down your server.
- Run a minimum of services on a server. Disable any unneeded component (like the Gopher daemon).
- Take care to never leave an instance of the EDIT utility running in a Command Prompt. If you accidentally hit the Alt button, it will max the CPU while polling for user input.
Database Design
Poor database design
A poor database design will negatively affect performance, such as too many tables or too few. Check the normalization. Different table configurations can improve your query results.
Is your database up to the task?
Depending on your application you may need a more powerful database. If you have a million records in an MS Access file you may need to upgrade to a more powerful class of database.
The other key issue in database choice is concurrency. MS Access on a per request basis is relatively quick. But MS Access does not handle concurrent requests well, while Microsoft SQL Server will handle high concurrency associated with high load and continue to perform extremely well. For lower traffic sites, MS Access may be enough, even for a relatively large database. If the site is expected to see high load, however, suggested databases are Microsoft SQL Server, Sybase, Oracle or Informix.
What is the bandwidth between the CF Server machine and the database?
What is the network bandwidth between my ColdFusion/Webserver machine and my database server? Are there any bottlenecks here? Is it a 10 megabit, or 100 megabit network? What about the network card? Does it support the 100 megabit traffic?
As discussed above, move the database off the Web server machine.
Web Server
Is your Web Server itself slow?
There are web server settings that will affect performance. Consult your Web server documentation.
ColdFusion Application
Application Design
At the center of any effort to create a scalable web application should be intelligent application design. While the ColdFusion server provides native facilities to boost performance, it is ultimately in the hands of the application architect to ensure a high-performance application.
First in a designer's mind should be concern for efficient use of code. ColdFusion provides a number of language features that facilitate higher-performance applications. Cookies, arrays, includes and server variables all provide a means to store and manage code and content in ways that increase performance.
Second, in database centric applications, the quality and performance of an application often rests on the speed of query execution in the database. The developer should examine the SQL to ensure that it is querying the database in the fastest and most efficient way.
Third, developers should analyze where it is appropriate to segment application logic into different servers and files. When possible, developers may choose to use stored procedures to execute SQL calls and application logic, providing a high-performance, compiled architecture for database intensive operations. Related to using stored procedures is the use of distributed objects, where elements of application logic and database access are offloaded to a separate external object written in a compiled language such as C++, Delphi or VB5.
Using Server, Application and Session Variables for Persistent Data
A number of variable scopes can be used by developers to have fine-grained control over data caching and output. Often times a given application will have queries or data used that is not totally dynamic and which could be cached across user requests and applications. For instance, a company might have a page with a list of press releases. The list of press releases is stored in the database. However, the query to generate the list needs to run only once for a given application, and then have that data available to all users without having to re-query the database. Developers can take the results of a query and store it in a 'application' or 'server' scoped variable. Successive requests then no longer need to query the database, but instead would just use the query results stored in the application variable and output them onto the page.
Another example is an online service where each user has a unique set of preferences that are stored in a database. When a user accesses the service, ColdFusion can create a 'session' for that user. The query against the database of preferences could be run, and then the results stored in a 'session' variable. Future access to the preference data can then simply be called out of memory from the 'session' variable, instead of having to re-query the database again. When the session expires, the preference data also expires.
Use Verity for Unstructured Data Searching
The ColdFusion Application Server includes an embedded high-performance text indexing and searching engine provided by Verity. The Verity engine provides developers with a platform for handling high-performance searches across unstructured textual data. This capability is a critical way of increasing performance in Web applications that involve searching large databases for information.
A particular feature of ColdFusion's integration with this technology is the ability to index and search textual content stored in a relational database, but using the high-performance Verity engine instead of SQL queries. SQL was originally designed for searching and manipulating highly structured data. Over time, however, the advantages of using a relational database to store unstructured textual data have become obvious, shifting developers to store and search textual data in relational databases. However, SQL is poorly suited to such searches. Using SQL to search thousands of textual memo fields or records can use unnecessary system processing cycles and typically yield poor matching and results.
Using ColdFusion's cfindex andcfsearch, it is easy to automatically index textual content into high performance Verity Collections. Then, when an end-user performs a keyword search against this data, it searches the Verity collection, returning matches, including the primary key of the database record, allowing the developer to return other information about the record from the database. Implementing intelligent indexing and searching where appropriate can radically improve the performance of search-oriented ColdFusion applications.
Schedule Asynchronous, Resource Intensive Tasks for Offline Use
ColdFusion includes a page scheduling framework that allows the Web developer to schedule parts of an application to run in the background (asynchronously). This capability offers significant opportunities to increase application performance by scheduling resource intensive batch processing or background tasks to execute during non-peak hours. Scheduling can and should be used to handle file and content replication, database reporting, high volume messaging, application and database clean-up, and other activities that are not part of the real-time or transaction oriented parts of applications.
Application Techniques
In terms of scaling to support multiple servers, developers should be careful about the use of niceties like session variables, server variables, and client variables, as these are all tied to the server that is hosting the application. If you scale to multiple ColdFusion servers hosting the same application and are depending upon these, your application will break or misbehave.
CF Admin debug settings
Turn on all debug options when developing and check the processing times for your queries, and loops.
Poorly written SQL queries
Test your SQL queries with the HomeSite+/ColdFusion Studio Query builder to make sure they are efficient.
Loops
Limit your use of nested loops.
Nested if's
Limit your use of nested cfif else statements. Try substituting iif functions or non-nestedcfif statements.
# evaluations
Complex dynamically constructed expressions will negatively affect performance.
Optimizing performance when using variables
You can improve performance by always qualifying your variables with the proper scope. For example, both forms of the following variable are permitted. However, the example that includes a scoping prefix will be evaluated more quickly than the unscoped example.
CFOUTPUT vs. CFLOOP
Use a cfoutput query instead of cfloop query wherever possible. A loop over a query repeats for every record in the query result set. The cfloop results are just like a cfoutput. During each iteration of the loop the columns of the current row will be available for output. The advantage of using cfloop instead of acfoutput is that you can use any CFML tag within acfloop. cfoutput is restricted to a limited number of tags to increase its performance.
Arrays
ArrayResize
Resets an array to a specified minimum number of elements. ArrayResize can provide some performance gains if used to size an array to its expected maximum. Use ArrayResize immediately after creating an array with ArrayNew for arrays greater than 500 elements.
Array objects can be created by assigning an existing array to a new variable:
<CFSET myarray2 = myarray>
In this case, a separate copy of the data in myarray is copied to myarray2. Changes made in myarray are not reflected in myarray2. It is very important to understand that such assignments are very resource-intensive since the entire array is copied from one variable to the other. This operation can significantly affect performance when large arrays are involved.
CFPOP
Two retrieve options are offered to maximize performance. Message header information is typically short and therefore quick to transfer. Message text and attachments can be very long and therefore take longer to process.
CFHTTP
Use the ResolveUrl=yes only when needed.
CFFILE
Extensive use of cffile will create a performance problem because of the slow nature of disk I/O. Explore other options, for example stored procedures or other database functions or system calls.
CFQUERY
Check out these SQl syntax tips
Optimizing ColdFusion Queries (a case study)CFSET
A general comment about good CFML coding style. We suggest that all CFML developers replace
<CFSET #foo# = "#bar()#">with the much simpler and more efficient
<CFSET foo = bar()>
ColdFusion Administrator settings
Beyond efficient application design, there are a number of additional ColdFusion server settings that will allow for higher performance applications.
Caching Settings
As noted above, ColdFusion's server administrator provides a means to tweak caching settings for pages and database connections.
Page caching settings also provide a very easy way to increase performance on the server. As a general rule, it is useful to set the amount of memory allocated for page caching to the total size in kilobytes of all of the pages used in applications on the server. This will ensure that all applications are automatically cached and compiled in memory, completely eliminating file I/O overhead and first-pass code interpretation. The only constraint on this is total amount of memory on the system. Note, however, that it is extremely rare that the total K of pages will exceed the available memory on the machine. In the case that the cache size is set lower than the total size of pages, ColdFusion will use a FIFO processing model on page requests. This means that the most commonly accessed pages will almost certainly always be cached in memory. (Note: the above discussion pertains to server-wide settings, as opposed to an individual application, because currently the caching settings can be set on a server-side basis only).
There is no harm however in setting page cache to a much higher setting as ColdFusion will use what it needs when it needs it and let it go when it is through with it.
This setting should represent the upper limit that ColdFusion will use. Set it high.
Thread Settings or simultaneous requests
A critical setting that can be tweaked to increase performance is the number of simultaneous requests that the ColdFusion server will execute at any given time. This setting is loosely associated with the number of threads. The general rule is to set the simultaneous requests setting to 2-3 times the number of CPUs on the system. So, if the server has two processors, the number of simultaneous requests for the ColdFusion server should be set to 4-6. In this case, if and when there are more than two threads being requested, ColdFusion automatically queues additional requests until one of the other two is freed up. Setting the number of allowed threads much much higher than the number of CPUs will result in a degraded performance, because the ColdFusion server must then attempt to manage the multiple thread execution even though the OS will not execute additional threads until one of the processors is free.
How to limit simultaneous requests CF Server settings
To set the server limit for simultaneous requests, run the ColdFusion Administrator. You will find the Simultaneous Requests setting on the 'Settings' page.
You can specify the limit that is appropriate for your configuration in the space provided for the setting. If ColdFusion attempts to process more requests than your server can handle (based on configuration), the server could possibly stop responding.
Limit simultaneous connections - Data Sources CF settings
As a general rule, the number of allowed connections to a database should be set to a number depending on the following:
- the estimated user load, and
- the amount of memory on the machine.
For higher numbers of users with a machine with lots of RAM, connection settings should be larger (e.g. 5 - 10 ). If you want to limit the total database connections, you must set that under the particular data source settings. If your database can't keep up with ColdFusion, you should begin to see errors like "timeout getting connection to Datasource". If your ColdFusion machine is bogged down processing ColdFusion templates, you start getting timeouts and "server busy".
Maintain Database Connections - Data Sources CF settings
This option is checked by default. What this setting does is that when a request is made from ColdFusion to a database it makes the database connection (first time only) and keeps it open to reuse for each subsequent database request. The connection is dropped only when the ColdFusion Service is stopped. If this setting is not used each database request made via ColdFusion would have to:
- Establish a connection to the database,
- fulfill the request, and
- disconnect from the database.
Take these activities and multiply them by every database request made via ColdFusion and you can understand the performance implications.
Scheduling and Static Page Generation
- It is possible to automatically generate static-pages from dynamic content stored in databases. Using a built-in scheduling engine, developers can automatically create static pages from dynamic data, substantially increasing the speed of page delivery to end-users without sacrificing the productivity and cost savings of using dynamic templates and database management of Web content.
- This facility can be very useful for applications that do not require user interactions or customized output, such as a daily sales report, corporate directories, statistical reports, and batch processing of transaction files.
- You can schedule application page execution to run on a daily, weekly, or monthly basis and specify a time of day for execution. You can also schedule a page to be run once on a specified date or at a regular interval during the day.
- When a scheduled template executes, a message is written to a schedule log file, which specifies the name of the scheduled action, the application page that was executed, and whether the page executed successfully or not.
- To access the scheduling facility, open the ColdFusion Administrator and click the Scheduled Task link.
Additional Information
Related TechNotes:
This content requires Flash
To view this content, JavaScript must be enabled, and you need the latest version of the Adobe Flash Player.
Download the free Flash Player now!
