51 thoughts on “The Best Way to Use TimThumb with a CDN (and Why Amazon S3 Is Not so Good) Leave a comment

    1. That’s true, and to be honest I haven’t used CloudFront – only looked briefly at the docs. The reason I wrote this is because I keep having people ask me about how to make TimThumb work with Amazon S3 🙂

      I think I will add some clarifications to the article to explain the difference

  1. I totally agree on the usage for W3 Total Cache for integrating it with CDN in order to speed up the loading speed of a website. I have been using the CDN with W3TC and it simply amazed me.

  2. Hi Ben,
    First of all, congratulations for your great work!

    It seems that WPCDN is based on HighWinds CDN. We have tried HighWinds sometime ago because it has a node in Sao Paulo / Brazil, our base operation. But we had no luck, specially regarding some crazy redirect issues. Thinking about another test soon!

    Also your site is acessible through http://www.bynarymoon.co.uk and cdn.bynarymoon.uk. Couldn´t it lead to duplicated content?

    1. Thanks for the comments. I think you’re right that wpcdn uses highwinds – yes. I hadn’t considered the duplicate content thing before – you’re also right about that, however WordPress does have the rel=canonical stuff built in which should help. I will ask wpcdn if there’s any way to disable html caching.

      1. Hi,

        Ben, thanks for the mention!

        To clarify, we no longer use Highwinds.

        Best regards,


  3. Hey Ben,

    So I did as you said and added *timthumb.php to the themefiles to upload field in W3TC and hit save and….. when I visited my site http://www.beaverjournal.com I clicked on a thumb and this is the result:

    It is using the CDN to server TimThumb BUT it is still using the local files as a source when serving the thumbnails themselves.

    1. that’s perfect – exactly what should be happening. The load on your server will only happen when the image is not cached. You should see a big drop off in server/ cpu & bandwidth now you’re using it! 🙂

      1. It’s not working for me
        ‘remote host “site.com” not allowed
        Query String : src=http://site.com/wp-content/uploads/2011/03/136576370_640.jpg&q=100&a=t&h=142&w=222
        TimThumb version : 1.25’

  4. Hi,

    Thank you for the article!

    I’ve tried putting *timthumb.php in W3 Total Cache Plugin and it uploads fine but when I call it, it prompts me to download the file… what am I missing?

    I can view images, etc. from cdn domain just fine, just when parsing through timthumb!

    I am using Amazon’s CloudFront for CDN.


    1. I am afraid I haven’t used Amazon Cloudfront so I don’t know how it works but it looks like it may not support timthumb/ images loaded through php…

    2. Just a FYI…. W3 TC works best with MaxCDN and is the preferred CDN for the developers of that plugin and is probably the most widely used CDN for WordPress blogs.

      Most other CDN’s including CloudFront and RS do not work well with the popular Cache/Performance plugins available to wordpress users.

      1. Thanks for the info however I am sure W3 Total Cache works fine with loads of cdns. I use most of the W3 features and have no issues. Works great for me 🙂

      2. That’s a big chunk of BS, since WordPress themselves use EdgeCast, not MaxCDN (and looking at the performance stats, I can see why.)

  5. Well,

    Even maxcdn/netdna wouldn’t work with timthumb as this article mentions.

    I asked maxcdn engineer and this is the answer I got:

    No because anything that has to do with php code considers dynamic and we dont support.

    What service is beaverjournal using to serve timthumb?


    1. wpcdn works fine with the service, as I mentioned in the article. It’s the only service I have tried so I can’t speak for any others.

      I wonder if the maxcdn engineer is wrong, since he hasn’t actually used the script. TimThumb sends image headers so unless they are looking at the url itself (which I doubt) it won’t know the difference between an image and a php file. Of course this is speculation and I am probably wrong. No way to know for sure without trying I guess.

      1. I had the exact thing said from MaxCDN. Actually below is what they wrote back after I asked about this.

        From what I can see, it seems that you have a thumbnails plugin that rewrites your links as http://xxx(dot)com/wp-content/themes/xxx/scripts/timthumb.php?src=http://xxx(dot)com/wp-content/uploads/2011/03/wrecked-movie-2011-.jpg&w=520&h=280&zc=1

        Our CDN service views this as a dynamic file and thus it is not cached. Probably what you could do is to get a thumbnails plugin that supports CDN integration or find out if your current plugin supports that.

        Michael Gathu
        NetDNA™ Support Representative

    2. We use MaxCDN for Timthumb and it works just fine 😉 who did you talk to at MaxCDN/NetDNA? It doesnt work out of the box and when I initially talked to them about timthumb they were not to familiar with it.

      1. I spoke with Fred M, I guess he thought since its a .php script, it must need php to work?

        If it doesn’t work out of the box, how does it work then? What type of changes are required?


      2. Actually Ben it doesn’t work as you think it is. We have tested this with maxCDN and timthumb and wordpress. All it does is saves the original source image via the pull to the cdn. It doesnt actually pull the thumbnail – this is served by your webserver, then back to the cdn and then back to your browser. It appears as though it is coming from your CDN in the GET but its actually masked from the location of the reference to the thumb script.

        How can I tell?

        Well a prime example is reference a thumbnail image directly from your cdn – http://cdn.beaverjournal.com/wp-content/uploads/2011/03/planned_parenthood1.gif

        Its the source, not the thumb. You can’t perform an fopen on the cdn remotely, and you certainly can’t do a filetime() check to see if the cached image has expired.

        So, all you are effectively doing is generating thumbnails on the fly each time from your own webserver.

        Sorry to bear the bad news.

      3. Hey Michael. I think you have misunderstood what I am saying.

        To try to clarify if you are resizing images that are on the cdn then they will be loaded from your website (although not on the fly every time since they are cached!)

        However that’s exactly what I am suggesting you don’t do.

        What I am suggesting you do is host point to timthumb on the cdn and then use pull to store the image. So the image would look like: http://cdn.website.com/timthumb.php?src=XXXX

        In this case the image is cached on the cdn and doesn’t touch your website. You can see I am using it for the thumbnails on this website.

      4. Actually ben, i still think im right – and it is confusing to understand but we’ve done extensive testing on this. You assume the cached image is being served to you by the cdn but the cdn is actually pulling the cached image still from your site each time – why? because you are still running the php script on your webserver to find the cached file – which in your case is your local server (maxcdn doesnt run php). The script handles the filetime() of the cached images, which you can’t do from a remote host. The get request on your page says your cdn because that’s the initial connection.

        There are 2 ways to prove this. Rename your thumb script and then purge your super cache and refresh your homepage – i bet it wont be able to serve your thumbnails. With our solution below you can do exactly that and the thumbnails are still served from the cdn. Of course this will only work on thumbnails that have been pulled once before.

        The other way to prove this is that if you sftp into your pull zone, see if there is a cache folder with png’s in there which i doubt because you wont be able to fopen from your server to maxcdn.

        I’ve posted a proper solution below which in fact does pull a unique named jpg to the cdn thumbnail instead of requiring a hit on your thumb script each time.

      5. I like the idea of renaming TimThumb and seeing if things still remain cached and so I did that, and it still works great with the instructions I described above. I also emptied the cache directory and, 10 minutes later, the cache directory is still empty.

        I should point out that I don’t use maxcdn so perhaps there’s something different between their system and wpcdn, which is what I do use.

  6. Hi Ben,

    So I signed up for maxcdn and have been using it for few days and then I had issues… I think it was related to cache having different files on origin server and on edge servers. For some reason, I am suspecting that images are still cached on the origin server and not on CDN, how can I be sure of this? Even if I am using

    cdn.domain.com for images and the timthumb.php script, and delete the cache folder, script still creates the cache folder and I can see cache images showing up in there.

    Also, like above example from beaverjournal:


    Is it okay if its showing src= as the origin server rather than the cdn? Can both be from CDN?


    1. the src for timthumb should be the origin server and not the cdn. That way you don’t have to edit the script. There’s no problem with doing this and nothing will be loaded unless there is no cached file on the cdn itself. The only time the src parameter is used is when the cache file is generated. The cache file will always be created on your server, even if a cdn is used, however the files will not be accessed unless you disable the cdn.

  7. Hey, just do some htaccess url rewriting and Timthumb will work everything, as its url will look like a plain jpg url.

  8. Firstly thx for timthumb – really awesome 🙂

    I am following your advice on CDN. As we are in Australia I chose GoGrid as the times were far better with a local Sydney POP for a mostly Aussie audience.

    I am getting an error – Resource interpreted as Image but transferred with MIME type application/octet-stream for timthumb.php when I call it via CDN. Works fine locally in testing as has for a couple of months.

    Any help would be great – thx again

  9. I found this on the web and it works for us. We use maxcdn and timthumb – and you can test it by looking at this link (fyi the webserver cache folder is emptied nightly by a cron so we can prove it’s coming from the cdn directly): http://auction-cdn.marketnews.com.au/thumb/wp-content/uploads/7622-124ArgyleStreetSTKILDA-6.80×288.jpg

    Here is the instructions to get it working.

    Create a base folder of /thumb/ on your webserver inside the public_html root.
    Copy timthumb.php into that folder and rename to index.php
    Create /cache/ folder inside the thumb folder
    Create a .htaccess and put the code below into it

    To turn your TimThumb image paths from


    where /images/whatever.jpg is the actual image location and 150×150 is the dimensions you want to create

    just do the following.

    edit your newly renamed index.php (old thumb.php) and add this code right after the line ‘define(“version”, …’ which is near the top (line 20-ish)

    // Check for mod_rewrite style path
    if ($_GET[‘thumb’]) {

    // get the image and size
    $thumb = strip_tags(htmlspecialchars($_GET[‘thumb’]));
    $thumb_array = explode(‘.’,$thumb);
    $image = ‘../’;

    foreach($thumb_array as $k=>$thumb_part){
    if ($k != count($thumb_array)-2) {
    $image .= $thumb_part . ‘.’;

    $image = substr($image,0,-1);
    $size = $thumb_array[count($thumb_array)-2];

    list($width,$height) = explode(‘x’,$size);

    // set request vars so rest of script just works
    $_REQUEST[‘h’] = $width;
    $_REQUEST[‘w’] = $height;
    $_REQUEST[‘src’] = $image;

    Now in your newly created .htaccess file in the thumb folder, add the following to it

    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php?thumb=$1 [L,QSA]

    And bob is your uncle.

  10. hey Michael,

    now after you did this, did you take out the timthumb script from your theme/scripts folder or leave it?

    I just applied your suggestion, but haven’t changed anything else to be safe, and thumbs still coming from origin…link below

    Thanks for looking into this. It’s odd that MaxCDN doesn’t seem to acknowledge any fixes or workarounds for timthumb even though it’s in so many themes.


    1. Hi curt

      The image format was removed from my post so here it is again

      you generate thhe thumbs by

      img src=”http://cdn.domain.com/thumbs/path-from-root-to-image/imagename.90×120.jpg”

      What this does is loads index.php from the thumbs folder and then uses the heightxwidth inside the name of the original image to parse the dimensions of the crop. On the first time loaded it I’ll create a local cache but the imagename.90×120.jpg will be pulled to the cdn as a resized thumb. So the next access to the file will ignore coming to your server and just load the image from the cdn. You can then empty the local cache folder to test it is working properly, and if no thumbs are regenerated in the cache folder then you can be safe to assume it’s correctly coming from the cdn.

      1. I tried what you said but it’s not working for me. I am also using Maxcdn with Timthumb. Could you tell me what’s wrong as everytime i try to fetch image it says “no image specified
        Query String : thumb=http:/cdn.stylishandtrendy.com/wp-content/uploads/2011/05/dress-like-celebrities.200×200.jpg” with or without http://www.stylishandtrendy.com appended in front of wp-content/

  11. Hi there,
    thanks for this article. Has anyone managed to get this going with cloudfront?

    Im storing my master image on Amazon Cloudfront, but id’ also like the cached thumbnail there too (bypass expensive local hosting costs etc)

    Any help greatly appreciated


  12. Hi Daryl,

    I think I might have found a reasonably simple solution (quite similar to Michael’s solution, but perhaps even easier) that seems to work with cloudfront, and doesn’t require modifying timthumb.php

    Take a look at http://blog.gingerlime.com/thumbs-up

    Interested to know if it works for you

    1. Hello Daryl,

      It can only prettyfy your URL but it doesn’t work with CDN (Especially MaxCDN)

      1. Finally i quit TimThumb since wordpress default image thumbs are working much better. If you are a speed enthusiast that will be a much faster approach. I still love TimThumb and i will continue to use it across projects but not on WordPress.

  13. Pingback: thumbs up | Gingerlime
  14. Thanks,
    I didn’t really want to mess with that area either.

    Hmm – so there doesn’t seem to be a way to re-upload the generated cache file back to my AmazonS3 and let the files be referenced from there.

    Unfortunately defeats my CDN.

    Another issue, but maybe easier to solve:
    Ive noticed that when I request an external image, the entire external image is downloaded locally (“external_… .jpg”)as well as the generated cached file. This is filling up my local content store.

    Has anyone come across a way to stop the external image being downloaded in full and saved to the local website?

    Ideally the external image is looked up and ONLY the resized image is saved locally for delivery.

    thanks again

  15. Hi Ben, I have been trying to get my theme’s timthumb files to try and work with a CDN. I am just about ready to give up on this as Im having no luck. I have set up the thumb folder in my root as per Michael’s instructions above and it seems to be working fine to re-size the images. (see below)


    I have no idea on how to get my theme to spit out the images in this format. Is anyone able to help me???

    PHP code from theme is below.

    <a href="” rel=”bookmark” title=””><img src="/scripts/timthumb.php?src=&h=90&w=140&zc=1;&q=50″ width=”140″ height=”90″ alt=”” />

    If anyone can help it would be greatly appreciated.

  16. Good day.

    I have a WordPress blog in http://www.davaobase.com, where I’m using timthumb (saved in my account as thumb.php) in order to display the sliding panel images at the homepage.

    My problem is that for the 5 featured posts on the sliding panel, they all have the same thumbnail as processed by thumb.php.

    I already turned off my caching plugins and disabled CDN / Cloudflare, but the problem still persists. Any ideas?

    1. This sounds like a problem with your theme. You will need to talk to the theme developers to find out why it’s displaying the same image. TimThumb resizes the image that is given to it, and so in this case TimThumb is being given the same image 5 times 🙂

  17. Hi Ben,

    I’m a little confused here (thanks for helping create thumb.php though, I use it extensively), and I was hoping you could help.

    1) You mentioned that you were using your own website using thumb and a cdn. But when I checked on a category page i.e.; http://www.binarymoon.co.uk/category/web-design/timthumb/

    You can see that the image paths are eg:

    This is not using a CDN. Did you decide not to use it for thumb.php in the end? Was Michael right and that your method on this page is actually not using the cdn or in fact speeding up the loading of the image by effectively using i.e.;


    2) Basically I think we would all like to know the best and fastest way to display images using thumb.php & a CDN. Could you tell me if the method you gave in this posts works to this effect?

    3) or is Michael’s solution the right one? (I noticed Benjamin Kerensa is using his Method now)

    4) Or is there an even better method?

    Thanks for your help

    1. Hi – my method works fine, but it doesn’t mean it’s the best (or only) way. I have changed cdn system, and am now using cloudflare which is seamless and doesn’t really look like a cdn. I’d recommend giving it a shot (it’s free).

  18. Hi Ben,

    Thanks for the post, this discussion has been very helpful. Having tried many of the options above, and found the following worked for me.

    My requirements

    1. Use Tim Thumb with a CDN.
    2. Images stored in Amazon S3 bucket.
    3. Use a CDN pull-zone (I use MaxCDN).
    4. Can work server and client-side (I need to resize some images after the page has loaded).
    5. Minimal coding and modifications to TimThumb.

    So here’s what I did:

    1. Create folder at root called thumb.
    2. Paste in timthumb.php script and rename to index.php

    Seriously, that’s all the configuration (no custom .htaccess or code changes to timthumb.php at all).

    How to use

    Standard example:

    Client-side example (using jQuery):


    Here’s how it works (or so I believe):

    1. Request is made for image with:


    2. The CDN receives this request and because I have it configured as a pullzone (MaxCDN supports these as do may other CDNs), the request is passed to my originating server (www.mydomain.com).

    3. My domain now receives the request and Tim Thumb now goes to work. Tim Thumb processes this part of the original request:


    Note: this is in the format that Tim Thumb is expecting, so you can use any parameters you like that Tim Thumb can accept, e.g. (s,a,f,zc,etc…)

    4. Now because I want to pull my my images from Amazon S3 (instead of my web server) s3.mydomain.com is a reference to this (s3 is a subdomain that resolves to my bucket and can be configured in DNS). Note: this domain must be included as an allowed external site in Tim Thumb’s configuration.


    My testing has indicated that the first time an image is requested, Tim Thumb generates the image and caches it locally as expected. However, subsequent requests are pulled from the CDN network and this has been proven by deleting the cache files and even renaming or removing the /thumb/index.php file. In all cases, the images load, indicating they are in fact coming from the CDN servers (I’ve even inspected the CDN edge servers, and can see the files that it has cached, so I know it is working).


    1. I can use standard query string parameters to pass through to Tim Thumb only because Max CDN has an advanced option that treats query strings as a separate cacheable item. This is extremely useful and avoids having to use the clever trick used by Michael (above) to make each image url unique by including the height and with in the image filename. So with Max CDN, you don’t need to do this and are free to use all Tim Thumb parameters if you wish. This approach allows you to create multiple size thumbnails of the same source image, and the CDN will treat them all as if they were different images for caching purposes, e.g.


    are treated by MaxCDN as three images.

    2. With this approach, you don’t need to store your images in Amazon S3 (this just suits my purposes). You can equally reference images on your web server as well, e.g.

    Where the full image path would be:


    Sorry for the long explanation for what is quite simple in the end! I appreciate that this may not work with all CDNs (the support for query strings as separate cacheable items is the key that makes this possible).

    Hope this helps someone, and thanks to all previous posters for there efforts on this challenge.


  19. Ben,

    A couple of lines were omitted in the above example:

    “Standard example:”

    [img src=”http://cdn.mydomain.com/thumb/?src=http://s3.mydomain.com/images/myimage.jpg&w=640&h=480″ /]


    “2. With this approach, you don’t need to store your images in Amazon S3 (this just suits my purposes). You can equally reference images on your web server as well, e.g.”

    [img src=”http://cdn.mydomain.com/thumb/?src=/images/myimage.jpg&w=640&h=480″ /]

    Comment preview would be nice 🙂

  20. So I have been searching all over and can’t find a solution to my problem. I hope you or someone here can can help.

    W3 Total Cache and Amazon Cloudfront are causing duplicate content and cdn. aliases to show in Google SERPs which is a site wide penalization under the new Panda/Penguin.

    So it’s fine on my wordpress side but on my static files below the wordpress directory it is creating duplicate content in Google SERPs.

    For example, blog installation: http://mysite.com/blog/article/ *note the sub dir blog

    Problem is when I search using the Google site:mysite.com query I come up with a ton of duplicate files from my aliases cdn and cdn1 being indexed.

    Such as http://cdn.mysite.com and http://cdn1.mysite.com/page.php

    These pages are NOT in the WordPress installation sub directory and they are static HTML/PHP files created by me.

    So they are indexed, out of my control because W3 & Amazon somehow cached them. I can’t just no index because it won’t work that way via robots and Amazon. Also they are already indexed so that wouldn’t help. It would just stop them from being crawled in the future.

    I have a rel=”canonical” in my static pages meaning they also show on the cdn. pages however Google still has them indexed. I can’t 301 redirect because again it’s a mirror of my static pages, not something I uploaded and have access to.

    So what say ye?

    Last thing I have tried was verifying http://cdn.mysite.com in Webmaster Tools and it’s pending for a URL removal. But I’m scared Google may see that as remove http://mysite.com as well. I shall soon see.

    Another thing is in W3 it says Never cache the following pages: wp-.*\.php index\.php

    Which are clearly in my sub mysite.com/blog/ but how would I get it to never cache mysite.com/page.php

    Pleaseee say you have answers. And if you have any questions feel free to email me.

  21. Thank Ben, the Tim Thumb was make my setup real slow, now seem too work better …
    got many other issue to fix ..how can i speed the First Byte Time begin slow a bit…

    maybe an issue with cloudfare, maxcdn and my linode dedicated server

    anyone use that setup any tips


  22. Hi Ben,

    Firstly, thanks for this tutorial, and your work on TimThumb!

    I’ve managed to get CloudFront working perfectly with W3TC, and it requires no hacking. In fact, it’s just one more step to what you’ve highlighted above.

    In a nutshell, visit your CloudFront distribution settings page in your management console, and create a new behaviour to allow querystrings to be passed to patterns of */timthumb.php

    That’s it… the problem with cloudfront is that it doesn’t pass on querystrings by default, so if you’re not accesssing the timthumb.php file directly for images it’ll always strip out the necessary info for loading the right image etc.

    Hope that helps someone, here’s a more detailed explanation with some screenshots:


Leave a Reply to OaktownerCancel Reply

Your email address will not be published.