Repository: knative/serving
Pull request #13202 (2022-08-11 15:35:43)

Refactor VolumeMountPath to Directory
<!-- Please include the 'why' behind your changes if no issue exists -->
## Proposed Changes

- Name refactoring
- Add exported const for Annotations filepath

knative-prow[bot]: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/knative/serving/pull/13202#" title="Author self-approved">davidhadas</a>*
**Once this PR has been reviewed and has the lgtm label**, please assign julz for approval by writing `/assign @julz` in a comment. For more information see:[The Kubernetes Code Review Process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process).

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=knative%2Fserving).

<details open>
Needs approval from an approver in each of these files:

- **[pkg/OWNERS](https://github.com/knative/serving/blob/main/pkg/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["julz"]} -->
davidhadas: /cc @rhuss @psschwei 

Patch:
diff --git a/OWNERS_ALIASES b/OWNERS_ALIASES
index 529327dc1..196409e33 100644
--- a/OWNERS_ALIASES
+++ b/OWNERS_ALIASES
@@ -67,9 +67,9 @@ aliases:
   - knative-test-reporter-robot
   - kvmware
   - lance
+  - matzew
   - n3wscott
   - pmorie
-  - psschwei
   - smoser-ibm
   - spencerdillard
   - thisisnotapril
@@ -77,8 +77,8 @@ aliases:
   - vaikas
   - zroubalik
   knative-release-leads:
-  - evankanderson
-  - psschwei
+  - dprotaso
+  - matzew
   knative-robots:
   - knative-automation
   - knative-prow-releaser-robot
@@ -179,6 +179,7 @@ aliases:
   - whaught
   serving-wg-leads:
   - dprotaso
+  - psschwei
   serving-writers:
   - dprotaso
   - julz
diff --git a/config/core/300-resources/configuration.yaml b/config/core/300-resources/configuration.yaml
index 1d54339c1..32403f36a 100644
--- a/config/core/300-resources/configuration.yaml
+++ b/config/core/300-resources/configuration.yaml
@@ -523,6 +523,10 @@ spec:
                             description: This is accessible behind a feature flag - kubernetes.podspec-hostaliases
                             type: object
                             x-kubernetes-preserve-unknown-fields: true
+                        idleTimeoutSeconds:
+                          description: IdleTimeoutSeconds is the maximum duration in seconds a request will be allowed to stay open while not receiving any bytes from the user's application. If unspecified, a system default will be provided.
+                          type: integer
+                          format: int64
                         imagePullSecrets:
                           description: 'ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. For example, in the case of docker, only DockerConfig type secrets are honored. More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod'
                           type: array
@@ -550,6 +554,10 @@ spec:
                           description: This is accessible behind a feature flag - kubernetes.podspec-priorityclassname
                           type: string
                           x-kubernetes-preserve-unknown-fields: true
+                        responseStartTimeoutSeconds:
+                          description: ResponseStartTimeoutSeconds is the maximum duration in seconds that the request routing layer will wait for a request delivered to a container to begin sending any network traffic.
+                          type: integer
+                          format: int64
                         runtimeClassName:
                           description: This is accessible behind a feature flag - kubernetes.podspec-runtimeclassname
                           type: string
@@ -566,7 +574,7 @@ spec:
                           description: 'ServiceAccountName is the name of the ServiceAccount to use to run this pod. More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/'
                           type: string
                         timeoutSeconds:
-                          description: TimeoutSeconds is the maximum duration in seconds that the request routing layer will wait for a request delivered to a container to begin replying (send network traffic). If unspecified, a system default will be provided.
+                          description: TimeoutSeconds is the maximum duration in seconds that the request instance is allowed to respond to a request. If unspecified, a system default will be provided.
                           type: integer
                           format: int64
                         tolerations:
diff --git a/config/core/300-resources/revision.yaml b/config/core/300-resources/revision.yaml
index c131e8e44..1183bbd50 100644
--- a/config/core/300-resources/revision.yaml
+++ b/config/core/300-resources/revision.yaml
@@ -502,6 +502,10 @@ spec:
                     description: This is accessible behind a feature flag - kubernetes.podspec-hostaliases
                     type: object
                     x-kubernetes-preserve-unknown-fields: true
+                idleTimeoutSeconds:
+                  description: IdleTimeoutSeconds is the maximum duration in seconds a request will be allowed to stay open while not receiving any bytes from the user's application. If unspecified, a system default will be provided.
+                  type: integer
+                  format: int64
                 imagePullSecrets:
                   description: 'ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. For example, in the case of docker, only DockerConfig type secrets are honored. More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod'
                   type: array
@@ -529,6 +533,10 @@ spec:
                   description: This is accessible behind a feature flag - kubernetes.podspec-priorityclassname
                   type: string
                   x-kubernetes-preserve-unknown-fields: true
+                responseStartTimeoutSeconds:
+                  description: ResponseStartTimeoutSeconds is the maximum duration in seconds that the request routing layer will wait for a request delivered to a container to begin sending any network traffic.
+                  type: integer
+                  format: int64
                 runtimeClassName:
                   description: This is accessible behind a feature flag - kubernetes.podspec-runtimeclassname
                   type: string
@@ -545,7 +553,7 @@ spec:
                   description: 'ServiceAccountName is the name of the ServiceAccount to use to run this pod. More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/'
                   type: string
                 timeoutSeconds:
-                  description: TimeoutSeconds is the maximum duration in seconds that the request routing layer will wait for a request delivered to a container to begin replying (send network traffic). If unspecified, a system default will be provided.
+                  description: TimeoutSeconds is the maximum duration in seconds that the request instance is allowed to respond to a request. If unspecified, a system default will be provided.
                   type: integer
                   format: int64
                 tolerations:
diff --git a/config/core/300-resources/service.yaml b/config/core/300-resources/service.yaml
index e3c6ead03..453a67da3 100644
--- a/config/core/300-resources/service.yaml
+++ b/config/core/300-resources/service.yaml
@@ -527,6 +527,10 @@ spec:
                             description: This is accessible behind a feature flag - kubernetes.podspec-hostaliases
                             type: object
                             x-kubernetes-preserve-unknown-fields: true
+                        idleTimeoutSeconds:
+                          description: IdleTimeoutSeconds is the maximum duration in seconds a request will be allowed to stay open while not receiving any bytes from the user's application. If unspecified, a system default will be provided.
+                          type: integer
+                          format: int64
                         imagePullSecrets:
                           description: 'ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. For example, in the case of docker, only DockerConfig type secrets are honored. More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod'
                           type: array
@@ -554,6 +558,10 @@ spec:
                           description: This is accessible behind a feature flag - kubernetes.podspec-priorityclassname
                           type: string
                           x-kubernetes-preserve-unknown-fields: true
+                        responseStartTimeoutSeconds:
+                          description: ResponseStartTimeoutSeconds is the maximum duration in seconds that the request routing layer will wait for a request delivered to a container to begin sending any network traffic.
+                          type: integer
+                          format: int64
                         runtimeClassName:
                           description: This is accessible behind a feature flag - kubernetes.podspec-runtimeclassname
                           type: string
@@ -570,7 +578,7 @@ spec:
                           description: 'ServiceAccountName is the name of the ServiceAccount to use to run this pod. More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/'
                           type: string
                         timeoutSeconds:
-                          description: TimeoutSeconds is the maximum duration in seconds that the request routing layer will wait for a request delivered to a container to begin replying (send network traffic). If unspecified, a system default will be provided.
+                          description: TimeoutSeconds is the maximum duration in seconds that the request instance is allowed to respond to a request. If unspecified, a system default will be provided.
                           type: integer
                           format: int64
                         tolerations:
diff --git a/config/core/configmaps/defaults.yaml b/config/core/configmaps/defaults.yaml
index bf0e037f1..38ea4a88d 100644
--- a/config/core/configmaps/defaults.yaml
+++ b/config/core/configmaps/defaults.yaml
@@ -22,7 +22,7 @@ metadata:
     app.kubernetes.io/component: controller
     app.kubernetes.io/version: devel
   annotations:
-    knative.dev/example-checksum: "a0feb4c6"
+    knative.dev/example-checksum: "4b3e0057"
 data:
   _example: |
     ################################
@@ -54,6 +54,16 @@ data:
     # should also be increased to prevent in-flight requests being disrupted.
     max-revision-timeout-seconds: "600"  # 10 minutes
 
+    # revision-response-start-timeout-seconds contains the default number of
+    # seconds a request will be allowed to stay open while waiting to
+    # receive any bytes from the user's application, if none is specified.
+    revision-response-start-timeout-seconds: "300"
+
+    # revision-idle-timeout-seconds contains the default number of
+    # seconds a request will be allowed to stay open while not receiving any
+    # bytes from the user's application, if none is specified.
+    revision-idle-timeout-seconds: "0"  # infinite
+
     # revision-cpu-request contains the cpu allocation to assign
     # to revisions by default.  If omitted, no value is specified
     # and the system default is used.
diff --git a/docs/serving-api.md b/docs/serving-api.md
index a92706304..26290a849 100644
--- a/docs/serving-api.md
+++ b/docs/serving-api.md
@@ -915,9 +915,37 @@ int64
 </td>
 <td>
 <em>(Optional)</em>
-<p>TimeoutSeconds is the maximum duration in seconds that the request routing
-layer will wait for a request delivered to a container to begin replying
-(send network traffic). If unspecified, a system default will be provided.</p>
+<p>TimeoutSeconds is the maximum duration in seconds that the request instance
+is allowed to respond to a request. If unspecified, a system default will
+be provided.</p>
+</td>
+</tr>
+<tr>
+<td>
+<code>responseStartTimeoutSeconds</code><br/>
+<em>
+int64
+</em>
+</td>
+<td>
+<em>(Optional)</em>
+<p>ResponseStartTimeoutSeconds is the maximum duration in seconds that the request
+routing layer will wait for a request delivered to a container to begin
+sending any network traffic.</p>
+</td>
+</tr>
+<tr>
+<td>
+<code>idleTimeoutSeconds</code><br/>
+<em>
+int64
+</em>
+</td>
+<td>
+<em>(Optional)</em>
+<p>IdleTimeoutSeconds is the maximum duration in seconds a request will be allowed
+to stay open while not receiving any bytes from the user&rsquo;s application. If
+unspecified, a system default will be provided.</p>
 </td>
 </tr>
 </table>
@@ -1377,9 +1405,37 @@ int64
 </td>
 <td>
 <em>(Optional)</em>
-<p>TimeoutSeconds is the maximum duration in seconds that the request routing
-layer will wait for a request delivered to a container to begin replying
-(send network traffic). If unspecified, a system default will be provided.</p>
+<p>TimeoutSeconds is the maximum duration in seconds that the request instance
+is allowed to respond to a request. If unspecified, a system default will
+be provided.</p>
+</td>
+</tr>
+<tr>
+<td>
+<code>responseStartTimeoutSeconds</code><br/>
+<em>
+int64
+</em>
+</td>
+<td>
+<em>(Optional)</em>
+<p>ResponseStartTimeoutSeconds is the maximum duration in seconds that the request
+routing layer will wait for a request delivered to a container to begin
+sending any network traffic.</p>
+</td>
+</tr>
+<tr>
+<td>
+<code>idleTimeoutSeconds</code><br/>
+<em>
+int64
+</em>
+</td>
+<td>
+<em>(Optional)</em>
+<p>IdleTimeoutSeconds is the maximum duration in seconds a request will be allowed
+to stay open while not receiving any bytes from the user&rsquo;s application. If
+unspecified, a system default will be provided.</p>
 </td>
 </tr>
 </tbody>
@@ -1577,9 +1633,37 @@ int64
 </td>
 <td>
 <em>(Optional)</em>
-<p>TimeoutSeconds is the maximum duration in seconds that the request routing
-layer will wait for a request delivered to a container to begin replying
-(send network traffic). If unspecified, a system default will be provided.</p>
+<p>TimeoutSeconds is the maximum duration in seconds that the request instance
+is allowed to respond to a request. If unspecified, a system default will
+be provided.</p>
+</td>
+</tr>
+<tr>
+<td>
+<code>responseStartTimeoutSeconds</code><br/>
+<em>
+int64
+</em>
+</td>
+<td>
+<em>(Optional)</em>
+<p>ResponseStartTimeoutSeconds is the maximum duration in seconds that the request
+routing layer will wait for a request delivered to a container to begin
+sending any network traffic.</p>
+</td>
+</tr>
+<tr>
+<td>
+<code>idleTimeoutSeconds</code><br/>
+<em>
+int64
+</em>
+</td>
+<td>
+<em>(Optional)</em>
+<p>IdleTimeoutSeconds is the maximum duration in seconds a request will be allowed
+to stay open while not receiving any bytes from the user&rsquo;s application. If
+unspecified, a system default will be provided.</p>
 </td>
 </tr>
 </table>
diff --git a/pkg/apis/config/defaults.go b/pkg/apis/config/defaults.go
index 9a33641b3..3168d210c 100644
--- a/pkg/apis/config/defaults.go
+++ b/pkg/apis/config/defaults.go
@@ -44,6 +44,14 @@ const (
 	// DefaultMaxRevisionTimeoutSeconds will be set if MaxRevisionTimeoutSeconds is not specified.
 	DefaultMaxRevisionTimeoutSeconds = 10 * 60
 
+	// DefaultRevisionResponseStartTimeoutSeconds will be set if ResponseStartTimeoutSeconds is not specified.
+	// for backward compatibility will keep default similar to DefaultRevisionTimeoutSeconds,
+	// should be revised in future releases.
+	DefaultRevisionResponseStartTimeoutSeconds = 5 * 60
+
+	// DefaultRevisionIdleTimeoutSeconds will be set if idleTimeoutSeconds not specified.
+	DefaultRevisionIdleTimeoutSeconds = 0
+
 	// DefaultInitContainerName is the default name we give to the init containers
 	// specified by the user, if `name:` is omitted.
 	DefaultInitContainerName = "init-container"
@@ -71,14 +79,16 @@ var (
 
 func defaultDefaultsConfig() *Defaults {
 	return &Defaults{
-		RevisionTimeoutSeconds:        DefaultRevisionTimeoutSeconds,
-		MaxRevisionTimeoutSeconds:     DefaultMaxRevisionTimeoutSeconds,
-		InitContainerNameTemplate:     DefaultInitContainerNameTemplate,
-		UserContainerNameTemplate:     DefaultUserContainerNameTemplate,
-		ContainerConcurrency:          DefaultContainerConcurrency,
-		ContainerConcurrencyMaxLimit:  DefaultMaxRevisionContainerConcurrency,
-		AllowContainerConcurrencyZero: DefaultAllowContainerConcurrencyZero,
-		EnableServiceLinks:            ptr.Bool(false),
+		RevisionTimeoutSeconds:             DefaultRevisionTimeoutSeconds,
+		MaxRevisionTimeoutSeconds:          DefaultMaxRevisionTimeoutSeconds,
+		RevisionRequestStartTimeoutSeconds: DefaultRevisionResponseStartTimeoutSeconds,
+		RevisionIdleTimeoutSeconds:         DefaultRevisionIdleTimeoutSeconds,
+		InitContainerNameTemplate:          DefaultInitContainerNameTemplate,
+		UserContainerNameTemplate:          DefaultUserContainerNameTemplate,
+		ContainerConcurrency:               DefaultContainerConcurrency,
+		ContainerConcurrencyMaxLimit:       DefaultMaxRevisionContainerConcurrency,
+		AllowContainerConcurrencyZero:      DefaultAllowContainerConcurrencyZero,
+		EnableServiceLinks:                 ptr.Bool(false),
 	}
 }
 
@@ -111,6 +121,9 @@ func NewDefaultsConfigFromMap(data map[string]string) (*Defaults, error) {
 
 		cm.AsInt64("revision-timeout-seconds", &nc.RevisionTimeoutSeconds),
 		cm.AsInt64("max-revision-timeout-seconds", &nc.MaxRevisionTimeoutSeconds),
+		cm.AsInt64("revision-response-start-timeout-seconds", &nc.RevisionRequestStartTimeoutSeconds),
+		cm.AsInt64("revision-idle-timeout-seconds", &nc.RevisionIdleTimeoutSeconds),
+
 		cm.AsInt64("container-concurrency", &nc.ContainerConcurrency),
 		cm.AsInt64("container-concurrency-max-limit", &nc.ContainerConcurrencyMaxLimit),
 
@@ -127,6 +140,12 @@ func NewDefaultsConfigFromMap(data map[string]string) (*Defaults, error) {
 	if nc.RevisionTimeoutSeconds > nc.MaxRevisionTimeoutSeconds {
 		return nil, fmt.Errorf("revision-timeout-seconds (%d) cannot be greater than max-revision-timeout-seconds (%d)", nc.RevisionTimeoutSeconds, nc.MaxRevisionTimeoutSeconds)
 	}
+	if nc.RevisionRequestStartTimeoutSeconds > 0 && nc.RevisionRequestStartTimeoutSeconds > nc.RevisionTimeoutSeconds {
+		return nil, fmt.Errorf("revision-response-start-timeout-seconds (%d) cannot be greater than revision-timeout-seconds (%d)", nc.RevisionRequestStartTimeoutSeconds, nc.RevisionTimeoutSeconds)
+	}
+	if nc.RevisionIdleTimeoutSeconds > 0 && nc.RevisionIdleTimeoutSeconds > nc.RevisionTimeoutSeconds {
+		return nil, fmt.Errorf("revision-idle-timeout-seconds (%d) cannot be greater than revision-timeout-seconds (%d)", nc.RevisionIdleTimeoutSeconds, nc.RevisionTimeoutSeconds)
+	}
 	if nc.ContainerConcurrencyMaxLimit < 1 {
 		return nil, apis.ErrOutOfBoundsValue(
 			nc.ContainerConcurrencyMaxLimit, 1, math.MaxInt32, "container-concurrency-max-limit")
@@ -157,6 +176,14 @@ type Defaults struct {
 	// RevisionTimeoutSeconds must be less than this value.
 	MaxRevisionTimeoutSeconds int64
 
+	// This is  the default number of seconds a request will be allowed to
+	// stay open while waiting to receive any bytes from the user's application
+	RevisionRequestStartTimeoutSeconds int64
+
+	// RevisionIdleTimeoutSeconds is the maximum duration in seconds a request
+	// will be allowed to stay open while not receiving any bytes from the user's application.
+	RevisionIdleTimeoutSeconds int64
+
 	InitContainerNameTemplate *ObjectMetaTemplate
 
 	UserContainerNameTemplate *ObjectMetaTemplate
diff --git a/pkg/apis/serving/v1/revision_types.go b/pkg/apis/serving/v1/revision_types.go
index 959d5e97a..a2a23c9ef 100644
--- a/pkg/apis/serving/v1/revision_types.go
+++ b/pkg/apis/serving/v1/revision_types.go
@@ -83,11 +83,23 @@ type RevisionSpec struct {
 	// +optional
 	ContainerConcurrency *int64 `json:"containerConcurrency,omitempty"`
 
-	// TimeoutSeconds is the maximum duration in seconds that the request routing
-	// layer will wait for a request delivered to a container to begin replying
-	// (send network traffic). If unspecified, a system default will be provided.
+	// TimeoutSeconds is the maximum duration in seconds that the request instance
+	// is allowed to respond to a request. If unspecified, a system default will
+	// be provided.
 	// +optional
 	TimeoutSeconds *int64 `json:"timeoutSeconds,omitempty"`
+
+	// ResponseStartTimeoutSeconds is the maximum duration in seconds that the request
+	// routing layer will wait for a request delivered to a container to begin
+	// sending any network traffic.
+	// +optional
+	ResponseStartTimeoutSeconds *int64 `json:"responseStartTimeoutSeconds,omitempty"`
+
+	// IdleTimeoutSeconds is the maximum duration in seconds a request will be allowed
+	// to stay open while not receiving any bytes from the user's application. If
+	// unspecified, a system default will be provided.
+	// +optional
+	IdleTimeoutSeconds *int64 `json:"idleTimeoutSeconds,omitempty"`
 }
 
 const (
diff --git a/pkg/apis/serving/v1/zz_generated.deepcopy.go b/pkg/apis/serving/v1/zz_generated.deepcopy.go
index 99ae1ca1d..c42bb4b92 100644
--- a/pkg/apis/serving/v1/zz_generated.deepcopy.go
+++ b/pkg/apis/serving/v1/zz_generated.deepcopy.go
@@ -230,6 +230,16 @@ func (in *RevisionSpec) DeepCopyInto(out *RevisionSpec) {
 		*out = new(int64)
 		**out = **in
 	}
+	if in.ResponseStartTimeoutSeconds != nil {
+		in, out := &in.ResponseStartTimeoutSeconds, &out.ResponseStartTimeoutSeconds
+		*out = new(int64)
+		**out = **in
+	}
+	if in.IdleTimeoutSeconds != nil {
+		in, out := &in.IdleTimeoutSeconds, &out.IdleTimeoutSeconds
+		*out = new(int64)
+		**out = **in
+	}
 	return
 }
 
diff --git a/pkg/http/handler/timeout.go b/pkg/http/handler/timeout.go
index e971c02de..a492c95c4 100644
--- a/pkg/http/handler/timeout.go
+++ b/pkg/http/handler/timeout.go
@@ -30,12 +30,12 @@ import (
 )
 
 type timeoutHandler struct {
-	handler            http.Handler
-	firstByteTimeout   time.Duration
-	idleTimeout        time.Duration
-	maxDurationTimeout time.Duration
-	body               string
-	clock              clock.Clock
+	handler              http.Handler
+	timeout              time.Duration
+	responseStartTimeout time.Duration
+	idleTimeout          time.Duration
+	body                 string
+	clock                clock.Clock
 }
 
 // NewTimeoutHandler returns a Handler that runs `h` with the
@@ -54,14 +54,14 @@ type timeoutHandler struct {
 // https://golang.org/pkg/net/http/#Handler.
 //
 // The implementation is largely inspired by http.TimeoutHandler.
-func NewTimeoutHandler(h http.Handler, msg string, firstByteTimeout time.Duration, idleTimeout time.Duration, maxDurationTimeout time.Duration) http.Handler {
+func NewTimeoutHandler(h http.Handler, msg string, timeout time.Duration, responseStartTimeout time.Duration, idleTimeout time.Duration) http.Handler {
 	return &timeoutHandler{
-		handler:            h,
-		body:               msg,
-		firstByteTimeout:   firstByteTimeout,
-		idleTimeout:        idleTimeout,
-		maxDurationTimeout: maxDurationTimeout,
-		clock:              clock.RealClock{},
+		handler:              h,
+		body:                 msg,
+		timeout:              timeout,
+		responseStartTimeout: responseStartTimeout,
+		idleTimeout:          idleTimeout,
+		clock:                clock.RealClock{},
 	}
 }
 
@@ -69,10 +69,10 @@ func (h *timeoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	ctx, cancel := context.WithCancel(r.Context())
 	defer cancel()
 
-	firstByteTimeout := getTimer(h.clock, h.firstByteTimeout)
-	var firstByteTimeoutDrained bool
+	timeout := getTimer(h.clock, h.timeout)
+	var timeoutDrained bool
 	defer func() {
-		putTimer(firstByteTimeout, firstByteTimeoutDrained)
+		putTimer(timeout, timeoutDrained)
 	}()
 
 	var idleTimeout clock.Timer
@@ -93,17 +93,17 @@ func (h *timeoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	done := make(chan interface{})
 	tw := &timeoutWriter{w: w, clock: h.clock}
 
-	var maxDurationTimeout clock.Timer
-	var maxDurationTimeoutDrained bool
-	if h.maxDurationTimeout > 0 {
-		maxDurationTimeout = getTimer(h.clock, h.maxDurationTimeout)
+	var responseStartTimeout clock.Timer
+	var responseStartTimeoutDrained bool
+	if h.responseStartTimeout > 0 {
+		responseStartTimeout = getTimer(h.clock, h.responseStartTimeout)
 		defer func() {
-			putTimer(maxDurationTimeout, maxDurationTimeoutDrained)
+			putTimer(responseStartTimeout, responseStartTimeoutDrained)
 		}()
 	}
-	var maxDurationTimeoutCh <-chan time.Time
-	if maxDurationTimeout != nil {
-		maxDurationTimeoutCh = maxDurationTimeout.C()
+	var responseStartTimeoutCh <-chan time.Time
+	if responseStartTimeout != nil {
+		responseStartTimeoutCh = responseStartTimeout.C()
 	}
 
 	go func() {
@@ -124,9 +124,9 @@ func (h *timeoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 				panic(p)
 			}
 			return
-		case <-firstByteTimeout.C():
-			firstByteTimeoutDrained = true
-			if tw.tryFirstByteTimeoutAndWriteError(h.body) {
+		case <-timeout.C():
+			timeoutDrained = true
+			if tw.tryTimeoutAndWriteError(h.body) {
 				return
 			}
 		case now := <-idleTimeoutCh:
@@ -136,10 +136,10 @@ func (h *timeoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 				return
 			}
 			idleTimeout.Reset(timeToNextTimeout)
-		case <-maxDurationTimeoutCh:
-			timedOut := tw.maxDurationTimeoutAndWriteError(h.body)
+		case <-responseStartTimeoutCh:
+			timedOut := tw.tryResponseStartTimeoutAndWriteError(h.body)
 			if timedOut {
-				maxDurationTimeoutDrained = true
+				responseStartTimeoutDrained = true
 				return
 			}
 		}
@@ -208,13 +208,31 @@ func (tw *timeoutWriter) WriteHeader(code int) {
 	tw.w.WriteHeader(code)
 }
 
-// tryFirstByteTimeoutAndWriteError writes an error to the responsewriter if
+// tryTimeoutAndWriteError writes an error to the responsewriter if
 // nothing has been written to the writer before. Returns whether
 // an error was written or not.
 //
 // If this writes an error, all subsequent calls to Write will
 // result in http.ErrHandlerTimeout.
-func (tw *timeoutWriter) tryFirstByteTimeoutAndWriteError(msg string) bool {
+func (tw *timeoutWriter) tryTimeoutAndWriteError(msg string) bool {
+	tw.mu.Lock()
+	defer tw.mu.Unlock()
+
+	if tw.lastWriteTime.IsZero() {
+		tw.timeoutAndWriteError(msg)
+		return true
+	}
+
+	return false
+}
+
+// tryResponseStartTimeoutAndWriteError writes an error to the responsewriter if
+// the response has not started responding before. Returns whether an error was
+// written or not.
+//
+// If this writes an error, all subsequent calls to Write will
+// result in http.ErrHandlerTimeout.
+func (tw *timeoutWriter) tryResponseStartTimeoutAndWriteError(msg string) bool {
 	tw.mu.Lock()
 	defer tw.mu.Unlock()
 
@@ -245,13 +263,6 @@ func (tw *timeoutWriter) tryIdleTimeoutAndWriteError(curTime time.Time, idleTime
 	return false, idleTimeout - timeSinceLastWrite
 }
 
-func (tw *timeoutWriter) maxDurationTimeoutAndWriteError(msg string) bool {
-	tw.mu.Lock()
-	defer tw.mu.Unlock()
-	tw.timeoutAndWriteError(msg)
-	return true
-}
-
 func (tw *timeoutWriter) timeoutAndWriteError(msg string) {
 	tw.w.WriteHeader(http.StatusGatewayTimeout)
 	io.WriteString(tw.w, msg)
diff --git a/pkg/queue/constants.go b/pkg/queue/constants.go
index 7c0d2dfaf..2e405ce78 100644
--- a/pkg/queue/constants.go
+++ b/pkg/queue/constants.go
@@ -28,18 +28,18 @@ const (
 	// accepted requests have been processed.
 	RequestQueueDrainPath = "/wait-for-drain"
 
-	// CertVolumeMountPath is the name of the directory path where certificates are stored.
-	CertVolumeMountPath = "/var/lib/knative/certs"
+	// CertDirectory is the name of the directory path where certificates are stored.
+	CertDirectory = "/var/lib/knative/certs"
 
-	// PodInfoVolumeMountPath is the name of the directory path where podinfo are stored.
-	PodInfoVolumeMountPath = "/etc/podinfo"
+	// PodInfoDirectory is the name of the directory path where podinfo are stored.
+	PodInfoDirectory = "/etc/podinfo"
 
-	// TokenVolumeMountPath is the name of the directory path where tokens are stored.
-	TokenVolumeMountPath = "/var/run/secrets/tokens"
+	// TokenDirectory is the name of the directory path where tokens are stored.
+	TokenDirectory = "/var/run/secrets/tokens"
 
-	// ConcurrencyStateTokenFilename is the file name of the concurency state in TokenVolumeMountPath.
+	// ConcurrencyStateTokenFilename is the file name of the concurency state in TokenDirectory.
 	ConcurrencyStateTokenFilename = "state-token"
 
-	// PodInfoAnnotationsFilename is the file name of the annotations in PodInfoVolumeMountPath.
+	// PodInfoAnnotationsFilename is the file name of the annotations in PodInfoDirectory.
 	PodInfoAnnotationsFilename = "annotations"
 )
diff --git a/pkg/queue/sharedmain/main.go b/pkg/queue/sharedmain/main.go
index 1f328c36a..2aed7e8c2 100644
--- a/pkg/queue/sharedmain/main.go
+++ b/pkg/queue/sharedmain/main.go
@@ -67,22 +67,27 @@ const (
 	drainSleepDuration = 30 * time.Second
 
 	// certPath is the path for the server certificate mounted by queue-proxy.
-	certPath = queue.CertVolumeMountPath + "/" + certificates.SecretCertKey
+	certPath = queue.CertDirectory + "/" + certificates.SecretCertKey
 
 	// keyPath is the path for the server certificate key mounted by queue-proxy.
-	keyPath = queue.CertVolumeMountPath + "/" + certificates.SecretPKKey
+	keyPath = queue.CertDirectory + "/" + certificates.SecretPKKey
+
+	// PodInfoAnnotationsPath is an exported path for the annotations file
+	// This path is used by QP Options (Extensions).
+	PodInfoAnnotationsPath = queue.PodInfoDirectory + "/" + queue.PodInfoAnnotationsFilename
 )
 
 type config struct {
-	ContainerConcurrency     int    `split_words:"true" required:"true"`
-	QueueServingPort         string `split_words:"true" required:"true"`
-	QueueServingTLSPort      string `split_words:"true" required:"true"`
-	UserPort                 string `split_words:"true" required:"true"`
-	RevisionTimeoutSeconds   int    `split_words:"true" required:"true"`
-	MaxDurationSeconds       int    `split_words:"true"` // optional
-	ServingReadinessProbe    string `split_words:"true"` // optional
-	EnableProfiling          bool   `split_words:"true"` // optional
-	EnableHTTP2AutoDetection bool   `split_words:"true"` // optional
+	ContainerConcurrency                int    `split_words:"true" required:"true"`
+	QueueServingPort                    string `split_words:"true" required:"true"`
+	QueueServingTLSPort                 string `split_words:"true" required:"true"`
+	UserPort                            string `split_words:"true" required:"true"`
+	RevisionTimeoutSeconds              int    `split_words:"true" required:"true"`
+	RevisionResponseStartTimeoutSeconds int    `split_words:"true"` // optional
+	RevisionIdleTimeoutSeconds          int    `split_words:"true"` // optional
+	ServingReadinessProbe               string `split_words:"true"` // optional
+	EnableProfiling                     bool   `split_words:"true"` // optional
+	EnableHTTP2AutoDetection            bool   `split_words:"true"` // optional
 
 	// Logging configuration
 	ServingLoggingConfig         string `split_words:"true" required:"true"`
@@ -336,12 +341,15 @@ func buildServer(ctx context.Context, env config, transport http.RoundTripper, p
 	metricsSupported := supportsMetrics(ctx, logger, env, enableTLS)
 	tracingEnabled := env.TracingConfigBackend != tracingconfig.None
 	concurrencyStateEnabled := env.ConcurrencyStateEndpoint != ""
-	firstByteTimeout := time.Duration(env.RevisionTimeoutSeconds) * time.Second
-	// hardcoded to always disable idle timeout for now, will expose this later
+	timeout := time.Duration(env.RevisionTimeoutSeconds) * time.Second
+	var responseStartTimeout time.Duration
+	if env.RevisionResponseStartTimeoutSeconds != 0 {
+		responseStartTimeout = time.Duration(env.RevisionResponseStartTimeoutSeconds) * time.Second
+	}
 	var idleTimeout time.Duration
-
-	maxDurationTimeout := time.Duration(env.MaxDurationSeconds) * time.Second
-
+	if env.RevisionIdleTimeoutSeconds != 0 {
+		idleTimeout = time.Duration(env.RevisionIdleTimeoutSeconds) * time.Second
+	}
 	// Create queue handler chain.
 	// Note: innermost handlers are specified first, ie. the last handler in the chain will be executed first.
 	var composedHandler http.Handler = httpProxy
@@ -361,7 +369,7 @@ func buildServer(ctx context.Context, env config, transport http.RoundTripper, p
 	}
 	composedHandler = queue.ProxyHandler(breaker, stats, tracingEnabled, composedHandler)
 	composedHandler = queue.ForwardedShimHandler(composedHandler)
-	composedHandler = handler.NewTimeoutHandler(composedHandler, "request timeout", firstByteTimeout, idleTimeout, maxDurationTimeout)
+	composedHandler = handler.NewTimeoutHandler(composedHandler, "request timeout", timeout, responseStartTimeout, idleTimeout)
 
 	if metricsSupported {
 		composedHandler = requestMetricsHandler(logger, composedHandler, env)
diff --git a/pkg/reconciler/revision/resources/deploy.go b/pkg/reconciler/revision/resources/deploy.go
index e9153de87..cf4a307ee 100644
--- a/pkg/reconciler/revision/resources/deploy.go
+++ b/pkg/reconciler/revision/resources/deploy.go
@@ -73,7 +73,7 @@ var (
 	}
 
 	varCertVolumeMount = corev1.VolumeMount{
-		MountPath: queue.CertVolumeMountPath,
+		MountPath: queue.CertDirectory,
 		Name:      certVolumeName,
 		ReadOnly:  true,
 	}
@@ -81,7 +81,7 @@ var (
 	//nolint:gosec // VolumeMount, not hardcoded credentials
 	varTokenVolumeMount = corev1.VolumeMount{
 		Name:      varTokenVolume.Name,
-		MountPath: queue.TokenVolumeMountPath,
+		MountPath: queue.TokenDirectory,
 	}
 
 	varPodInfoVolume = corev1.Volume{
@@ -100,7 +100,7 @@ var (
 
 	varPodInfoVolumeMount = corev1.VolumeMount{
 		Name:      varPodInfoVolume.Name,
-		MountPath: queue.PodInfoVolumeMountPath,
+		MountPath: queue.PodInfoDirectory,
 		ReadOnly:  true,
 	}
 
diff --git a/pkg/reconciler/revision/resources/queue.go b/pkg/reconciler/revision/resources/queue.go
index c45ecac13..e65f30f96 100644
--- a/pkg/reconciler/revision/resources/queue.go
+++ b/pkg/reconciler/revision/resources/queue.go
@@ -198,6 +198,14 @@ func makeQueueContainer(rev *v1.Revision, cfg *config.Config) (*corev1.Container
 	if rev.Spec.TimeoutSeconds != nil {
 		ts = *rev.Spec.TimeoutSeconds
 	}
+	responseStartTimeout := int64(0)
+	if rev.Spec.ResponseStartTimeoutSeconds != nil {
+		responseStartTimeout = *rev.Spec.ResponseStartTimeoutSeconds
+	}
+	idleTimeout := int64(0)
+	if rev.Spec.IdleTimeoutSeconds != nil {
+		idleTimeout = *rev.Spec.IdleTimeoutSeconds
+	}
 	ports := queueNonServingPorts
 	if cfg.Observability.EnableProfiling {
 		ports = append(ports, profilingPort)
@@ -283,6 +291,12 @@ func makeQueueContainer(rev *v1.Revision, cfg *config.Config) (*corev1.Container
 		}, {
 			Name:  "REVISION_TIMEOUT_SECONDS",
 			Value: strconv.Itoa(int(ts)),
+		}, {
+			Name:  "REVISION_RESPONSE_START_TIMEOUT_SECONDS",
+			Value: strconv.Itoa(int(responseStartTimeout)),
+		}, {
+			Name:  "REVISION_IDLE_TIMEOUT_SECONDS",
+			Value: strconv.Itoa(int(idleTimeout)),
 		}, {
 			Name: "SERVING_POD",
 			ValueFrom: &corev1.EnvVarSource{
@@ -350,7 +364,7 @@ func makeQueueContainer(rev *v1.Revision, cfg *config.Config) (*corev1.Container
 			Value: cfg.Deployment.ConcurrencyStateEndpoint,
 		}, {
 			Name:  "CONCURRENCY_STATE_TOKEN_PATH",
-			Value: path.Join(queue.TokenVolumeMountPath, queue.ConcurrencyStateTokenFilename),
+			Value: path.Join(queue.TokenDirectory, queue.ConcurrencyStateTokenFilename),
 		}, {
 			Name: "HOST_IP",
 			ValueFrom: &corev1.EnvVarSource{


Test patch:
diff --git a/pkg/apis/config/defaults_test.go b/pkg/apis/config/defaults_test.go
index f6128424b..695d7d077 100644
--- a/pkg/apis/config/defaults_test.go
+++ b/pkg/apis/config/defaults_test.go
@@ -73,35 +73,40 @@ func TestDefaultsConfiguration(t *testing.T) {
 		name:    "specified values",
 		wantErr: false,
 		wantDefaults: &Defaults{
-			RevisionTimeoutSeconds:       123,
-			MaxRevisionTimeoutSeconds:    456,
-			ContainerConcurrencyMaxLimit: 1984,
-			RevisionCPURequest:           &oneTwoThree,
-			UserContainerNameTemplate:    mustParseTemplate("{{.Name}}"),
-			InitContainerNameTemplate:    mustParseTemplate("{{.Name}}"),
-			EnableServiceLinks:           ptr.Bool(true),
+			RevisionTimeoutSeconds:             123,
+			MaxRevisionTimeoutSeconds:          456,
+			RevisionRequestStartTimeoutSeconds: 60,
+			RevisionIdleTimeoutSeconds:         123,
+			ContainerConcurrencyMaxLimit:       1984,
+			RevisionCPURequest:                 &oneTwoThree,
+			UserContainerNameTemplate:          mustParseTemplate("{{.Name}}"),
+			InitContainerNameTemplate:          mustParseTemplate("{{.Name}}"),
+			EnableServiceLinks:                 ptr.Bool(true),
 		},
 		data: map[string]string{
-			"revision-timeout-seconds":         "123",
-			"max-revision-timeout-seconds":     "456",
-			"revision-cpu-request":             "123m",
-			"container-concurrency-max-limit":  "1984",
-			"container-name-template":          "{{.Name}}",
-			"init-container-name-template":     "{{.Name}}",
-			"allow-container-concurrency-zero": "false",
-			"enable-service-links":             "true",
+			"revision-timeout-seconds":                "123",
+			"max-revision-timeout-seconds":            "456",
+			"revision-response-start-timeout-seconds": "60",
+			"revision-idle-timeout-seconds":           "123",
+			"revision-cpu-request":                    "123m",
+			"container-concurrency-max-limit":         "1984",
+			"container-name-template":                 "{{.Name}}",
+			"init-container-name-template":            "{{.Name}}",
+			"allow-container-concurrency-zero":        "false",
+			"enable-service-links":                    "true",
 		},
 	}, {
 		name:    "service links false",
 		wantErr: false,
 		wantDefaults: &Defaults{
-			RevisionTimeoutSeconds:        DefaultRevisionTimeoutSeconds,
-			MaxRevisionTimeoutSeconds:     DefaultMaxRevisionTimeoutSeconds,
-			InitContainerNameTemplate:     DefaultInitContainerNameTemplate,
-			UserContainerNameTemplate:     DefaultUserContainerNameTemplate,
-			ContainerConcurrencyMaxLimit:  DefaultMaxRevisionContainerConcurrency,
-			AllowContainerConcurrencyZero: true,
-			EnableServiceLinks:            ptr.Bool(false),
+			RevisionTimeoutSeconds:             DefaultRevisionTimeoutSeconds,
+			MaxRevisionTimeoutSeconds:          DefaultMaxRevisionTimeoutSeconds,
+			RevisionRequestStartTimeoutSeconds: DefaultRevisionResponseStartTimeoutSeconds,
+			InitContainerNameTemplate:          DefaultInitContainerNameTemplate,
+			UserContainerNameTemplate:          DefaultUserContainerNameTemplate,
+			ContainerConcurrencyMaxLimit:       DefaultMaxRevisionContainerConcurrency,
+			AllowContainerConcurrencyZero:      true,
+			EnableServiceLinks:                 ptr.Bool(false),
 		},
 		data: map[string]string{
 			"enable-service-links": "false",
@@ -110,13 +115,14 @@ func TestDefaultsConfiguration(t *testing.T) {
 		name:    "service links default",
 		wantErr: false,
 		wantDefaults: &Defaults{
-			RevisionTimeoutSeconds:        DefaultRevisionTimeoutSeconds,
-			MaxRevisionTimeoutSeconds:     DefaultMaxRevisionTimeoutSeconds,
-			InitContainerNameTemplate:     DefaultInitContainerNameTemplate,
-			UserContainerNameTemplate:     DefaultUserContainerNameTemplate,
-			ContainerConcurrencyMaxLimit:  DefaultMaxRevisionContainerConcurrency,
-			AllowContainerConcurrencyZero: true,
-			EnableServiceLinks:            nil,
+			RevisionTimeoutSeconds:             DefaultRevisionTimeoutSeconds,
+			MaxRevisionTimeoutSeconds:          DefaultMaxRevisionTimeoutSeconds,
+			RevisionRequestStartTimeoutSeconds: DefaultRevisionResponseStartTimeoutSeconds,
+			InitContainerNameTemplate:          DefaultInitContainerNameTemplate,
+			UserContainerNameTemplate:          DefaultUserContainerNameTemplate,
+			ContainerConcurrencyMaxLimit:       DefaultMaxRevisionContainerConcurrency,
+			AllowContainerConcurrencyZero:      true,
+			EnableServiceLinks:                 nil,
 		},
 		data: map[string]string{
 			"enable-service-links": "default",
@@ -139,6 +145,12 @@ func TestDefaultsConfiguration(t *testing.T) {
 		data: map[string]string{
 			"max-revision-timeout-seconds": "asdf",
 		},
+	}, {
+		name:    "bad revision idle timeout",
+		wantErr: true,
+		data: map[string]string{
+			"revision-idle-timeout-seconds": "asdf",
+		},
 	}, {
 		name:    "bad name template",
 		wantErr: true,
@@ -158,6 +170,20 @@ func TestDefaultsConfiguration(t *testing.T) {
 			"revision-timeout-seconds":     "456",
 			"max-revision-timeout-seconds": "123",
 		},
+	}, {
+		name:    "revision request start timeout bigger than revision timeout",
+		wantErr: true,
+		data: map[string]string{
+			"revision-timeout-seconds":                "123",
+			"revision-response-start-timeout-seconds": "456",
+		},
+	}, {
+		name:    "revision idle timeout bigger than revision timeout",
+		wantErr: true,
+		data: map[string]string{
+			"revision-timeout-seconds":      "123",
+			"revision-idle-timeout-seconds": "456",
+		},
 	}, {
 		name:    "container-concurrency is bigger than default DefaultMaxRevisionContainerConcurrency",
 		wantErr: true,
@@ -182,13 +208,14 @@ func TestDefaultsConfiguration(t *testing.T) {
 		name:    "different user and init container name template values",
 		wantErr: false,
 		wantDefaults: &Defaults{
-			RevisionTimeoutSeconds:        DefaultRevisionTimeoutSeconds,
-			MaxRevisionTimeoutSeconds:     DefaultMaxRevisionTimeoutSeconds,
-			ContainerConcurrencyMaxLimit:  DefaultMaxRevisionContainerConcurrency,
-			AllowContainerConcurrencyZero: DefaultAllowContainerConcurrencyZero,
-			EnableServiceLinks:            ptr.Bool(false),
-			UserContainerNameTemplate:     mustParseTemplate("{{.Name}}"),
-			InitContainerNameTemplate:     mustParseTemplate("my-template"),
+			RevisionTimeoutSeconds:             DefaultRevisionTimeoutSeconds,
+			MaxRevisionTimeoutSeconds:          DefaultMaxRevisionTimeoutSeconds,
+			RevisionRequestStartTimeoutSeconds: DefaultRevisionResponseStartTimeoutSeconds,
+			ContainerConcurrencyMaxLimit:       DefaultMaxRevisionContainerConcurrency,
+			AllowContainerConcurrencyZero:      DefaultAllowContainerConcurrencyZero,
+			EnableServiceLinks:                 ptr.Bool(false),
+			UserContainerNameTemplate:          mustParseTemplate("{{.Name}}"),
+			InitContainerNameTemplate:          mustParseTemplate("my-template"),
 		},
 		data: map[string]string{
 			"container-name-template":      "{{.Name}}",
diff --git a/pkg/apis/serving/v1/revision_defaults_test.go b/pkg/apis/serving/v1/revision_defaults_test.go
index 4375ecb39..e56ec9c52 100644
--- a/pkg/apis/serving/v1/revision_defaults_test.go
+++ b/pkg/apis/serving/v1/revision_defaults_test.go
@@ -76,7 +76,7 @@ func TestRevisionDefaulting(t *testing.T) {
 					Name: config.DefaultsConfigName,
 				},
 				Data: map[string]string{
-					"revision-timeout-seconds": "123",
+					"revision-timeout-seconds": "423",
 				},
 			})
 
@@ -85,7 +85,7 @@ func TestRevisionDefaulting(t *testing.T) {
 		want: &Revision{
 			Spec: RevisionSpec{
 				ContainerConcurrency: ptr.Int64(0),
-				TimeoutSeconds:       ptr.Int64(123),
+				TimeoutSeconds:       ptr.Int64(423),
 				PodSpec: corev1.PodSpec{
 					Containers: []corev1.Container{{
 						Name:           config.DefaultUserContainerName,
@@ -107,7 +107,7 @@ func TestRevisionDefaulting(t *testing.T) {
 					Name: config.DefaultsConfigName,
 				},
 				Data: map[string]string{
-					"revision-timeout-seconds": "123",
+					"revision-timeout-seconds": "323",
 				},
 			})
 
@@ -116,7 +116,7 @@ func TestRevisionDefaulting(t *testing.T) {
 		want: &Revision{
 			Spec: RevisionSpec{
 				ContainerConcurrency: ptr.Int64(0),
-				TimeoutSeconds:       ptr.Int64(123),
+				TimeoutSeconds:       ptr.Int64(323),
 				PodSpec: corev1.PodSpec{
 					EnableServiceLinks: ptr.Bool(false),
 					Containers: []corev1.Container{{
diff --git a/pkg/apis/serving/v1/revision_validation_test.go b/pkg/apis/serving/v1/revision_validation_test.go
index 18735b693..916662f60 100644
--- a/pkg/apis/serving/v1/revision_validation_test.go
+++ b/pkg/apis/serving/v1/revision_validation_test.go
@@ -439,7 +439,9 @@ func TestRevisionSpecValidation(t *testing.T) {
 					Image: "helloworld",
 				}},
 			},
-			TimeoutSeconds: ptr.Int64(100),
+			TimeoutSeconds:              ptr.Int64(100),
+			ResponseStartTimeoutSeconds: ptr.Int64(0),
+			IdleTimeoutSeconds:          ptr.Int64(0),
 		},
 		wc: func(ctx context.Context) context.Context {
 			s := config.NewStore(logtesting.TestLogger(t))
@@ -450,8 +452,10 @@ func TestRevisionSpecValidation(t *testing.T) {
 					Name: config.DefaultsConfigName,
 				},
 				Data: map[string]string{
-					"revision-timeout-seconds":     "25",
-					"max-revision-timeout-seconds": "50"},
+					"revision-timeout-seconds":                "25",
+					"max-revision-timeout-seconds":            "50",
+					"revision-response-start-timeout-seconds": "10",
+					"revision-idle-timeout-seconds":           "10"},
 			})
 			return s.ToContext(ctx)
 		},
@@ -534,7 +538,9 @@ func TestImmutableFields(t *testing.T) {
 						Image: "helloworld",
 					}},
 				},
-				TimeoutSeconds: ptr.Int64(100),
+				TimeoutSeconds:              ptr.Int64(100),
+				ResponseStartTimeoutSeconds: ptr.Int64(0),
+				IdleTimeoutSeconds:          ptr.Int64(0),
 			},
 		},
 		old: &Revision{
@@ -547,7 +553,9 @@ func TestImmutableFields(t *testing.T) {
 						Image: "helloworld",
 					}},
 				},
-				TimeoutSeconds: ptr.Int64(100),
+				TimeoutSeconds:              ptr.Int64(100),
+				ResponseStartTimeoutSeconds: ptr.Int64(0),
+				IdleTimeoutSeconds:          ptr.Int64(0),
 			},
 		},
 		wc: func(ctx context.Context) context.Context {
@@ -559,8 +567,10 @@ func TestImmutableFields(t *testing.T) {
 					Name: config.DefaultsConfigName,
 				},
 				Data: map[string]string{
-					"revision-timeout-seconds":     "25",
-					"max-revision-timeout-seconds": "50"},
+					"revision-timeout-seconds":                "25",
+					"max-revision-timeout-seconds":            "50",
+					"revision-response-start-timeout-seconds": "10",
+					"revision-idle-timeout-seconds":           "10"},
 			})
 			return s.ToContext(ctx)
 		},
diff --git a/pkg/http/handler/timeout_test.go b/pkg/http/handler/timeout_test.go
index 061134b59..ec0205d96 100644
--- a/pkg/http/handler/timeout_test.go
+++ b/pkg/http/handler/timeout_test.go
@@ -33,7 +33,8 @@ func TestTimeoutWriterAllowsForAdditionalWritesBeforeTimeout(t *testing.T) {
 	clock := clock.RealClock{}
 	handler := &timeoutWriter{w: recorder, clock: clock}
 	handler.WriteHeader(http.StatusOK)
-	handler.tryFirstByteTimeoutAndWriteError("error")
+	handler.tryTimeoutAndWriteError("error")
+	handler.tryResponseStartTimeoutAndWriteError("error")
 	handler.tryIdleTimeoutAndWriteError(clock.Now(), 10*time.Second, "error")
 	if _, err := io.WriteString(handler, "test"); err != nil {
 		t.Fatalf("handler.Write() = %v, want no error", err)
@@ -78,16 +79,16 @@ func TestTimeoutWriterErrorsWriteAfterTimeout(t *testing.T) {
 }
 
 type timeoutHandlerTestScenario struct {
-	name               string
-	firstByteTimeout   time.Duration
-	idleTimeout        time.Duration
-	maxDurationTimeout time.Duration
-	handler            func(clock *clock.FakeClock, mux *sync.Mutex, writeErrors chan error) http.Handler
-	timeoutMessage     string
-	wantStatus         int
-	wantBody           string
-	wantWriteError     bool
-	wantPanic          bool
+	name                 string
+	timeout              time.Duration
+	responseStartTimeout time.Duration
+	idleTimeout          time.Duration
+	handler              func(clock *clock.FakeClock, mux *sync.Mutex, writeErrors chan error) http.Handler
+	timeoutMessage       string
+	wantStatus           int
+	wantBody             string
+	wantWriteError       bool
+	wantPanic            bool
 }
 
 // This has to be global as the timer cache would otherwise return timers from another clock.
@@ -103,12 +104,12 @@ func testTimeoutScenario(t *testing.T, scenarios []timeoutHandlerTestScenario) {
 			rr := httptest.NewRecorder()
 
 			handler := &timeoutHandler{
-				handler:            scenario.handler(fakeClock, &reqMux, writeErrors),
-				body:               scenario.timeoutMessage,
-				firstByteTimeout:   scenario.firstByteTimeout,
-				idleTimeout:        scenario.idleTimeout,
-				maxDurationTimeout: scenario.maxDurationTimeout,
-				clock:              fakeClock,
+				handler:              scenario.handler(fakeClock, &reqMux, writeErrors),
+				body:                 scenario.timeoutMessage,
+				timeout:              scenario.timeout,
+				responseStartTimeout: scenario.responseStartTimeout,
+				idleTimeout:          scenario.idleTimeout,
+				clock:                fakeClock,
 			}
 
 			defer func() {
@@ -140,7 +141,7 @@ func testTimeoutScenario(t *testing.T, scenarios []timeoutHandlerTestScenario) {
 	}
 }
 
-func TestTimeToFirstByteTimeoutHandler(t *testing.T) {
+func TestTimeToResponseStartTimeoutHandler(t *testing.T) {
 	const (
 		immediateTimeout = 1 * time.Millisecond
 		longTimeout      = 1 * time.Minute // Super long, not supposed to hit this.
@@ -148,9 +149,9 @@ func TestTimeToFirstByteTimeoutHandler(t *testing.T) {
 	)
 
 	scenarios := []timeoutHandlerTestScenario{{
-		name:             "all good",
-		firstByteTimeout: longTimeout,
-		idleTimeout:      noIdleTimeout,
+		name:                 "all good",
+		responseStartTimeout: longTimeout,
+		idleTimeout:          noIdleTimeout,
 		handler: func(*clock.FakeClock, *sync.Mutex, chan error) http.Handler {
 			return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 				w.Write([]byte("hi"))
@@ -159,9 +160,9 @@ func TestTimeToFirstByteTimeoutHandler(t *testing.T) {
 		wantStatus: http.StatusOK,
 		wantBody:   "hi",
 	}, {
-		name:             "custom timeout message",
-		firstByteTimeout: immediateTimeout,
-		idleTimeout:      noIdleTimeout,
+		name:                 "custom timeout message",
+		responseStartTimeout: immediateTimeout,
+		idleTimeout:          noIdleTimeout,
 		handler: func(c *clock.FakeClock, mux *sync.Mutex, writeErrors chan error) http.Handler {
 			return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 				c.Step(immediateTimeout)
@@ -176,9 +177,9 @@ func TestTimeToFirstByteTimeoutHandler(t *testing.T) {
 		wantBody:       "request timeout",
 		wantWriteError: true,
 	}, {
-		name:             "propagate panic",
-		firstByteTimeout: longTimeout,
-		idleTimeout:      noIdleTimeout,
+		name:                 "propagate panic",
+		responseStartTimeout: longTimeout,
+		idleTimeout:          noIdleTimeout,
 		handler: func(*clock.FakeClock, *sync.Mutex, chan error) http.Handler {
 			return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 				panic(http.ErrAbortHandler)
@@ -188,9 +189,9 @@ func TestTimeToFirstByteTimeoutHandler(t *testing.T) {
 		wantBody:   "request timeout",
 		wantPanic:  true,
 	}, {
-		name:             "timeout before panic",
-		firstByteTimeout: immediateTimeout,
-		idleTimeout:      noIdleTimeout,
+		name:                 "timeout before panic",
+		responseStartTimeout: immediateTimeout,
+		idleTimeout:          noIdleTimeout,
 		handler: func(c *clock.FakeClock, mux *sync.Mutex, _ chan error) http.Handler {
 			return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 				c.Step(immediateTimeout)
@@ -209,17 +210,17 @@ func TestTimeToFirstByteTimeoutHandler(t *testing.T) {
 
 func TestIdleTimeoutHandler(t *testing.T) {
 	const (
-		noIdleTimeout        = 0 * time.Millisecond
-		immediateIdleTimeout = 1 * time.Millisecond // 0 would disable the timeout
-		shortIdleTimeout     = 100 * time.Millisecond
-		longIdleTimeout      = 1 * time.Minute // Super long, not supposed to hit this.
-		longFirstByteTimeout = 1 * time.Minute // Super long, not supposed to hit this.
+		noIdleTimeout            = 0 * time.Millisecond
+		immediateIdleTimeout     = 1 * time.Millisecond // 0 would disable the timeout
+		shortIdleTimeout         = 100 * time.Millisecond
+		longIdleTimeout          = 1 * time.Minute // Super long, not supposed to hit this.
+		longResponseStartTimeout = 1 * time.Minute // Super long, not supposed to hit this.
 	)
 
 	scenarios := []timeoutHandlerTestScenario{{
-		name:             "all good",
-		firstByteTimeout: longFirstByteTimeout,
-		idleTimeout:      longIdleTimeout,
+		name:                 "all good",
+		responseStartTimeout: longResponseStartTimeout,
+		idleTimeout:          longIdleTimeout,
 		handler: func(*clock.FakeClock, *sync.Mutex, chan error) http.Handler {
 			return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 				w.Write([]byte("hi"))
@@ -228,9 +229,9 @@ func TestIdleTimeoutHandler(t *testing.T) {
 		wantStatus: http.StatusOK,
 		wantBody:   "hi",
 	}, {
-		name:             "custom timeout message",
-		idleTimeout:      immediateIdleTimeout,
-		firstByteTimeout: longFirstByteTimeout,
+		name:                 "custom timeout message",
+		idleTimeout:          immediateIdleTimeout,
+		responseStartTimeout: longResponseStartTimeout,
 		handler: func(c *clock.FakeClock, mux *sync.Mutex, writeErrors chan error) http.Handler {
 			return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 				c.Step(immediateIdleTimeout)
@@ -245,9 +246,9 @@ func TestIdleTimeoutHandler(t *testing.T) {
 		wantBody:       "request timeout",
 		wantWriteError: true,
 	}, {
-		name:             "propagate panic",
-		idleTimeout:      longIdleTimeout,
-		firstByteTimeout: longFirstByteTimeout,
+		name:                 "propagate panic",
+		idleTimeout:          longIdleTimeout,
+		responseStartTimeout: longResponseStartTimeout,
 		handler: func(*clock.FakeClock, *sync.Mutex, chan error) http.Handler {
 			return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 				panic(http.ErrAbortHandler)
@@ -257,9 +258,9 @@ func TestIdleTimeoutHandler(t *testing.T) {
 		wantBody:   "request timeout",
 		wantPanic:  true,
 	}, {
-		name:             "timeout before panic",
-		idleTimeout:      immediateIdleTimeout,
-		firstByteTimeout: longFirstByteTimeout,
+		name:                 "timeout before panic",
+		idleTimeout:          immediateIdleTimeout,
+		responseStartTimeout: longResponseStartTimeout,
 		handler: func(c *clock.FakeClock, mux *sync.Mutex, _ chan error) http.Handler {
 			return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 				c.Step(immediateIdleTimeout)
@@ -273,9 +274,9 @@ func TestIdleTimeoutHandler(t *testing.T) {
 		wantBody:       "request timeout",
 		wantPanic:      false,
 	}, {
-		name:             "successful writes prevent timeout",
-		idleTimeout:      shortIdleTimeout,
-		firstByteTimeout: longFirstByteTimeout,
+		name:                 "successful writes prevent timeout",
+		idleTimeout:          shortIdleTimeout,
+		responseStartTimeout: longResponseStartTimeout,
 		handler: func(c *clock.FakeClock, _ *sync.Mutex, _ chan error) http.Handler {
 			return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 				w.Write([]byte("foo"))
@@ -292,9 +293,9 @@ func TestIdleTimeoutHandler(t *testing.T) {
 		wantBody:   "foobarbaztest",
 		wantPanic:  false,
 	}, {
-		name:             "can still timeout after a successful write",
-		idleTimeout:      shortIdleTimeout,
-		firstByteTimeout: longFirstByteTimeout,
+		name:                 "can still timeout after a successful write",
+		idleTimeout:          shortIdleTimeout,
+		responseStartTimeout: longResponseStartTimeout,
 		handler: func(c *clock.FakeClock, mux *sync.Mutex, _ chan error) http.Handler {
 			return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 				w.Write([]byte("foo"))
@@ -309,9 +310,9 @@ func TestIdleTimeoutHandler(t *testing.T) {
 		wantBody:       "foorequest timeout",
 		wantPanic:      false,
 	}, {
-		name:             "no idle timeout",
-		idleTimeout:      noIdleTimeout,
-		firstByteTimeout: longFirstByteTimeout,
+		name:                 "no idle timeout",
+		idleTimeout:          noIdleTimeout,
+		responseStartTimeout: longResponseStartTimeout,
 		handler: func(*clock.FakeClock, *sync.Mutex, chan error) http.Handler {
 			return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 				panic(http.ErrAbortHandler)
@@ -327,12 +328,12 @@ func TestIdleTimeoutHandler(t *testing.T) {
 
 	// If max duration is set high enough it should not affect any idle timeout test
 	for i := range scenarios {
-		scenarios[i].maxDurationTimeout = 5 * longIdleTimeout
+		scenarios[i].timeout = 5 * longIdleTimeout
 	}
 	testTimeoutScenario(t, scenarios)
 }
 
-func TestMaxDurationTimeoutHandler(t *testing.T) {
+func TestTimeoutHandler(t *testing.T) {
 	const (
 		noTimeout        = 0 * time.Millisecond
 		immediateTimeout = 1 * time.Millisecond
@@ -341,10 +342,10 @@ func TestMaxDurationTimeoutHandler(t *testing.T) {
 	)
 
 	scenarios := []timeoutHandlerTestScenario{{
-		name:               "all good",
-		firstByteTimeout:   shortTimeout,
-		idleTimeout:        shortTimeout,
-		maxDurationTimeout: longTimeout,
+		name:                 "all good",
+		responseStartTimeout: shortTimeout,
+		idleTimeout:          shortTimeout,
+		timeout:              longTimeout,
 		handler: func(*clock.FakeClock, *sync.Mutex, chan error) http.Handler {
 			return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 				w.Write([]byte("hi"))
@@ -353,10 +354,10 @@ func TestMaxDurationTimeoutHandler(t *testing.T) {
 		wantStatus: http.StatusOK,
 		wantBody:   "hi",
 	}, {
-		name:               "max duration timeout with writes",
-		firstByteTimeout:   shortTimeout,
-		idleTimeout:        shortTimeout,
-		maxDurationTimeout: longTimeout,
+		name:                 "max duration timeout with writes",
+		responseStartTimeout: shortTimeout,
+		idleTimeout:          shortTimeout,
+		timeout:              longTimeout,
 		handler: func(c *clock.FakeClock, mux *sync.Mutex, _ chan error) http.Handler {
 			return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 				c.Step(longTimeout)
@@ -367,10 +368,10 @@ func TestMaxDurationTimeoutHandler(t *testing.T) {
 		},
 		wantStatus: http.StatusGatewayTimeout,
 	}, {
-		name:               "propagate panic, max duration too short",
-		idleTimeout:        longTimeout,
-		firstByteTimeout:   longTimeout,
-		maxDurationTimeout: immediateTimeout,
+		name:                 "propagate panic, max duration too short",
+		idleTimeout:          longTimeout,
+		responseStartTimeout: longTimeout,
+		timeout:              immediateTimeout,
 		handler: func(*clock.FakeClock, *sync.Mutex, chan error) http.Handler {
 			return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 				panic(http.ErrAbortHandler)
@@ -380,10 +381,10 @@ func TestMaxDurationTimeoutHandler(t *testing.T) {
 		wantBody:   "request timeout",
 		wantPanic:  true,
 	}, {
-		name:               "timeout before panic, max duration too short",
-		idleTimeout:        shortTimeout,
-		firstByteTimeout:   shortTimeout,
-		maxDurationTimeout: immediateTimeout,
+		name:                 "timeout before panic, max duration too short",
+		idleTimeout:          shortTimeout,
+		responseStartTimeout: shortTimeout,
+		timeout:              immediateTimeout,
 		handler: func(c *clock.FakeClock, mux *sync.Mutex, _ chan error) http.Handler {
 			return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 				c.Step(immediateTimeout)
diff --git a/pkg/reconciler/revision/resources/deploy_test.go b/pkg/reconciler/revision/resources/deploy_test.go
index fdeddb766..009f72f72 100644
--- a/pkg/reconciler/revision/resources/deploy_test.go
+++ b/pkg/reconciler/revision/resources/deploy_test.go
@@ -112,6 +112,12 @@ var (
 		}, {
 			Name:  "REVISION_TIMEOUT_SECONDS",
 			Value: "45",
+		}, {
+			Name:  "REVISION_RESPONSE_START_TIMEOUT_SECONDS",
+			Value: "0",
+		}, {
+			Name:  "REVISION_IDLE_TIMEOUT_SECONDS",
+			Value: "0",
 		}, {
 			Name: "SERVING_POD",
 			ValueFrom: &corev1.EnvVarSource{
diff --git a/pkg/reconciler/revision/resources/queue_test.go b/pkg/reconciler/revision/resources/queue_test.go
index 6d826e9f4..a61352b4b 100644
--- a/pkg/reconciler/revision/resources/queue_test.go
+++ b/pkg/reconciler/revision/resources/queue_test.go
@@ -285,6 +285,32 @@ func TestMakeQueueContainer(t *testing.T) {
 				"REVISION_TIMEOUT_SECONDS": "99",
 			})
 		}),
+	}, {
+		name: "custom ResponseStartTimeoutSeconds",
+		rev: revision("bar", "foo",
+			withContainers(containers),
+			func(revision *v1.Revision) {
+				revision.Spec.ResponseStartTimeoutSeconds = ptr.Int64(77)
+			},
+		),
+		want: queueContainer(func(c *corev1.Container) {
+			c.Env = env(map[string]string{
+				"REVISION_RESPONSE_START_TIMEOUT_SECONDS": "77",
+			})
+		}),
+	}, {
+		name: "custom IdleTimeoutSeconds",
+		rev: revision("bar", "foo",
+			withContainers(containers),
+			func(revision *v1.Revision) {
+				revision.Spec.IdleTimeoutSeconds = ptr.Int64(99)
+			},
+		),
+		want: queueContainer(func(c *corev1.Container) {
+			c.Env = env(map[string]string{
+				"REVISION_IDLE_TIMEOUT_SECONDS": "99",
+			})
+		}),
 	}, {
 		name: "default resource config",
 		rev: revision("bar", "foo",
@@ -878,32 +904,34 @@ func TestTCPProbeGeneration(t *testing.T) {
 }
 
 var defaultEnv = map[string]string{
-	"CONCURRENCY_STATE_ENDPOINT":       "",
-	"CONCURRENCY_STATE_TOKEN_PATH":     "/var/run/secrets/tokens/state-token",
-	"CONTAINER_CONCURRENCY":            "0",
-	"ENABLE_HTTP2_AUTO_DETECTION":      "false",
-	"ENABLE_PROFILING":                 "false",
-	"METRICS_DOMAIN":                   metrics.Domain(),
-	"METRICS_COLLECTOR_ADDRESS":        "",
-	"QUEUE_SERVING_PORT":               "8012",
-	"QUEUE_SERVING_TLS_PORT":           "8112",
-	"REVISION_TIMEOUT_SECONDS":         "45",
-	"SERVING_CONFIGURATION":            "",
-	"SERVING_ENABLE_PROBE_REQUEST_LOG": "false",
-	"SERVING_ENABLE_REQUEST_LOG":       "false",
-	"SERVING_LOGGING_CONFIG":           "",
-	"SERVING_LOGGING_LEVEL":            "",
-	"SERVING_NAMESPACE":                "foo",
-	"SERVING_REQUEST_LOG_TEMPLATE":     "",
-	"SERVING_REQUEST_METRICS_BACKEND":  "",
-	"SERVING_REVISION":                 "bar",
-	"SERVING_SERVICE":                  "",
-	"SYSTEM_NAMESPACE":                 system.Namespace(),
-	"TRACING_CONFIG_BACKEND":           "",
-	"TRACING_CONFIG_DEBUG":             "false",
-	"TRACING_CONFIG_SAMPLE_RATE":       "0",
-	"TRACING_CONFIG_ZIPKIN_ENDPOINT":   "",
-	"USER_PORT":                        strconv.Itoa(v1.DefaultUserPort),
+	"CONCURRENCY_STATE_ENDPOINT":              "",
+	"CONCURRENCY_STATE_TOKEN_PATH":            "/var/run/secrets/tokens/state-token",
+	"CONTAINER_CONCURRENCY":                   "0",
+	"ENABLE_HTTP2_AUTO_DETECTION":             "false",
+	"ENABLE_PROFILING":                        "false",
+	"METRICS_DOMAIN":                          metrics.Domain(),
+	"METRICS_COLLECTOR_ADDRESS":               "",
+	"QUEUE_SERVING_PORT":                      "8012",
+	"QUEUE_SERVING_TLS_PORT":                  "8112",
+	"REVISION_TIMEOUT_SECONDS":                "45",
+	"REVISION_RESPONSE_START_TIMEOUT_SECONDS": "0",
+	"REVISION_IDLE_TIMEOUT_SECONDS":           "0",
+	"SERVING_CONFIGURATION":                   "",
+	"SERVING_ENABLE_PROBE_REQUEST_LOG":        "false",
+	"SERVING_ENABLE_REQUEST_LOG":              "false",
+	"SERVING_LOGGING_CONFIG":                  "",
+	"SERVING_LOGGING_LEVEL":                   "",
+	"SERVING_NAMESPACE":                       "foo",
+	"SERVING_REQUEST_LOG_TEMPLATE":            "",
+	"SERVING_REQUEST_METRICS_BACKEND":         "",
+	"SERVING_REVISION":                        "bar",
+	"SERVING_SERVICE":                         "",
+	"SYSTEM_NAMESPACE":                        system.Namespace(),
+	"TRACING_CONFIG_BACKEND":                  "",
+	"TRACING_CONFIG_DEBUG":                    "false",
+	"TRACING_CONFIG_SAMPLE_RATE":              "0",
+	"TRACING_CONFIG_ZIPKIN_ENDPOINT":          "",
+	"USER_PORT":                               strconv.Itoa(v1.DefaultUserPort),
 }
 
 func probeJSON(container *corev1.Container) string {
diff --git a/pkg/testing/v1/configuration.go b/pkg/testing/v1/configuration.go
index c1e355890..e84e532d9 100644
--- a/pkg/testing/v1/configuration.go
+++ b/pkg/testing/v1/configuration.go
@@ -124,3 +124,17 @@ func WithConfigRevisionTimeoutSeconds(revisionTimeoutSeconds int64) ConfigOption
 		cfg.Spec.Template.Spec.TimeoutSeconds = ptr.Int64(revisionTimeoutSeconds)
 	}
 }
+
+// WithConfigRevisionResponseStartTimeoutSeconds sets revision first byte timeout
+func WithConfigRevisionResponseStartTimeoutSeconds(revisionResponseStartTimeoutSeconds int64) ConfigOption {
+	return func(cfg *v1.Configuration) {
+		cfg.Spec.Template.Spec.ResponseStartTimeoutSeconds = ptr.Int64(revisionResponseStartTimeoutSeconds)
+	}
+}
+
+// WithConfigRevisionIdleTimeoutSeconds sets revision idle timeout
+func WithConfigRevisionIdleTimeoutSeconds(revisionIdleTimeoutSeconds int64) ConfigOption {
+	return func(cfg *v1.Configuration) {
+		cfg.Spec.Template.Spec.IdleTimeoutSeconds = ptr.Int64(revisionIdleTimeoutSeconds)
+	}
+}
diff --git a/pkg/testing/v1/service.go b/pkg/testing/v1/service.go
index 26e86e90f..8dbec1a4d 100644
--- a/pkg/testing/v1/service.go
+++ b/pkg/testing/v1/service.go
@@ -182,6 +182,20 @@ func WithRevisionTimeoutSeconds(revisionTimeoutSeconds int64) ServiceOption {
 	}
 }
 
+// WithRevisionResponseStartTimeoutSeconds sets revision first byte timeout
+func WithRevisionResponseStartTimeoutSeconds(revisionResponseStartTimeoutSeconds int64) ServiceOption {
+	return func(service *v1.Service) {
+		service.Spec.Template.Spec.ResponseStartTimeoutSeconds = ptr.Int64(revisionResponseStartTimeoutSeconds)
+	}
+}
+
+// WithRevisionIdleTimeoutSeconds sets revision idle timeout
+func WithRevisionIdleTimeoutSeconds(revisionIdleTimeoutSeconds int64) ServiceOption {
+	return func(service *v1.Service) {
+		service.Spec.Template.Spec.IdleTimeoutSeconds = ptr.Int64(revisionIdleTimeoutSeconds)
+	}
+}
+
 // WithServiceAccountName sets revision service account name
 func WithServiceAccountName(serviceAccountName string) ServiceOption {
 	return func(service *v1.Service) {
diff --git a/test/e2e/timeout_test.go b/test/e2e/timeout_test.go
new file mode 100644
index 000000000..23b7b728f
--- /dev/null
+++ b/test/e2e/timeout_test.go
@@ -0,0 +1,168 @@
+//go:build e2e
+// +build e2e
+
+/*
+Copyright 2019 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package e2e
+
+import (
+	"context"
+	"fmt"
+	"net/http"
+	"net/url"
+	"testing"
+	"time"
+
+	pkgtest "knative.dev/pkg/test"
+	"knative.dev/pkg/test/spoof"
+	"knative.dev/serving/test"
+	v1test "knative.dev/serving/test/v1"
+
+	. "knative.dev/serving/pkg/testing/v1"
+)
+
+// sendRequests send a request to "endpoint", returns error if unexpected response code, nil otherwise.
+func sendRequestWithTimeout(t *testing.T, clients *test.Clients, endpoint *url.URL,
+	initialSleep, sleep time.Duration, expectedResponseCode int) error {
+	client, err := pkgtest.NewSpoofingClient(context.Background(), clients.KubeClient, t.Logf, endpoint.Hostname(), test.ServingFlags.ResolvableDomain, test.AddRootCAtoTransport(context.Background(), t.Logf, clients, test.ServingFlags.HTTPS))
+	if err != nil {
+		return fmt.Errorf("error creating Spoofing client: %w", err)
+	}
+
+	start := time.Now()
+	defer func() {
+		t.Logf("URL: %v, initialSleep: %v, sleep: %v, request elapsed %v ms", endpoint, initialSleep, sleep,
+			time.Since(start).Milliseconds())
+	}()
+	u, _ := url.Parse(endpoint.String())
+	q := u.Query()
+	q.Set("initialTimeout", fmt.Sprint(initialSleep.Milliseconds()))
+	q.Set("timeout", fmt.Sprint(sleep.Milliseconds()))
+	u.RawQuery = q.Encode()
+	req, err := http.NewRequest(http.MethodGet, u.String(), nil)
+	if err != nil {
+		return fmt.Errorf("failed to create new HTTP request: %w", err)
+	}
+	spoof.WithHeader(test.ServingFlags.RequestHeader())(req)
+
+	resp, err := client.Do(req)
+	if err != nil {
+		return fmt.Errorf("failed roundtripping: %w", err)
+	}
+
+	t.Logf("Response status code: %v, expected: %v", resp.StatusCode, expectedResponseCode)
+	if expectedResponseCode != resp.StatusCode {
+		return fmt.Errorf("response status code = %v, want = %v, response = %v", resp.StatusCode, expectedResponseCode, resp)
+	}
+
+	return nil
+}
+
+func TestRevisionTimeout(t *testing.T) {
+	t.Parallel()
+	clients := test.Setup(t)
+
+	testCases := []struct {
+		name                        string
+		timeoutSeconds              int64
+		responseStartTimeoutSeconds int64
+		idleTimeoutSeconds          int64
+		initialSleep                time.Duration
+		sleep                       time.Duration
+		expectedStatus              int
+		expectedBody                string
+	}{{
+		name:           "does not exceed timeout seconds",
+		timeoutSeconds: 10,
+		initialSleep:   2 * time.Second,
+		expectedStatus: http.StatusOK,
+	}, {
+		name:           "exceeds timeout seconds",
+		timeoutSeconds: 10,
+		initialSleep:   12 * time.Second,
+		expectedStatus: http.StatusGatewayTimeout,
+	}, {
+		name:                        "writes response before response start timeout",
+		timeoutSeconds:              10,
+		responseStartTimeoutSeconds: 7,
+		expectedStatus:              http.StatusOK,
+		initialSleep:                4 * time.Second,
+	}, {
+		name:                        "exceeds response start timeout",
+		timeoutSeconds:              20,
+		responseStartTimeoutSeconds: 7,
+		expectedStatus:              http.StatusGatewayTimeout,
+		initialSleep:                15 * time.Second,
+	}, {
+		name:               "writes response before idle timeout",
+		timeoutSeconds:     10,
+		idleTimeoutSeconds: 5,
+		expectedStatus:     http.StatusOK,
+		sleep:              2 * time.Second,
+	}, {
+		name:               "exceeds idle timeout",
+		timeoutSeconds:     15,
+		idleTimeoutSeconds: 7,
+		expectedStatus:     http.StatusGatewayTimeout,
+		initialSleep:       20 * time.Second,
+	}}
+
+	for _, tc := range testCases {
+		tc := tc
+
+		t.Run(tc.name, func(t *testing.T) {
+			t.Parallel()
+
+			names := test.ResourceNames{
+				Service: test.ObjectNameForTest(t),
+				Image:   test.Timeout,
+			}
+
+			test.EnsureTearDown(t, clients, &names)
+
+			t.Log("Creating a new Service ")
+			resources, err := v1test.CreateServiceReady(t, clients, &names,
+				WithRevisionTimeoutSeconds(tc.timeoutSeconds),
+				WithRevisionResponseStartTimeoutSeconds(tc.responseStartTimeoutSeconds),
+				WithRevisionIdleTimeoutSeconds(tc.idleTimeoutSeconds))
+			if err != nil {
+				t.Fatal("Failed to create Service:", err)
+			}
+
+			serviceURL := resources.Service.Status.URL.URL()
+
+			t.Log("Probing to force at least one pod", serviceURL)
+			if _, err := pkgtest.CheckEndpointState(
+				context.Background(),
+				clients.KubeClient,
+				t.Logf,
+				serviceURL,
+				spoof.IsOneOfStatusCodes(http.StatusOK, http.StatusGatewayTimeout),
+				"CheckSuccessfulResponse",
+				test.ServingFlags.ResolvableDomain,
+				test.AddRootCAtoTransport(context.Background(), t.Logf, clients, test.ServingFlags.HTTPS),
+				spoof.WithHeader(test.ServingFlags.RequestHeader())); err != nil {
+				t.Fatalf("Error probing %s: %v", serviceURL, err)
+			}
+
+			if err := sendRequestWithTimeout(t, clients, serviceURL, tc.initialSleep, tc.sleep, tc.expectedStatus); err != nil {
+				t.Errorf("Failed request with initialSleep %v, sleep %v, with revision timeout %ds, response start timeout %ds idle timeout %ds, expecting status %v: %v",
+					tc.initialSleep, tc.sleep, tc.timeoutSeconds, tc.responseStartTimeoutSeconds, tc.idleTimeoutSeconds, tc.expectedStatus, err)
+			}
+		})
+	}
+}
diff --git a/third_party/contour-latest/net-contour.yaml b/third_party/contour-latest/net-contour.yaml
index 96f42649a..2c8055ebd 100644
--- a/third_party/contour-latest/net-contour.yaml
+++ b/third_party/contour-latest/net-contour.yaml
@@ -8,7 +8,7 @@ metadata:
     networking.knative.dev/ingress-provider: contour
     app.kubernetes.io/component: net-contour
     app.kubernetes.io/name: knative-serving
-    app.kubernetes.io/version: "20220808-d7a54ac3"
+    app.kubernetes.io/version: "20220812-248a16a8"
     serving.knative.dev/controller: "true"
 rules:
   - apiGroups: ["projectcontour.io"]
@@ -38,7 +38,7 @@ metadata:
     networking.knative.dev/ingress-provider: contour
     app.kubernetes.io/component: net-contour
     app.kubernetes.io/name: knative-serving
-    app.kubernetes.io/version: "20220808-d7a54ac3"
+    app.kubernetes.io/version: "20220812-248a16a8"
 data:
   _example: |
     ################################
@@ -104,14 +104,14 @@ spec:
         app: net-contour-controller
         app.kubernetes.io/component: net-contour
         app.kubernetes.io/name: knative-serving
-        app.kubernetes.io/version: "20220808-d7a54ac3"
+        app.kubernetes.io/version: "20220812-248a16a8"
     spec:
       serviceAccountName: controller
       containers:
         - name: controller
           # This is the Go import path for the binary that is containerized
           # and substituted here.
-          image: gcr.io/knative-nightly/knative.dev/net-contour/cmd/controller@sha256:e6021bfa9c119edf706048148e62bdc7fcf18251139a06c148eb0a6c31de66a7
+          image: gcr.io/knative-nightly/knative.dev/net-contour/cmd/controller@sha256:7337b577c8b295201c64add7a8bc158c321ca507b3331a777bf93d4352e80347
           resources:
             requests:
               cpu: 40m
diff --git a/third_party/gateway-api-latest/istio-gateway.yaml b/third_party/gateway-api-latest/istio-gateway.yaml
index b4e95878c..ce3b6131f 100644
--- a/third_party/gateway-api-latest/istio-gateway.yaml
+++ b/third_party/gateway-api-latest/istio-gateway.yaml
@@ -22,7 +22,7 @@ metadata:
   labels:
     app.kubernetes.io/component: net-gateway-api
     app.kubernetes.io/name: knative-serving
-    app.kubernetes.io/version: "20220810-25e3f772"
+    app.kubernetes.io/version: "20220815-56732f0b"
     experimental.istio.io/disable-gateway-port-translation: "true"
 spec:
   type: ClusterIP
diff --git a/third_party/gateway-api-latest/net-gateway-api.yaml b/third_party/gateway-api-latest/net-gateway-api.yaml
index c5272e69f..713320fe6 100644
--- a/third_party/gateway-api-latest/net-gateway-api.yaml
+++ b/third_party/gateway-api-latest/net-gateway-api.yaml
@@ -4046,7 +4046,7 @@ metadata:
     networking.knative.dev/ingress-provider: net-gateway-api
     app.kubernetes.io/component: net-gateway-api
     app.kubernetes.io/name: knative-serving
-    app.kubernetes.io/version: "20220810-25e3f772"
+    app.kubernetes.io/version: "20220815-56732f0b"
 aggregationRule:
   clusterRoleSelectors:
     - matchLabels:
@@ -4062,7 +4062,7 @@ metadata:
     networking.knative.dev/ingress-provider: net-gateway-api
     app.kubernetes.io/component: net-gateway-api
     app.kubernetes.io/name: knative-serving
-    app.kubernetes.io/version: "20220810-25e3f772"
+    app.kubernetes.io/version: "20220815-56732f0b"
 rules:
   - apiGroups: ["gateway.networking.k8s.io"]
     resources: ["httproutes", "referencegrants", "referencepolicies"]
@@ -4095,7 +4095,7 @@ metadata:
     networking.knative.dev/ingress-provider: net-gateway-api
     app.kubernetes.io/component: net-gateway-api
     app.kubernetes.io/name: knative-serving
-    app.kubernetes.io/version: "20220810-25e3f772"
+    app.kubernetes.io/version: "20220815-56732f0b"
 data:
   _example: |
     ################################
@@ -4149,7 +4149,7 @@ metadata:
   labels:
     networking.knative.dev/ingress-provider: net-gateway-api
     app.kubernetes.io/component: net-gateway-api
-    app.kubernetes.io/version: "20220810-25e3f772"
+    app.kubernetes.io/version: "20220815-56732f0b"
     app.kubernetes.io/name: knative-serving
 spec:
   replicas: 1
@@ -4176,7 +4176,7 @@ spec:
         - name: controller
           # This is the Go import path for the binary that is containerized
           # and substituted here.
-          image: gcr.io/knative-nightly/knative.dev/net-gateway-api/cmd/controller@sha256:d2675a41903309a5484e97a9802334612b9a41263f447f6250d6fa82eb26d4f3
+          image: gcr.io/knative-nightly/knative.dev/net-gateway-api/cmd/controller@sha256:54dfc3ca751dfe4754952c688b6959ae1cebe38ab670477d442618c1262efdf6
           resources:
             requests:
               cpu: 100m
diff --git a/third_party/istio-latest/net-istio.yaml b/third_party/istio-latest/net-istio.yaml
index 7191034bd..67baf2d78 100644
--- a/third_party/istio-latest/net-istio.yaml
+++ b/third_party/istio-latest/net-istio.yaml
@@ -1,4 +1,4 @@
-# Generated when HEAD was 3e9dd543b98a02fac37c7a8902f5fd0d85b32183
+# Generated when HEAD was e7a111a7f432d636681a2b556ec373cb748f4d11
 #
 # Copyright 2019 The Knative Authors
 #
@@ -22,7 +22,7 @@ metadata:
   labels:
     app.kubernetes.io/component: net-istio
     app.kubernetes.io/name: knative-serving
-    app.kubernetes.io/version: "20220805-3e9dd543"
+    app.kubernetes.io/version: "20220812-e7a111a7"
     serving.knative.dev/controller: "true"
     networking.knative.dev/ingress-provider: istio
 rules:
@@ -54,7 +54,7 @@ metadata:
   labels:
     app.kubernetes.io/component: net-istio
     app.kubernetes.io/name: knative-serving
-    app.kubernetes.io/version: "20220805-3e9dd543"
+    app.kubernetes.io/version: "20220812-e7a111a7"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -93,7 +93,7 @@ metadata:
   labels:
     app.kubernetes.io/component: net-istio
     app.kubernetes.io/name: knative-serving
-    app.kubernetes.io/version: "20220805-3e9dd543"
+    app.kubernetes.io/version: "20220812-e7a111a7"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -114,7 +114,7 @@ metadata:
   labels:
     app.kubernetes.io/component: net-istio
     app.kubernetes.io/name: knative-serving
-    app.kubernetes.io/version: "20220805-3e9dd543"
+    app.kubernetes.io/version: "20220812-e7a111a7"
     networking.knative.dev/ingress-provider: istio
     experimental.istio.io/disable-gateway-port-translation: "true"
 spec:
@@ -149,7 +149,7 @@ metadata:
   labels:
     app.kubernetes.io/component: net-istio
     app.kubernetes.io/name: knative-serving
-    app.kubernetes.io/version: "20220805-3e9dd543"
+    app.kubernetes.io/version: "20220812-e7a111a7"
     networking.knative.dev/ingress-provider: istio
 data:
   # TODO(nghia): Extract the .svc.cluster.local suffix into its own config.
@@ -208,7 +208,7 @@ metadata:
   labels:
     app.kubernetes.io/component: net-istio
     app.kubernetes.io/name: knative-serving
-    app.kubernetes.io/version: "20220805-3e9dd543"
+    app.kubernetes.io/version: "20220812-e7a111a7"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -226,7 +226,7 @@ metadata:
   labels:
     app.kubernetes.io/component: net-istio
     app.kubernetes.io/name: knative-serving
-    app.kubernetes.io/version: "20220805-3e9dd543"
+    app.kubernetes.io/version: "20220812-e7a111a7"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -244,7 +244,7 @@ metadata:
   labels:
     app.kubernetes.io/component: net-istio
     app.kubernetes.io/name: knative-serving
-    app.kubernetes.io/version: "20220805-3e9dd543"
+    app.kubernetes.io/version: "20220812-e7a111a7"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -277,7 +277,7 @@ metadata:
   labels:
     app.kubernetes.io/component: net-istio
     app.kubernetes.io/name: knative-serving
-    app.kubernetes.io/version: "20220805-3e9dd543"
+    app.kubernetes.io/version: "20220812-e7a111a7"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -295,14 +295,14 @@ spec:
         app: net-istio-controller
         app.kubernetes.io/component: net-istio
         app.kubernetes.io/name: knative-serving
-        app.kubernetes.io/version: "20220805-3e9dd543"
+        app.kubernetes.io/version: "20220812-e7a111a7"
     spec:
       serviceAccountName: controller
       containers:
         - name: controller
           # This is the Go import path for the binary that is containerized
           # and substituted here.
-          image: gcr.io/knative-nightly/knative.dev/net-istio/cmd/controller@sha256:d8c16a6b54147e4edf992fc0913ecc42e659069cde5271c76d92e12fd4e37ee6
+          image: gcr.io/knative-nightly/knative.dev/net-istio/cmd/controller@sha256:521b3eda56bb789643941758104991c07a584878dc3a1130c1f20dc2324b2704
           resources:
             requests:
               cpu: 30m
@@ -363,7 +363,7 @@ metadata:
   labels:
     app.kubernetes.io/component: net-istio
     app.kubernetes.io/name: knative-serving
-    app.kubernetes.io/version: "20220805-3e9dd543"
+    app.kubernetes.io/version: "20220812-e7a111a7"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -379,14 +379,14 @@ spec:
         role: net-istio-webhook
         app.kubernetes.io/component: net-istio
         app.kubernetes.io/name: knative-serving
-        app.kubernetes.io/version: "20220805-3e9dd543"
+        app.kubernetes.io/version: "20220812-e7a111a7"
     spec:
       serviceAccountName: controller
       containers:
         - name: webhook
           # This is the Go import path for the binary that is containerized
           # and substituted here.
-          image: gcr.io/knative-nightly/knative.dev/net-istio/cmd/webhook@sha256:d578cf6889aa72981603ba024e95478e7786d4c88ad15ecbcdf1fe6d8fee0ac5
+          image: gcr.io/knative-nightly/knative.dev/net-istio/cmd/webhook@sha256:c91f93d3aec38722e9d7192043b1b27bb60e4100e67bf5324a9c5cbcc4471a47
           resources:
             requests:
               cpu: 20m
@@ -441,7 +441,7 @@ metadata:
   labels:
     app.kubernetes.io/component: net-istio
     app.kubernetes.io/name: knative-serving
-    app.kubernetes.io/version: "20220805-3e9dd543"
+    app.kubernetes.io/version: "20220812-e7a111a7"
     networking.knative.dev/ingress-provider: istio
 
 ---
@@ -468,7 +468,7 @@ metadata:
     role: net-istio-webhook
     app.kubernetes.io/component: net-istio
     app.kubernetes.io/name: knative-serving
-    app.kubernetes.io/version: "20220805-3e9dd543"
+    app.kubernetes.io/version: "20220812-e7a111a7"
     networking.knative.dev/ingress-provider: istio
 spec:
   ports:
@@ -507,7 +507,7 @@ metadata:
   labels:
     app.kubernetes.io/component: net-istio
     app.kubernetes.io/name: knative-serving
-    app.kubernetes.io/version: "20220805-3e9dd543"
+    app.kubernetes.io/version: "20220812-e7a111a7"
     networking.knative.dev/ingress-provider: istio
 webhooks:
   - admissionReviewVersions:
@@ -546,7 +546,7 @@ metadata:
   labels:
     app.kubernetes.io/component: net-istio
     app.kubernetes.io/name: knative-serving
-    app.kubernetes.io/version: "20220805-3e9dd543"
+    app.kubernetes.io/version: "20220812-e7a111a7"
     networking.knative.dev/ingress-provider: istio
 webhooks:
   - admissionReviewVersions:
diff --git a/third_party/kourier-latest/kourier.yaml b/third_party/kourier-latest/kourier.yaml
index aeea84fb6..527bd193a 100644
--- a/third_party/kourier-latest/kourier.yaml
+++ b/third_party/kourier-latest/kourier.yaml
@@ -20,7 +20,7 @@ metadata:
     networking.knative.dev/ingress-provider: kourier
     app.kubernetes.io/name: knative-serving
     app.kubernetes.io/component: net-kourier
-    app.kubernetes.io/version: "20220808-fe85c717"
+    app.kubernetes.io/version: "20220812-d48b9f78"
 
 ---
 # Copyright 2020 The Knative Authors
@@ -45,7 +45,7 @@ metadata:
   labels:
     networking.knative.dev/ingress-provider: kourier
     app.kubernetes.io/component: net-kourier
-    app.kubernetes.io/version: "20220808-fe85c717"
+    app.kubernetes.io/version: "20220812-d48b9f78"
     app.kubernetes.io/name: knative-serving
 data:
   envoy-bootstrap.yaml: |
@@ -150,7 +150,7 @@ metadata:
   labels:
     networking.knative.dev/ingress-provider: kourier
     app.kubernetes.io/component: net-kourier
-    app.kubernetes.io/version: "20220808-fe85c717"
+    app.kubernetes.io/version: "20220812-d48b9f78"
     app.kubernetes.io/name: knative-serving
 data:
   _example: |
@@ -227,7 +227,7 @@ metadata:
   labels:
     networking.knative.dev/ingress-provider: kourier
     app.kubernetes.io/component: net-kourier
-    app.kubernetes.io/version: "20220808-fe85c717"
+    app.kubernetes.io/version: "20220812-d48b9f78"
     app.kubernetes.io/name: knative-serving
 ---
 apiVersion: rbac.authorization.k8s.io/v1
@@ -238,7 +238,7 @@ metadata:
   labels:
     networking.knative.dev/ingress-provider: kourier
     app.kubernetes.io/component: net-kourier
-    app.kubernetes.io/version: "20220808-fe85c717"
+    app.kubernetes.io/version: "20220812-d48b9f78"
     app.kubernetes.io/name: knative-serving
 rules:
   - apiGroups: [""]
@@ -270,7 +270,7 @@ metadata:
   labels:
     networking.knative.dev/ingress-provider: kourier
     app.kubernetes.io/component: net-kourier
-    app.kubernetes.io/version: "20220808-fe85c717"
+    app.kubernetes.io/version: "20220812-d48b9f78"
     app.kubernetes.io/name: knative-serving
 roleRef:
   apiGroup: rbac.authorization.k8s.io
@@ -304,7 +304,7 @@ metadata:
   labels:
     networking.knative.dev/ingress-provider: kourier
     app.kubernetes.io/component: net-kourier
-    app.kubernetes.io/version: "20220808-fe85c717"
+    app.kubernetes.io/version: "20220812-d48b9f78"
     app.kubernetes.io/name: knative-serving
 spec:
   replicas: 1
@@ -317,7 +317,7 @@ spec:
         app: net-kourier-controller
     spec:
       containers:
-        - image: gcr.io/knative-nightly/knative.dev/net-kourier/cmd/kourier@sha256:c6e3d108fc36261601c00d8cb044a134b54a9b0b4139e3d229ac4ba111579a9c
+        - image: gcr.io/knative-nightly/knative.dev/net-kourier/cmd/kourier@sha256:a5524b62336d64cb1d00b7df22f1ce4ad68e52c84c2d68806f442043894d4d1d
           name: controller
           env:
             - name: CERTS_SECRET_NAMESPACE
@@ -359,7 +359,7 @@ metadata:
   labels:
     networking.knative.dev/ingress-provider: kourier
     app.kubernetes.io/component: net-kourier
-    app.kubernetes.io/version: "20220808-fe85c717"
+    app.kubernetes.io/version: "20220812-d48b9f78"
     app.kubernetes.io/name: knative-serving
 spec:
   ports:
@@ -394,7 +394,7 @@ metadata:
   labels:
     networking.knative.dev/ingress-provider: kourier
     app.kubernetes.io/component: net-kourier
-    app.kubernetes.io/version: "20220808-fe85c717"
+    app.kubernetes.io/version: "20220812-d48b9f78"
     app.kubernetes.io/name: knative-serving
 spec:
   strategy:
@@ -477,7 +477,7 @@ metadata:
   labels:
     networking.knative.dev/ingress-provider: kourier
     app.kubernetes.io/component: net-kourier
-    app.kubernetes.io/version: "20220808-fe85c717"
+    app.kubernetes.io/version: "20220812-d48b9f78"
     app.kubernetes.io/name: knative-serving
 spec:
   ports:
@@ -501,7 +501,7 @@ metadata:
   labels:
     networking.knative.dev/ingress-provider: kourier
     app.kubernetes.io/component: net-kourier
-    app.kubernetes.io/version: "20220808-fe85c717"
+    app.kubernetes.io/version: "20220812-d48b9f78"
     app.kubernetes.io/name: knative-serving
 spec:
   ports: