• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Optimise CFHTTP Requests/Requests Being Throttled?

New Here ,
Feb 27, 2014 Feb 27, 2014

Copy link to clipboard

Copied

I currently have an application that trades virtual items and is making at least 40 CFHTTP requests per second to the host's server.

The issue I'm encountering is that it's taking anywhere from 400ms+ for my CFHTTP call to return a response which means my application is missing out on 99% of the deals it finds, as there are lots of other competiting applications out there that are getting a faster response.

I've struggled to find a cause and/or a solution to this situation so I wrote a script in both CF and C# that makes 10 http requests timing each one which resulted in the following response times:

In CF using the following browsers:

IE9: 384, 444, 302, 570, 535, 317, 510, 349, 357, 467 - Average 423.5ms

Firefox 27.0.1: 354, 587, 291, 480, 437, 304, 537, 322, 286, 652 - Average 425ms

Chrome: 300, 328, 328, 639, 285, 259, 348, 291, 299, 414 - Average 349.7ms

In C# Console Application:

597, 43, 96, 52, 44, 305, 67, 91, 54, 270 - Average 161.9ms

As you can see there is a big performance difference when making an HTTPWebRequest in a C# Console Application which is making me think that perhaps the CFHTTP requests are being throttled? Or could it maybe be something to do with the browsers?

Any help would be greatly appreciated! 

Views

2.0K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 27, 2014 Feb 27, 2014

Copy link to clipboard

Copied

You might be worrying for nothing. There are apparently 2 different processes at work here:

1) CFHTTP is itself a browser! It interacts with the host server;

2) IE, Firefox and Chrome each interacts with ColdFusion, via the web server, to get the result of the CFHTTP action.

Your priority is of course for process 1 to be as fast as possible. It is indeed possible that process 1 is super fast, and that process 2 is causing most of the delay that you observe.

To verify this, go to the Debugging page of the ColdFusion Administrator and check the options Enable Request Debugging Output and Report Execution Times. Then examine the execution times of the page containing the CFHTTP code.

In use-cases where reaction speed is critical, one technology comes to mind, push technology. You could redesign your application to use websockets. It would then be possible to get the response from the host server as soon as ColdFusion receives it.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Feb 28, 2014 Feb 28, 2014

Copy link to clipboard

Copied

Thanks for your reply.

Below is a screen dump of the test page I set up which makes 10 requests to a test function. The test function makes a standard CFHTTP call. Each request is timed and the time output on the page.

ExecutionTime.jpg

From what's there it gives no insight to me of what is actually happening or causing the requests to take so long to complete.

I've had a look around online the last few hours for web socket example but can find nothing other than creating a chat room! Do you have a link to any material or pseudo code that would allow me to create a test page that used web sockets so I could make a comparison between the request times?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 28, 2014 Feb 28, 2014

Copy link to clipboard

Copied

I thought your application involved just CFM pages that implement CFHTTP. Hence my suggestion to enable Debugging Output in the Administrator.

From the look of it, your application involves invoking CFCs. This calls for a change of plan. You should de-activate Debugging Output. It is a very blunt instrument in the circumstances.

The cftimer tag or getTickCount function are more appropriate. I guess you are using them already.

The question remains how to crank up the speed in this new setting. Invoking a function in a CFC to interact with a remote server can be costly in CPU terms. I'll have a think.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Feb 28, 2014 Feb 28, 2014

Copy link to clipboard

Copied

Thanks, you have no idea how much I appreciate your help with this

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 03, 2014 Mar 03, 2014

Copy link to clipboard

Copied

I have tested a number of CFHTTP scenarios. There is good news and bad news.

Firstly, the bad news. It seems that CFHTTP is sluggish by design. No amount of refactoring or code-efficiency that I implemented could get it to run faster than a modest threshold.

To emulate your scenario, I did the following tests:

TestComp.cfc

cfcomponent>  

    <cffunction name="getURL" returntype="struct">

        <cfhttp method="get" url="http://www.myDomain.com">

        <cfreturn cfhttp>

    </cffunction>

</cfcomponent>

Test scenario 1

The following CFM page invokes the CFC 10 times. Each invocation creates an instance of the component, then calls a method that makes a CFHTTP Get request and returns the result as a struct. The result is stored as an array element. Each such invocation is timed.

cfhttpTest1.cfm

<cfset arr=arrayNew(1)>

