Skip to Content

Network throttling in Puppeteer

Puppeteer is an awesome way to run Chrome (or Chromium) in headless mode, i.e. load and interact with web pages without ever visually seeing them.

Why would this be useful?
A headless browser is a great way to automate testing, even on remote server machines!

Puppeteer provides a nice interface through Node to script any interactions you can have with a page, like entering input in a textbox, clicking a button and so on. It also allows you grab screenshots or convert web pages into PDFs.

Now, Puppeteer does not come with support for Network throttling out of the box, but it does have a way to communicate directly with the Chrome DevTools, which have support for throttling. The DevTools property in question is Network.emulateNetworkConditions, and it expects a configuration with the following attributes:

let config = {
  // Whether chrome should simulate
  // the absence of connectivity
  'offline': false,
  // Simulated download speed (bytes/s)
  'downloadThroughput': 500,
  // Simulated upload speed (bytes/s)
  'uploadThroughput': 500,
  // Simulated latency (ms)
  'latency': 20
}

As an example, lets say you wanted to load this site with a 200 Kb/s connection and 20 ms latency, and take a screenshot before shutting down, you could use the following script:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
const puppeteer = require('puppeteer')

puppeteer.launch().then(async browser => {
  // Create a new tab
  const page = await browser.newPage()

  // Connect to Chrome DevTools
  const client = await page.target().createCDPSession()

  // Set throttling property
  await client.send('Network.emulateNetworkConditions', {
    'offline': false,
    'downloadThroughput': 200 * 1024 / 8,
    'uploadThroughput': 200 * 1024 / 8,
    'latency': 20
  })

  // Navigate and take a screenshot
  await page.goto('https://fdalvi.github.io')
  await page.screenshot({path: 'screenshot.png'})
  await browser.close()
})

Chrome DevTools also have some nice presets like 3G (and used to have a lot more!). Although the original presets are gone, a source file in the Chromium repo still has the presets, listed below for convenience. Just replace the second option in line 11 with NETWORK_PRESETS['...'] to use the preset of your choice. These values are probably average values for each type of connection, and all of the / 8 operations are because network speed is commonly measured in bits/s, while DevTools expects the throughputs in bytes/s!

let NETWORK_PRESETS = {
  'GPRS': {
    'offline': false,
    'downloadThroughput': 50 * 1024 / 8,
    'uploadThroughput': 20 * 1024 / 8,
    'latency': 500
  },
  'Regular2G': {
    'offline': false,
    'downloadThroughput': 250 * 1024 / 8,
    'uploadThroughput': 50 * 1024 / 8,
    'latency': 300
  },
  'Good2G': {
    'offline': false,
    'downloadThroughput': 450 * 1024 / 8,
    'uploadThroughput': 150 * 1024 / 8,
    'latency': 150
  },
  'Regular3G': {
    'offline': false,
    'downloadThroughput': 750 * 1024 / 8,
    'uploadThroughput': 250 * 1024 / 8,
    'latency': 100
  },
  'Good3G': {
    'offline': false,
    'downloadThroughput': 1.5 * 1024 * 1024 / 8,
    'uploadThroughput': 750 * 1024 / 8,
    'latency': 40
  },
  'Regular4G': {
    'offline': false,
    'downloadThroughput': 4 * 1024 * 1024 / 8,
    'uploadThroughput': 3 * 1024 * 1024 / 8,
    'latency': 20
  },
  'DSL': {
    'offline': false,
    'downloadThroughput': 2 * 1024 * 1024 / 8,
    'uploadThroughput': 1 * 1024 * 1024 / 8,
    'latency': 5
  },
  'WiFi': {
    'offline': false,
    'downloadThroughput': 30 * 1024 * 1024 / 8,
    'uploadThroughput': 15 * 1024 * 1024 / 8,
    'latency': 2
  }
}

Comments

anuj
Friday, Jun 25, 2021

↓ Reply
this is not working

Fahim (In reply to anuj)
Saturday, Jul 3, 2021

What is the issue that you faced? If you can provide some error messages it might be easier to debug.

Tapi
Monday, Oct 4, 2021

↓ Reply
This is also not working for me. There is no error at all, just when I do speed test it shows download and upload speed of my internet connection without throttle.

Fahim (In reply to Tapi)
Monday, Oct 4, 2021

Hi Tapi,

How are you performing the speed test? Are you visiting a speed test site within puppeteer? Also, is your code hosted somewhere publicly or can you give a link to a minimal example that doesn’t work?

Weam
Tuesday, Mar 1, 2022

↓ Reply
How I can post the result for the script?

Fahim (In reply to Weam)
Tuesday, Mar 1, 2022

What do you mean? Is it not working for you?

Maxim Mazurok
Monday, May 23, 2022

↓ Reply
Make sure that devtools are open in order for this to work. And also don’t expect the preset value to change in devtools. Despite preset staying the same I am pretty sure settings was applied based on the loading speed change.

Milan
Wednesday, Jul 20, 2022

↓ Reply
Hey Fahim, I am currently trying to automate a process on my domain and see how long it takes to finish using different network stats. Could you help me out with this one?

Say something: