Zoompf's Web Performance Blog

Note: Archived Content

This is the archived version of the Zoompf blog. Since our acquisition by Rigor, all our new research and posts on web performance are being published on The Rigor Blog

Performance Tip for HTTP Downloads

 Billy Hoffman on March 24, 2010. Category: Optimization

HTTPWatch has an interesting article today on their blog entitled “Four Tips for Setting up HTTP File Downloads.” They offer some great advice to make sure your downloadable files work across all browsers and are saved using the appropriate name. However they didn’t include a very important feature that all websites offering large file downloads should have: support for resumable downloads! As we will see this is an essential performance feature that improves user experience while reducing bandwidth costs.

Partial Downloads and the Range Header

HTTP/1.1 added many exciting features over HTTP/1.0. And while people are familiar with the more popular HTTP/1.1 performance enhancements such as default persistent connections or chunked encoding most are unaware of another performance enhancement: partial responses. HTTP/1.1 allows a client to request a certain piece of a resource. The client can use the Range header to tell the web server to serve only a subset of bytes from the total resource.

This seemingly odd and esoteric feature is actually quite powerful because it allows for browsers to resume HTTP downloads! Consider this scenario:

Diagram showing how a browser can use the Range header to resume an interrupted download

Here we see the browser is trying to download a large PDF file named “report.pdf” which is approximately 9 megabytes. The client issues an HTTP GET request and starts downloading the response. The web server used the Accept-Range header to indicated to the client that it allows for GET requests with the Range header to download pieces of this resource. After the client has downloaded a 2 megabytes, the browser experiences a problem. This could have been a caused by a number of issues. For example the computer might have momentary lost its network connection (common on wireless networks) or another program on the computer might have locked up and caused the browser’s connection to time out. Whatever the cause, the client had to close the HTTP connection it had with the web server. However, instead of having to redownload the entire PDF file, the client can use a range request to skip what it has already downloaded and only fetch the remaining data. The client does so by using a Range header to tell the web server to serve the contents of the PDF starting at the offset 2048000.

A few key points about resumable downloads and range requests:

  • Range requests allow the user to pause and resume the download inside their browser’s downloads window.
  • Resumable downloads can only work for static resources. They cannot be used with dynamically generated responses that change with each request or where you do not know the size of the resource ahead of time.
  • To indicate to the client that you allow range requests, you must send both a Content-Length response header and a Accept-Ranges response header.
  • IIS and Apache include the appropriate headers to support range requests by default when serving static files from the file system. These web servers will also automatically handle incoming Range header and serve the appropriate bytes.
  • If you are using PHP, ASP.NET, Ruby, or some other application logic to process the client’s request and deliver the downloaded file (as in /download.php?ID=123), you will need to manually add logic into your application code to handle range requests. This is not an easy task. Consider getting rid of your download handling application logic entirely and serve the file directly from the file system. This allows you to leverage the web server’s built in support for range requests.


Supporting resumable downloads is an easy way for you to save bandwidth while providing your users with a better browsing experience. You can view the HTTP headers for your downloadable resources to determine if you support resumable downloads using this service and making sure the “Show all server header fields” option is enabled. You can also use a browser plug-in like Live Headers to view the HTTP header coming from the server. Zoompf checks for this issue by looking for HTTP responses that have a Content-Disposition: attachment; header (indicating a downloadable file) but don’t have an Accept-Range header.

Want to see what performance problems your website has? Non-Resumable HTTP Download is just one of the 300+ web performance issues Zoompf detects when scanning your web application for performance issues. Get your instant free web performance assessment at Zoompf.com today!


Have some thoughts, a comment, or some feedback? Talk to us on Twitter @zoompf or use our contact us form.