Should I use Expires headers, Cache-Control headers, or both?

The Expires entity-header field gives the date/time after which the response is considered stale.

The Cache-Control general-header field is used to specify directives that MUST be obeyed by all caching mechanisms along the request/response chain.

The Expires header is a short form of 'Cache-Control: max-age=...', and is not obligatory to be obeyed. To ensure your rules work okay, use both of them: it will do no harm, really :)

Cheers!