<!--- <cfset obj=createobject("component","TestComp")> --->

<cfloop from="1" to="10" index="i">

    <cfset start = getTickCount()>

    <cfset obj=createobject("component","TestComp")>

    <cfset arr = obj.getURL()>

    <cfoutput>count #i#: #getTickCount() - start# milliseconds<br></cfoutput>

</cfloop>

Scenario 1 result

count 1: 1665 milliseconds

count 2: 1774 milliseconds

count 3: 1634 milliseconds

count 4: 1771 milliseconds

count 5: 1667 milliseconds

count 6: 2045 milliseconds

count 7: 1645 milliseconds

count 8: 3004 milliseconds

count 9: 1656 milliseconds

count 10: 1844 milliseconds

Instantiating the component object outside the loop made no difference in the execution times.

Test scenario 2

Here the CFHTTP tag comes in as an included CFM file, rather than via a method in a CFC. The hope is that this will be much faster than the above scenario, as there is no object creation and no method invocation. As before, the CFHTTP Get request is run 10 times and the resulting struct is stored as an array element.

cfhttpRequest.cfm

<cfhttp method="get" url="http://www.myDomain.com">

cfhttpTest2.cfm

<cfset arr=arrayNew(1)>

<cfloop from="1" to="10" index="i">

    <cfset start = getTickCount()>

    <cfinclude template="cfhttpRequest.cfm">

    <cfset arr = cfhttp>

    <cfoutput>count #i#: #getTickCount() - start# milliseconds<br></cfoutput>

</cfloop>

Scenario 2 result

count 1: 1678 milliseconds

count 2: 1740 milliseconds

count 3: 1894 milliseconds

count 4: 1695 milliseconds

count 5: 1769 milliseconds

count 6: 1721 milliseconds

count 7: 1538 milliseconds

count 8: 1683 milliseconds

count 9: 1569 milliseconds

count 10: 1795 milliseconds

Scenario 2 is faster than scenario 1, but only marginally. So, sadly, I have to confirm your findings. I cannot think of any other way to make the CFHTTP requests faster in these scenarios. CFHTTP seems to be slow by design. That was then the bad news.

On to the good news. I found a much faster alternative to CFHTTP, namely, Curl.

Test scenario 3

My Operating System is 64 Bit Windows 7. I downloaded the latest Curl file curl-7.35.0-win64.zip and extracted it to c:\curl-7.35.0-win64. I then ran Curl in ColdFusion, using cfexecute. The loop runs 10 times, as before, each result, being stored as a text file.

curlTest.cfm

<cfset outputPath=arrayNew(1)>

<cfloop from="1" to="10" index="i">

    <cfset start = getTickCount()>

    <cfset outputPath= "C:\Temp\output#i#.txt">

    <cfexecute name = "C:\curl-7.35.0-win64\bin\curl.exe"

        arguments = "http://www.myDomain.com"

        outputFile = "#outputPath#">

    </cfexecute>

    <cfoutput>count #i#: #getTickCount() - start# milliseconds<br></cfoutput>

</cfloop>

Scenario 3 result

count 1: 392 milliseconds

count 2: 128 milliseconds

count 3: 119 milliseconds

count 4: 191 milliseconds

count 5: 49 milliseconds

count 6: 12 milliseconds

count 7: 24 milliseconds

count 8: 23 milliseconds

count 9: 6 milliseconds

count 10: 21 milliseconds

Evidently, Curl is faster than CFHTTP is this scenario, by several orders of magnitude!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Mar 03, 2014 Mar 03, 2014

Copy link to clipboard

Copied

Wow!! Thanks very much for this!

I'll have a look into cURL and see how customisable it is (to pass in custom header values) and report back.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Mar 03, 2014 Mar 03, 2014

Copy link to clipboard

Copied

LATEST

I've always thought that CFHTTP had alot of overhead.  a year or two ago we were looking at switching to php (have since dropped that in favor of .NET), and had a php programmer convert one of our really slow CFHTTP laden scripts.  The php script used curl for all of the HTTP handling.  It ran so fast I didn't think it did anything.  We're talking about going from hours of processing to a minute or so, doing around 100,000 calls to a google API.

One of the nice things about curl is that if you have problems with ssl sites you can set an option to ignore certificate errors.

The .NET rewrite also saw gains in performance over CFHTTP in CF, but not quite to the level of what we saw above.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation