As a part of the August Cumulative Update for Internet Explorer, a small enhancement was made to Internet Explorer’s HTTP Cookie handling. This post describes that enhancement, and presents some other considerations for using cookies on your site. A knowledge base article referencing this change can be found here.
In the past, IE’s cookie jar stored a maximum of 20 cookies per domain. If more than 20 cookies were sent by the server, older cookies were automatically dropped by the browser. The dropped cookies could lead to lost website settings, an empty web shopping basket, or similar problems. In order to store more than 20 name-value pairs per domain, web developers were forced to create a “dictionary cookie”, a single cookie that contains multiple name-value pairs. Creation of dictionary cookies is described in this Knowledge Base article.
Note that IE’s cookie limit is applied on per-domain basis. If http://example.com sets 20 cookies, each with Domain=example.com, and http://subdomain.example.com also sets 20 cookies, each with Domain=subdomain.example.com, then 40 cookies will be sent on subsequent requests to subdomain.example.com.
New Cookie Limit
As a part of the Internet Explorer update announced yesterday, the cookies per domain limit has been increased from 20 to 50. This change was made to simplify the development and hosting of web applications on domains that use a large number of cookies.
Please note that even after installing this update, two other cookie limits remain unchanged:
- The DOM's document.cookie property will return an empty string if the current cookie string is longer than 4096 bytes
- Internet Explorer (and the WinINET HTTP stack) will ignore any Set-Cookie header if the header value's length exceeds 5118 bytes
For functionality and performance reasons (discussed next), it’s recommended that you continue to use the smallest cookies possible.
Watch Your Weight
You might be tempted to take advantage of the new higher cookie limit and add more cookies to your site. Unfortunately, cookies can dramatically impact the size of HTTP requests, slowing down the user’s browsing experience significantly. Many of today’s web users have connections with asymmetrical bandwidth, having download speeds 2 to 5 times faster than their upload speeds. This means that in some cases, HTTP request size is a more important factor than the size of the server’s response in determining overall transfer time.
There are three strategies you can use to minimize the impact of cookies on your site’s site performance:
- Minimize the size of your cookies
- Deliver static content from a different domain
- Use the Path attribute to send cookies only when necessary
The first strategy is simple: use the shortest cookie names and values possible. For instance, rather than naming a cookie USERNAME, name it U. The seven bytes saved might not sound like much, but multiplied over dozens or hundreds of requests, these savings can add up.
The second strategy can yield even better results, particularly if your pages use many static resources (images, CSS, JS, etc) that do not change based on the value of the visitor’s cookie. For instance, if you use the Fiddler Web Debugger to look at the Office Online clipart site, you’ll see that the static clipart images are delivered from http://officeimages.microsoft.com rather than http://office.microsoft.com. This means that the relatively large cookie set on office.microsoft.com isn’t sent when requesting each clipart thumbnail, saving more than 2K of request bytes per page of search results.
The last strategy is similar to the second, except that you can undertake it with just one domain. If you can keep all of your pages that need access to cookies within a single path (e.g. http://example.com/webapp/) you can use the Path attribute on the cookie to specify that the cookie should only be sent for requests within that path. This will ensure that requests sent outside of that path (e.g. http://example.com/images/) are not forced to carry unneeded cookies.
You can easily use Fiddler to monitor your uploaded cookie sizes. Inside Fiddler, click Rules > Customize Rules. Scroll down to OnBeforeResponse, and add the following line:
oSession["ui-customcolumn"] = oSession.oRequest["Cookie"].Length.ToString();
After you save the script, the size of the uploaded cookie (if any) for each request will be shown in the User-defined column at the far right side of the Web Sessions list.
Protecting Your Cookies
While you’re looking at your cookie code, you should determine if you need to expose your cookies to scripts running on your site. If your cookies are only used by your server, and your scripts don’t require access to your cookies, use the HttpOnly attribute to help protect your site against cookie theft via cross-site scripting attacks. Simply add the HttpOnly attribute to your Set-Cookie headers, and Internet Explorer will ensure that your cookie is not available to any script running in your pages. Cookies with the HttpOnly attribute are still sent in each HTTP request, but will not appear in the script-accessible document.cookies property. This means that if a hacker finds a cross-site scripting hole in your site, he cannot easily use the hole to steal logged-on visitors’ cookies.
Over the coming months, I’ll be posting more tips for developers. If you have any suggested topics, please leave me a comment below. Thanks!