RFC 2068                        HTTP/1.1                    January 1997


13.2.3 Age Calculations

   In order to know if a cached entry is fresh, a cache needs to know if
   its age exceeds its freshness lifetime. We discuss how to calculate
   the latter in section 13.2.4; this section describes how to calculate
   the age of a response or cache entry.

   In this discussion, we use the term "now" to mean "the current value
   of the clock at the host performing the calculation." Hosts that use
   HTTP, but especially hosts running origin servers and caches, should
   use NTP [28] or some similar protocol to synchronize their clocks to
   a globally accurate time standard.

   Also note that HTTP/1.1 requires origin servers to send a Date header
   with every response, giving the time at which the response was
   generated. We use the term "date_value" to denote the value of the
   Date header, in a form appropriate for arithmetic operations.

   HTTP/1.1 uses the Age response-header to help convey age information
   between caches. The Age header value is the sender's estimate of the
   amount of time since the response was generated at the origin server.
   In the case of a cached response that has been revalidated with the
   origin server, the Age value is based on the time of revalidation,
   not of the original response.

   In essence, the Age value is the sum of the time that the response
   has been resident in each of the caches along the path from the
   origin server, plus the amount of time it has been in transit along
   network paths.

   We use the term "age_value" to denote the value of the Age header, in
   a form appropriate for arithmetic operations.

   A response's age can be calculated in two entirely independent ways:

     1. now minus date_value, if the local clock is reasonably well
        synchronized to the origin server's clock. If the result is
        negative, the result is replaced by zero.

     2. age_value, if all of the caches along the response path
        implement HTTP/1.1.

   Given that we have two independent ways to compute the age of a
   response when it is received, we can combine these as

          corrected_received_age = max(now - date_value, age_value)

   and as long as we have either nearly synchronized clocks or all-



Fielding, et. al.           Standards Track                    [Page 77]

RFC 2068                        HTTP/1.1                    January 1997


   HTTP/1.1 paths, one gets a reliable (conservative) result.

   Note that this correction is applied at each HTTP/1.1 cache along the
   path, so that if there is an HTTP/1.0 cache in the path, the correct
   received age is computed as long as the receiving cache's clock is
   nearly in sync. We don't need end-to-end clock synchronization
   (although it is good to have), and there is no explicit clock
   synchronization step.

   Because of network-imposed delays, some significant interval may pass
   from the time that a server generates a response and the time it is
   received at the next outbound cache or client. If uncorrected, this
   delay could result in improperly low ages.

   Because the request that resulted in the returned Age value must have
   been initiated prior to that Age value's generation, we can correct
   for delays imposed by the network by recording the time at which the
   request was initiated. Then, when an Age value is received, it MUST
   be interpreted relative to the time the request was initiated, not
   the time that the response was received. This algorithm results in
   conservative behavior no matter how much delay is experienced. So, we
   compute:

         corrected_initial_age = corrected_received_age
                               + (now - request_time)

   where "request_time" is the time (according to the local clock) when
   the request that elicited this response was sent.

   Summary of age calculation algorithm, when a cache receives a
   response:

      /*
       * age_value
       *      is the value of Age: header received by the cache with
       *              this response.
       * date_value
       *      is the value of the origin server's Date: header
       * request_time
       *      is the (local) time when the cache made the request
       *              that resulted in this cached response
       * response_time
       *      is the (local) time when the cache received the
       *              response
       * now
       *      is the current (local) time
       */
      apparent_age = max(0, response_time - date_value);



Fielding, et. al.           Standards Track                    [Page 78]

RFC 2068                        HTTP/1.1                    January 1997


      corrected_received_age = max(apparent_age, age_value);
      response_delay = response_time - request_time;
      corrected_initial_age = corrected_received_age + response_delay;
      resident_time = now - response_time;
      current_age   = corrected_initial_age + resident_time;

   When a cache sends a response, it must add to the
   corrected_initial_age the amount of time that the response was
   resident locally. It must then transmit this total age, using the Age
   header, to the next recipient cache.

     Note that a client cannot reliably tell that a response is first-
     hand, but the presence of an Age header indicates that a response
     is definitely not first-hand. Also, if the Date in a response is
     earlier than the client's local request time, the response is
     probably not first-hand (in the absence of serious clock skew).