Skip to content

The Best Way to Use TimThumb with a CDN (and Why Amazon S3 Is Not so Good)

Speeding up a websites loading time is so good for so many reasons, so it’s understandable that people want to use a CDN (Content Delivery Network) to serve their images, however in the case of TimThumb there’s a right way and a wrong way. Below I am going to explain how I use a CDN to speed up TimThumb on Binary Moon.

Content Delivery Network?

A CDN or Content Delivery Network, is a method for serving website content. Your content (generally static files such as images, CSS and javascript) get uploaded to the CDN, and it then gets distributed to other servers on the network that are spread all around the world. Then, when a user tries to access a file, the CDN picks the server nearest to the user. This means that the content has less far to travel so the data will arrive in a nice timely fashion. In addition, since CDN’s serve static content, they are optimized for static files, which makes the process quicker still.

Note that technically Amazon S3 is not a true CDN. S3 was designed for content storage. The correct Amazon service to use for content delivery is Amazon CloudFront.

TimThumb and CDN’s

The problems start when you combine TimThumb with a CDN. The most common scenario is that a file is included in a TimThumb url as such (I am using an image I have on Amazon S3 as an example).


On the face of it this looks like it will work great, the image is hosted on Amazon and is being resized by TimThumb. Look closer and it’s not so good. The first time the image is requested the things happen in the following order:

  1. TimThumb loads on your server
  2. TimThumb requests the file from the CDN
  3. TimThumb caches the external file on your server
  4. TimThumb resizes the image
  5. TmThumb saves the cached image on your server

The second time the image is requested the following things happen:

  1. TimThumb loads on your server
  2. TimThumb loads the cached file from your server

Once the file is cached it is served entirely from your server and the CDN is bypassed, making it redundant. So how do we fix this?

TimThumb CDN, a solution

The first thing we need to do is look a little closer at how CDN’s work.

There are 2 ways of getting content onto a CDN. In the case of Amazon S3 (which as mentioned above isn’t a true CDN) you have to upload the files to the server manually. This is called a push server, since you are pushing the content on to the CDN. The second type of server is a pull server. In this case the server waits for a request for some content and, if it doesn’t have it already, pulls it from the original website and then stores it on the CDN.

We want to use a pull server.

The advantage with the pull server is that it doesn’t (always) need to know what the content it is storing is going to be. For instance with TimThumb the server can access the dynamic cropped url, see there is an image, and then store that image.

Here on Binary Moon I have set up a pull server to use If the pull server sees a request to then it will check for a stored file, grab the content it needs and then store it for serving later. This means that you can happily make use of TimThumb AND of CDNs.

W3 Total Cache

The easiest way I have found to move your images onto a pull server is using W3 Total Cache. Below is how I configured W3 Total Cache so that it would work with TimThumb.

  1. Download, install and enable the W3 Total Cache Plugin
  2. On the plugins General Settings page scroll down to ‘Content Delivery Network’ settings and then select from the Origin Pull section, either Mirror, or Mirror: NetDNA/ MaxCDN, then hit save.
  3. Go to the Content Delivery Network Settings page, scroll down to the Advanced Settings section, and then add *timthumb.php to the Theme file types to upload: field, and hit save.

A full W3 Total Cache Tutorial would take a lot longer, there’s loads of settings in there, but this should help get you started on the road to creating a site that caches your TimThumb images.

All of the images on Binary Moon are served from a CDN. Currently I am using For personal usage their prices are very reasonable (less than $10 a month). If you search around you will find there are actually quite a few cdn’s targeted towards bloggers but they have served me pretty well so far.

Check out more articles on TimThumb here.


TimThumb, Web Design

Ben View All

Ben is a lifelong Nintendo fan who also likes to build websites, and develop games. He also buys way too much Lego.

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

    • 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 and Couldn´t it lead to duplicated content?

    • 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.

  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 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.

    • 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! 🙂

  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.


    • 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…

    • 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.

      • 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 🙂

      • 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?


    • 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.

    • 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.

      • 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?


      • 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 –

        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.

      • 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:

        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.

      • 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.

      • 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 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?


    • 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. 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

  8. 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):×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.

  9. 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.


    • Hi curt

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

      you generate thhe thumbs by

      img src=”×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.

      • 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:/×200.jpg” with or without appended in front of wp-content/

  10. 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


  11. 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

    Interested to know if it works for you

    • Hello Daryl,

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

      • 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.

  12. Pingback: thumbs up | Gingerlime
  13. 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

  14. 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)×300.jpg

    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.

  15. Good day.

    I have a WordPress blog in, 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?

    • 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 🙂

  16. 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.;

    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

    • 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).

  17. 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 (

    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) 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.


  18. Ben,

    A couple of lines were omitted in the above example:

    “Standard example:”

    [img src=”″ /]


    “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=”″ /]

    Comment preview would be nice 🙂

  19. 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: *note the sub dir blog

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

    Such as and

    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 in Webmaster Tools and it’s pending for a URL removal. But I’m scared Google may see that as remove 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 but how would I get it to never cache

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

  20. Thank Ben, the Tim Thumb was make my setup real slow, now seem too work better …
    got many other issue to fix 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


  21. 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

Your email address will not be published. Required fields are marked *