Resource expiration

Customers often want to provide the time that a given resource or resource attribute is no longer useful or valid (e.g. a rotating security key). Currently we recommend that customers do this by specifying an exact "expiration time" into a google.protobuf.Timestamp expire_time field; however, this adds additional strain on the user when they want to specify a relative time offset until expiration rather than a specific time until expiration.

Furthermore, the world understands the concept of a "time-to-live", often abbreviated to TTL, but the typical format of this field (an integer, measured in seconds) results in a sub-par experience when using an auto-generated client library.


  1. APIs wishing to convey an expiration must rely on a google.protobuf.Timestamp field called expire_time.
  2. APIs wishing to allow a relative expiration time must define a oneof called expiration (or {something}_expiration) containing both the expire_time field and a separate google.protobuf.Duration field called ttl, the latter marked as input only.
  3. APIs must always return the expiration time in the expire_time field and leave the ttl field blank when retrieving the resource.
  4. APIs that rely on the specific semantics of a "time to live" (e.g., DNS which must represent the TTL as an integer) may use an int64 ttl field (and should provide an comment in this case).


message ExpiringResource {
  // google.api.resource and other annotations and fields

  oneof expiration {
    // Timestamp in UTC of when this resource is considered expired.
    // This is *always* provided on output, regardless of what was sent
    // on input.
    google.protobuf.Timestamp expire_time = 2;

    // Input only. The TTL for this resource.
    google.protobuf.Duration ttl = 3 [(google.api.field_behavior) = INPUT_ONLY];


Alternatives considered

A new standard field called ttl

We considered allowing a standard field called ttl as an alternative way of defining the expiration, however doing so would require that API services continually update the field, like a clock counting down. This could potentially cause problems with the read-modify-write lifecycle where a resource is being processed for some time, and effectively has its life extended as a result of that processing time.

Always use expire_time

This is the current state of the world with a few exceptions. In this scenario, we could potentially push the computation of now + ttl = expire_time into client libraries; however, this leads to a somewhat frustrating experience in the command-line and using REST/JSON. Leaving things as they are is typically the default, but it seems many customers want the ability to define relative expiration times as it is quite a bit easier and removes questions of time zones, stale clocks, and other silly mistakes.