The Network Information API enables web applications to access information about the network connection in use by the device.
## Introduction and background More and more devices are permanently connected to the Internet, and connectivity is a fundamental requirement for many. Network connectivity depends on a lot of factors, some of which include the connection type (e.g., Wi-Fi, 3G, 4G, 5G, etc.), but also factors like the device's physical location (e.g., Wi-Fi on a moving train), or the user's preferences (e.g., a desire to not overly tax a data connection shared with others). Naive assumptions like "connected to Wi-Fi always means connectivity is granted and data is cheap" or the opposite "connected to cellular always means connectivity is spotty and data is expensive" no longer hold true, and in many cases never did. The Network Information API aims to provide a standard approach for web applications to query the current network status in a meaningful and privacy-preserving way. ## Definitions ### Metered connection A metered connection is an Internet connection that has a data limit associated with it. Examples include mobile data plans with a certain amount of included data, but also ad-hoc hotel Wi-Fi access, or even certain home Internet data plans. Once the data limit is reached, the connection is interrupted, or continuous data usage is charged at an additional (commonly high) cost. It is typically the desire of the user to remain within the caps of the data plan, and not be charged for data usage above the cap. This signal is up to the user and/or operating system to provide. It is not an indication of any particular level of metering. ### Sustained connection speed The sustained connection speed is a numerical means to express what kind of transfers the current connection is suitable for. [Nielsen's Law of Internet Bandwidth](https://www.nngroup.com/articles/law-of-bandwidth/) has shown that users' bandwidth grows by 50% per year. Therefore, rather than use fixed speed labels like 3G, 4G, or 5G (that might be based on theoretically technically possible maximum bandwidth or field-measured actual bandwidth) or meaningless labels like Wi-Fi, the Network Information API uses open-ended bandwidth ranges to express the sustained connection speed. These ranges are measured in bit per second (bit/s) and can be used in conjunction with SI prefixes (e.g., 1 kbit/s = 1,000 bit/s, 1 Mbit/s = 1,000 kbit/s, 1 Gbit/s = 1,000 Mbit/s, or 1 Tbit/s = 1,000 Gbit/s). For example, 4K video commonly requires 20 Mbp/s sustained speed according to the popular streaming service [YouTube](https://support.google.com/youtube/answer/78358?hl=en). The means through which the sustained connection speed is realized (e.g., via a Wi-Fi or an ethernet connection) is not exposed. ## Use cases Depending on the dynamically obtained network connection information, pages can: - Instead of Retina resolution images use "regular" resolution images. - Reduce the quality of lossy compressed images. - Disable autoplay for foreground videos. - Replace background videos with poster images. - Request fewer or more results from a search API. ### Distinction from the save data use case Getting information about the network connection is not to be treated as equivalent to a necessary desire to save data. For example, a web application that downloads data via the BitTorrent protocol may voluntarily want to limit itself to only a percentage of the available bandwidth as to not block other browsing activity, but the objective is not saving data. The save data use case is described in [[SAVE-DATA]]. Web developers can also make use of the [prefers-reduced-data](https://www.w3.org/TR/mediaqueries-5/#prefers-reduced-data) user preference media feature in CSS (@media (prefers-reduced-data: reduce) { /*…*/ }) or JavaScript (if (window.matchMedia('(prefers-reduced-data: reduce)').matches) { /*…*/ }). [[MEDIA-QUERIES]] As another example, on a metered connection a hypothetical podcast application would not synchronize new podcasts for offline use, but downloading high quality image resources for illustrating each podcast would be acceptable. With save data, a hypothetical podcast app would likewise not synchronize new podcasts, but could even go as far as defaulting to only downloading low quality images to illustrate each podcast. ## The NavigatorNetworkInformation interface The Navigator and WorkerNavigator interface expose access to the NetworkInformation interface by mixing in NavigatorNetworkInformation.
  interface mixin NavigatorNetworkInformation {
    [SameObject] readonly attribute NetworkInformation connection;
  };

  Navigator includes NavigatorNetworkInformation;
  WorkerNavigator includes NavigatorNetworkInformation;
### The connection attribute The connection attribute, when getting, returns an object that implements the NetworkInformation interface. ## The NetworkInformation interface The NetworkInformation interface provides a means to access information about the network connection the user agent is currently using. The EventTarget is defined in [[!DOM]].
  [Exposed=(Window,Worker)]
  interface NetworkInformation : EventTarget {
    readonly attribute boolean metered;
    readonly attribute unrestricted double sustainedSpeed;
    attribute EventHandler onchange;
  };
