Code change:
HTTP/2 allows a server to pre-emptively send (or "push") responses (along with corresponding "promised" requests) to a client in <del> association with a previous client-initiated request.  This can be useful when the server knows the client will need to have those responses available in order to fully process the response to the original request. </del> <ins> association with a previous client-initiated request. Server push was designed to allow a server to improve client- perceived performance by predicting what requests will follow those that it receives, thereby removing a round trip for them.  For example, a request for HTML is often followed by requests for stylesheets and scripts referenced by that page.  When these requests are pushed, the client does not need to wait to receive the references to them in the HTML and issue separate requests. In practice, server push is difficult to use effectively, because it requires the server to correctly anticipate the additional requests the client will make, taking into account factors such as caching, content negotiation, and user behavior.  Errors in prediction can lead to performance degradation, due to the opportunity cost that the additional data on the wire represents.  In particular, pushing any significant amount of data can cause contention issues with more- important responses. </ins> A client can request that server push be disabled, though this is negotiated for each hop independently.  The SETTINGS_ENABLE_PUSH

Related discussion:
text: NAME says: It's not very widely used and many implementations either don't support it at all or don't support it in a way that improves end-user performance. This sparked a lively discussion at URL
I’m open to dropping this, but I think the case needs to be be made for what the burden is. It’s one of the easiest protocol features to just ignore: send SETTINGSENABLEPUSH=0 and then you can remove all awareness of PUSH_PROMISE from your state machine altogether.
Crazy thought: what if we made part of HTTP/2, and then factored server push into an extension?
Or what if we minted a new ALPN () and flipped the default value?
Or left it as is, since it is used outside of browsers. The browsers have an API problem that has not been solved, and it is unlikely that push will be effective there (except as a competitor to inlining) until that changes.
I have no particular objection to flipping the default under a new ALPN. Factoring it out to an extension is harder, but not impossible -- it's pretty embedded in the state machine, but we might be able to abstract that away. Removing it entirely seems challenging for several reasons. The purely process one is that RFC 8030 requires Server Push, and removing a feature used by a Standards Track RFC presumably requires deprecating that other RFC.
I should note that my preferred outcome here is "do nothing". I'm just spitballing ideas.
Flipping the default if we mint a new alpn seems sensible based on the comments above. This would also align with HTTP/3. Moving it to an extension is probably more work than it's worth, I'll admit. I wasn't aware of RFC 8030. Is that an actively used RFC?
Push is being used outside of browsers (curl supports it, once implemented for a particular company that uses/used it pretty widely across the globe), although I suspect that outside of browsers we also have no real means of figuring out exactly how much or little. Saying "do it in extension" will probably equal killing it, but I also think that removing it from the spec is more work than its worth and just toggling the default seems like the best middle ground.
We may want to be a bit relaxed about flipping the default.