Caching and Vary: Cookie header

527 views
Skip to first unread message

Thanos Diacakis

unread,
Mar 7, 2011, 11:23:55 AM3/7/11
to Django users
I have spent several hours researching this, and I'm stumped, so
perhaps I could tap into some collective wisdom:

I have a website whose page template includes a "Sign-In or Register"
link at the top. This is shown on pretty much every page. If the
user is already signed in, this is replaced with "Hello _username_ |
My Account". This is done by passing request.user to the template and
checking is_authenticated().

The problem is, that as soon as I touch request.user, the Vary: Cookie
header is tagged on, and that destroys caching. Every anonymous user
gets their own version of the page cached, which is almost pointless.

I'm trying to figure out a way that I can fully utilize the cache for
anonymous users (i.e. one instance of the rendered page in the cache)
and I'm OK for caching with Vary: Cookie for logged in users.

So, is there a way to figure out if the user is logged in or not,
without tripping the Vary: Cookie header, or is there a better way of
doing this altogether?

BTW, it seems that it is significantly faster (15x CPU time) to cache
a whole view, that to cache a fragment, so I'd like to avoid that if
possible.

Thanks

Thanos

Tom Evans

unread,
Mar 7, 2011, 12:43:17 PM3/7/11
to django...@googlegroups.com

If it is the same URL being visited by the anonymous users and the
authenticated users, then how is the upstream cache to determine which
version to send?

Or put it like this, you want to have anonymous users viewing the page
to not generate a 'Vary: cookie' header. This leads to the following
situation:

Anonymous user visits /contact-us/
Django generates the anonymous version of the page and delivers it,
with appropriate caching headers.
Upstream cache stores anonymous version in cache
Logged in user visits /contact-us/
Upstream cache intercepts the request, looks in its cache for an
appropriate hit, and delivers the anonymous page.

The basic thing here is that you cannot have your cake and eat it as
well. Either the page contains dynamic, user-specific content, in
which case vary on cookie, or it does not, in which case cache it.

If you want to deliver truly cache-able anonymous content, deliver it
on a different URL to your dynamic content.

Cheers

Tom

Thanos Diacakis

unread,
Mar 7, 2011, 2:20:30 PM3/7/11
to Django users
Doh - thanks.

I guess to keep the structure simple, I can set the page up for
anonymous users, fully cached and all, and then use AJAX to figure out
if they are logged in and tweak my header.

Thanos
Reply all
Reply to author
Forward
0 new messages