### The metered attribute The metered attribute, when getting, returns whether the connection that the the user agent is using is a metered connection. This information is commonly known to the operating system and can be relayed to the user agent as is. User agents may offer an override mechanism at their own discretion. #### The Sec-CH-Metered-Connection request header field The Sec-CH-Metered-Connection request header field is a boolean that indicates whether the connection that the user agent is using is a metered connection at the time when the request is made by the user agent. It is a Structured Header whose value must be a Boolean. [[STRUCTURED-HEADERS]] ### The sustainedSpeed attribute The sustainedSpeed attribute, when getting, returns the sustained connection speed in bit per second that is facilitated by the user agent. This information is commonly known to the operating system and can be relayed to the user agent as is. User agents may, at their own discretion, look back at a sliding window of recent observations and put the observed connection speeds in buckets of exponentially growing size of bits per second ranges. User agents with a special focus on privacy can report the sustained connection speed as `Infinity`. #### The Sec-CH-Sustained-Speed request header field The Sec-CH-Sustained-Speed request header field is a token that indicates the sustainedSpeed at the time when the request is made by the user agent. It is a Structured Header whose value must be a Token. [[STRUCTURED-HEADERS]] ### The onchange attribute The onchange event handler attribute handles "change" events fired during the steps to update the connection values. #### Handling changes to the underlying connection When the properties of the network connection change, the user agent MUST run the steps to update the connection values: 1. Let new-metered be the new metered connection value. 1. Let new-sustained-speed be the new bucket for the new sustained connection speed. 1. If new-metered is different from the previous `connection.metered` value, or if new-sustained-speed is in a different bucket than `connection.sustainedSpeed`: 1. Using the networking task source, queue a task to perform the following: 1. Set `connection.metered` to new-metered. 1. Set `connection.sustainedSpeed` to new-sustained-speed. 1. Fire an event named `change` at the `NetworkInformation` object. ## Privacy Considerations Knowing whether a connection is metered adds a low entropy signal to the user agent. Since both mobile and desktop connections can be marked as metered, having this information is not enough to determine whether a user is on a cellular, Ethernet, or Wi-Fi connection. Pages can measure the sustained connection speed by requesting files of a known size from multiple remote servers and measuring the time until the downloads finish. The same information is made available in more granular form as buckets of exponentially growing size of bit per second ranges. User agents can size these buckets arbitrarily, or in the extreme case report infinity or zero. By making the sustained connection speed available at request time via client hint adds a low entropy signal to the user agent. The privacy considerations of [[CLIENT-HINTS]] likewise apply to the headers defined by this specification. ## Examples of usage ### Downloading non-essential content
  
    let nonEssentialContentLoaded = false;

    async function downloadNonEssentialContent() {
      if (nonEssentialContentLoaded) {
        return;
      }
      if (!navigator.connection.metered) {
        await fetch('https://example.com/non-essential-content/');
        nonEssentialContentLoaded = true;
      }
    }

    if (!navigator.connection.metered) {
      downloadNonEssentialContent();
    }

    navigator.connection.addEventListener('change', downloadNonEssentialContent);
  
### Limiting bandwidth usage
  
    const initialSustainedSpeedInBytes = navigator.connection.sustainedSpeed / 8;

    // https://github.com/webtorrent/webtorrent/blob/master/docs/api.md#client--new-webtorrentopts
    const client = new WebTorrent({
      // Max 50% of the available bandwidth.
      downLimit = 0.5 * initialSustainedSpeedInBytes,
    });

    navigator.connection.addEventListener('change', (event) => {
      const currentSustainedSpeedInBytes = event.connection.sustainedSpeed / 8;
      // https://github.com/webtorrent/webtorrent/blob/master/docs/api.md#clientthrottledownloadrate
      client.throttleDownload(0.5 * currentSustainedSpeedInBytes);
    });
  
### Adaptive loading based on client hints 1. The client makes an initial request to the server. ```bash GET / HTTP/1.1 Host: example.com ``` 1. The server responds, telling the client via `Accept-CH` that it accepts the `Sec-CH-Metered-Connection` and the `Sec-CH-Sustained-Speed` client hints, and that it also varies the response on the former, as conveyed by `Vary`. ```bash HTTP/1.1 200 OK Content-Type: text/html Accept-CH: Sec-CH-Metered-Connection, Sec-CH-Sustained-Speed Vary: Sec-CH-Metered-Connection ``` 1. The client then later makes a follow-up request for `/list-of-products`, telling the server via `Sec-CH-Metered-Connection` that it is on a metered connection and via `Sec-CH-Sustained-Speed` that its sustained speed is in the bucket of 50,000,000 bps (50 Mbps). ```bash GET /list-of-products HTTP/1.1 Host: example.com Sec-CH-Metered-Connection: 1 Sec-CH-Sustained-Speed: 50000000 ``` 1. The server can then tailor the response to the client's preferences accordingly and, respecting the metered connection, for example, choose to not return all possible products, but just a subset. Since the connection speed permits it, the server can choose to include product videos in the response, but not autoplay them, because the connection is metered.
There is only one class of product that can claim conformance to this specification: a user agent.
## Acknowledgments This document reuses text from the [[!HTML]] specification as permitted by the license of that specification.