When downloading a 700+ MB wheel^1 from files.pythonhosted.org using a Google Cloud Compute Engine instance, I noticed that the first ~50 % of the file was being downloaded at full speed (~60 MB/s) and then it got throttled to less than ~1 MB/s.
At first, I wasn't able to reproduce the issue on my local workstation, where the download speed remained high and constant (~30 MB/s) across the process. On the Google Cloud instance, though, I was able to reliably reproduce the described throttling.
Then, I noticed that the domain resolved to a different IP address locally and on Google Cloud, due to the differences in geographical location. I was able to reproduce the issue also on my local workstation by using the IP address found on the Google Cloud DNS resolution.
Is Fastly throttling download speeds for 199.232.96.223, but not for 151.101.132.223?
Good (local)
$ ping files.pythonhosted.org
PING dualstack.python.map.fastly.net (151.101.132.223): 56 data bytes
64 bytes from 151.101.132.223: icmp_seq=0 ttl=58 time=5.247 ms
64 bytes from 151.101.132.223: icmp_seq=1 ttl=58 time=5.403 ms
64 bytes from 151.101.132.223: icmp_seq=2 ttl=58 time=7.611 ms
--- dualstack.python.map.fastly.net ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 5.247/6.087/7.611/1.080 ms
Bad (Google Cloud)
$ ping files.pythonhosted.org
PING dualstack.python.map.fastly.net (199.232.96.223) 56(84) bytes of data.
64 bytes from 199.232.96.223: icmp_seq=1 ttl=61 time=32.3 ms
64 bytes from 199.232.96.223: icmp_seq=2 ttl=61 time=32.1 ms
64 bytes from 199.232.96.223: icmp_seq=3 ttl=61 time=32.0 ms
--- dualstack.python.map.fastly.net ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2957ms
rtt min/avg/max/mdev = 31.950/32.127/32.291/0.139 ms
Fastly Debug
#### Good
```
ewogICJnZW9pcCI6IHsKICAgICJjaSI6ICJsYSBwdWVibGEgZGUgYWxmaW5kZW4iLAogICAgInN0IjogIloiLAogICAgImN0IjogInNwYWluIiwKICAgICJjbyI6ICJFVSIsCiAgICAiY19pcCI6ICJSRURBQ1RFRCIsCiAgICAiY19hc24iOiAiNTcyNjkiLAogICAgImNfYXNuX25hbWUiOiAiZGlnaSBzcGFpbiB0ZWxlY29tIHMubC4iLAogICAgInJfaXAiOiAiMTcyLjcwLjU5LjU3IiwKICAgICJyX2FzbiI6ICIxMzMzNSIsCiAgICAicl9hc25fbmFtZSI6ICJjbG91ZGZsYXJlIGluYy4iLAogICAgInJfY2kiOiAibWFkcmlkIiwKICAgICJyX3N0IjogIk0iLAogICAgInJfY3QiOiAic3BhaW4iLAogICAgInJfY28iOiAiRVUiCiAgfSwKICAicG9wTGF0ZW5jeSI6IHsKICAgICJhbXMiOiAzOSwKICAgICJibWEiOiA1NSwKICAgICJicnUiOiAzOSwKICAgICJjcGgiOiA1MCwKICAgICJkdWIiOiA1MCwKICAgICJlZGRmIjogMzUsCiAgICAiZWdsYyI6IDMzLAogICAgImV0b3UiOiA0NSwKICAgICJmY28iOiAzNSwKICAgICJoZWwiOiA2MCwKICAgICJsZnBnIjogMjksCiAgICAibGhyIjogMjksCiAgICAibGluIjogMjgsCiAgICAibGlzIjogMjgsCiAgICAibG9uIjogMzQsCiAgICAibWFkIjogNywKICAgICJtYW4iOiA0NCwKICAgICJtcnMiOiAyMSwKICAgICJtdWMiOiA0MSwKICAgICJteHAiOiAyOCwKICAgICJvc2wiOiA1NywKICAgICJwbW8iOiA1OSwKICAgICJzb2YiOiA2MSwKICAgICJ2aWUiOiA1MSwKICAgICJhbnkiOiA3CiAgfSwKICAicG9wQXNzaWdubWVudHMiOiB7CiAgICAiYWMiOiAibWFkIiwKICAgICJhcyI6ICJtYWQiCiAgfSwKICAicmVxdWVzdCI6IHsKICAgICJyZXNvbHZlcl9pcCI6ICIxNzIuNzAuNTkuNTciLAogICAgInJlc29sdmVyX2FzX25hbWUiOiAiQ0xPVURGTEFSRU5FVCwgVVMiLAogICAgInJlc29sdmVyX2FzX251bWJlciI6ICIxMzMzNSIsCiAgICAicmVzb2x2ZXJfY291bnRyeV9jb2RlIjogIlVTIiwKICAgICJjbGllbnRfaXAiOiAiUkVEQUNURUQiLAogICAgImNsaWVudF9hc19uYW1lIjogIkRJR0lTUEFJTlRFTEVDT00sIEVTIiwKICAgICJjbGllbnRfYXNfbnVtYmVyIjogIjU3MjY5IiwKICAgICJ0aW1lIjogIjIwMjQtMDQtMDVUMDM6Mjg6NDMuMDAwWiIsCiAgICAiaG9zdCI6ICJ3d3cuZmFzdGx5LWRlYnVnLmNvbSIsCiAgICAiYWNjZXB0IjogInRleHQvaHRtbCxhcHBsaWNhdGlvbi94aHRtbCt4bWwsYXBwbGljYXRpb24veG1sO3E9MC45LGltYWdlL2F2aWYsaW1hZ2Uvd2VicCxpbWFnZS9hcG5nLCovKjtxPTAuOCxhcHBsaWNhdGlvbi9zaWduZWQtZXhjaGFuZ2U7dj1iMztxPTAuNyIsCiAgICAidXNlcmFnZW50IjogIk1vemlsbGEvNS4wIChNYWNpbnRvc2g7IEludGVsIE1hYyBPUyBYIDEwXzE1XzcpIEFwcGxlV2ViS2l0LzUzNy4zNiAoS0hUTUwsIGxpa2UgR2Vja28pIENocm9tZS8xMjMuMC4wLjAgU2FmYXJpLzUzNy4zNiIsCiAgICAiYWNjZXB0bGFuZ3VhZ2UiOiAiZXMtRVMsZXM7cT0wLjksZW4tVVM7cT0wLjgsZW47cT0wLjciLAogICAgImFjY2VwdGVuY29kaW5nIjogImd6aXAiLAogICAgImZhc3RseXNlcnZlcmlwIjogIjE1MS4xMDEuMC42NCIsCiAgICAieGZmIjogIlJFREFDVEVEIiwKICAgICJkYXRhY2VudGVyIjogIk1BRCIsCiAgICAiYmFuZHdpZHRoX21icHMiOiAiMTAwLjE2IiwKICAgICJjd25kIjogMjAyLAogICAgIm5leHRob3AiOiAiMTcyLjIzLjE2Ni4xIiwKICAgICJydHQiOiA4LjAzLAogICAgImRlbHRhX3JldHJhbnMiOiAwLAogICAgInRvdGFsX3JldHJhbnMiOiAwCiAgfQp9Cg==
```
#### Bad
```
ewogICJnZW9pcCI6IHsKICAgICJjaSI6ICJjb3VuY2lsIGJsdWZmcyIsCiAgICAic3QiOiAiSUEiLAogICAgImN0IjogInVuaXRlZCBzdGF0ZXMiLAogICAgImNvIjogIk5BIiwKICAgICJjX2lwIjogIjM0LjQxLjIyNy40NCIsCiAgICAiY19hc24iOiAiMzk2OTgyIiwKICAgICJjX2Fzbl9uYW1lIjogImdvb2dsZSBsbGMiLAogICAgInJfaXAiOiAiNzQuMTI1LjcyLjEzOSIsCiAgICAicl9hc24iOiAiMTUxNjkiLAogICAgInJfYXNuX25hbWUiOiAiZ29vZ2xlIGxsYyIsCiAgICAicl9jaSI6ICJjb3VuY2lsIGJsdWZmcyIsCiAgICAicl9zdCI6ICJJQSIsCiAgICAicl9jdCI6ICJ1bml0ZWQgc3RhdGVzIiwKICAgICJyX2NvIjogIk5BIgogIH0sCiAgInBvcExhdGVuY3kiOiB7CiAgICAiYm9zIjogMTQ4LAogICAgImNtaCI6IDE2NiwKICAgICJkZW4iOiAxMTUsCiAgICAiZHR3IjogMTM1LAogICAgImV3ciI6IDE2OCwKICAgICJnbnYiOiAxNDQsCiAgICAiaG5sIjogMTkyLAogICAgImlhaCI6IDEzNSwKICAgICJrYXRsIjogMTQyLAogICAgImtiZmkiOiAxNTcsCiAgICAia2J1ciI6IDE1MSwKICAgICJrY2dzIjogMTMwLAogICAgImtkYWwiOiAxMjAsCiAgICAia2RmdyI6IDEyMywKICAgICJrZnR5IjogMTMwLAogICAgImtpYWQiOiAxMjksCiAgICAia2lncSI6IDExNSwKICAgICJranlvIjogMTI5LAogICAgImtsb3QiOiAxMTYsCiAgICAia21pYSI6IDE1MCwKICAgICJrcGFvIjogMTUzLAogICAgImtwZGsiOiAxMjgsCiAgICAia3JudCI6IDE0NiwKICAgICJrdGViIjogMTQ2LAogICAgImt3aHAiOiAxNTAsCiAgICAibGNrIjogMTY1LAogICAgImxnYSI6IDEzMywKICAgICJtY2kiOiAxMjksCiAgICAibXNwIjogMTI3LAogICAgInBkeCI6IDE3NiwKICAgICJwaHgiOiAxNDUsCiAgICAic2pjIjogMTQ3LAogICAgInN0bCI6IDEyOSwKICAgICJzdHAiOiAxNTgsCiAgICAieXVsIjogMTQ1LAogICAgInl2ciI6IDE2MCwKICAgICJ5eWMiOiAxNjcsCiAgICAieXl6IjogMTI4LAogICAgImFueSI6IDExOAogIH0sCiAgInBvcEFzc2lnbm1lbnRzIjogewogICAgImFjIjogImNoaSIsCiAgICAiYXMiOiAiY2hpIgogIH0sCiAgInJlcXVlc3QiOiB7CiAgICAicmVzb2x2ZXJfaXAiOiAiMTcyLjI1My4yMjEuMTA4IiwKICAgICJyZXNvbHZlcl9hc19uYW1lIjogIkdPT0dMRSwgVVMiLAogICAgInJlc29sdmVyX2FzX251bWJlciI6ICIxNTE2OSIsCiAgICAicmVzb2x2ZXJfY291bnRyeV9jb2RlIjogIlVTIiwKICAgICJjbGllbnRfaXAiOiAiMzQuNDEuMjI3LjQ0IiwKICAgICJjbGllbnRfYXNfbmFtZSI6ICJHT09HTEUtQ0xPVUQtUExBVEZPUk0sIFVTIiwKICAgICJjbGllbnRfYXNfbnVtYmVyIjogIjM5Njk4MiIsCiAgICAidGltZSI6ICIyMDI0LTA0LTA1VDAzOjMyOjMyLjAwMFoiLAogICAgImhvc3QiOiAid3d3LmZhc3RseS1kZWJ1Zy5jb20iLAogICAgImFjY2VwdCI6ICJ0ZXh0L2h0bWwsYXBwbGljYXRpb24veGh0bWwreG1sLGFwcGxpY2F0aW9uL3htbDtxPTAuOSxpbWFnZS9hdmlmLGltYWdlL3dlYnAsaW1hZ2UvYXBuZywqLyo7cT0wLjgsYXBwbGljYXRpb24vc2lnbmVkLWV4Y2hhbmdlO3Y9YjM7cT0wLjciLAogICAgInVzZXJhZ2VudCI6ICJNb3ppbGxhLzUuMCAoTWFjaW50b3NoOyBJbnRlbCBNYWMgT1MgWCAxMF8xNV83KSBBcHBsZVdlYktpdC81MzcuMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvMTIzLjAuMC4wIFNhZmFyaS81MzcuMzYiLAogICAgImFjY2VwdGxhbmd1YWdlIjogImVzLUVTLGVzO3E9MC45LGVuLVVTO3E9MC44LGVuO3E9MC43IiwKICAgICJhY2NlcHRlbmNvZGluZyI6ICJnemlwIiwKICAgICJmYXN0bHlzZXJ2ZXJpcCI6ICIxNTEuMTAxLjAuNjQiLAogICAgInhmZiI6ICIzNC40MS4yMjcuNDQiLAogICAgImRhdGFjZW50ZXIiOiAiQ0hJIiwKICAgICJiYW5kd2lkdGhfbWJwcyI6ICI3Ljk4IiwKICAgICJjd25kIjogMzc4LAogICAgIm5leHRob3AiOiAiMTcyLjI3LjMyLjEiLAogICAgInJ0dCI6IDExNS4yNTUsCiAgICAiZGVsdGFfcmV0cmFucyI6IDAsCiAgICAidG90YWxfcmV0cmFucyI6IDAKICB9Cn0=
```
DNS Resolution
#### Good
```console (paste your output after the line with the dig command)
$ dig pypi.org A
; <<>> DiG 9.10.6 <<>> pypi.org A
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 22030
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;pypi.org. IN A
;; ANSWER SECTION:
pypi.org. 75299 IN A 151.101.128.223
pypi.org. 75299 IN A 151.101.64.223
pypi.org. 75299 IN A 151.101.192.223
pypi.org. 75299 IN A 151.101.0.223
;; Query time: 39 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Fri Apr 05 05:38:17 CEST 2024
;; MSG SIZE rcvd: 101
```
```console (paste your output after the line with the dig command)
$ dig pypi.org AAAA
; <<>> DiG 9.10.6 <<>> pypi.org AAAA
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31968
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;pypi.org. IN AAAA
;; ANSWER SECTION:
pypi.org. 76647 IN AAAA 2a04:4e42::223
pypi.org. 76647 IN AAAA 2a04:4e42:400::223
pypi.org. 76647 IN AAAA 2a04:4e42:600::223
pypi.org. 76647 IN AAAA 2a04:4e42:200::223
;; Query time: 53 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Fri Apr 05 05:38:30 CEST 2024
;; MSG SIZE rcvd: 149
```
```console (paste your output after the line with the dig command)
$ dig files.pythonhosted.org A
; <<>> DiG 9.10.6 <<>> files.pythonhosted.org A
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45283
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;files.pythonhosted.org. IN A
;; ANSWER SECTION:
files.pythonhosted.org. 83255 IN CNAME dualstack.python.map.fastly.net.
dualstack.python.map.fastly.net. 26 IN A 151.101.132.223
;; Query time: 53 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Fri Apr 05 05:38:41 CEST 2024
;; MSG SIZE rcvd: 112
```
```console (paste your output after the line with the dig command)
$ dig files.pythonhosted.org AAAA
; <<>> DiG 9.10.6 <<>> files.pythonhosted.org AAAA
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26152
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;files.pythonhosted.org. IN AAAA
;; ANSWER SECTION:
files.pythonhosted.org. 86388 IN CNAME dualstack.python.map.fastly.net.
dualstack.python.map.fastly.net. 18 IN AAAA 2a04:4e42:1f::223
;; Query time: 7 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Fri Apr 05 05:38:57 CEST 2024
;; MSG SIZE rcvd: 124
```
#### Bad
```console (paste your output after the line with the dig command)
$ dig pypi.org A
; <<>> DiG 9.18.24-1-Debian <<>> pypi.org A
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 9156
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;pypi.org. IN A
;; ANSWER SECTION:
pypi.org. 21600 IN A 151.101.64.223
pypi.org. 21600 IN A 151.101.128.223
pypi.org. 21600 IN A 151.101.0.223
pypi.org. 21600 IN A 151.101.192.223
;; Query time: 3 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Fri Apr 05 03:37:05 UTC 2024
;; MSG SIZE rcvd: 101
```
```console (paste your output after the line with the dig command)
$ dig pypi.org AAAA
; <<>> DiG 9.18.24-1-Debian <<>> pypi.org AAAA
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 42909
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;pypi.org. IN AAAA
;; ANSWER SECTION:
pypi.org. 21600 IN AAAA 2a04:4e42:600::223
pypi.org. 21600 IN AAAA 2a04:4e42:400::223
pypi.org. 21600 IN AAAA 2a04:4e42:200::223
pypi.org. 21600 IN AAAA 2a04:4e42::223
;; Query time: 3 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Fri Apr 05 03:37:14 UTC 2024
;; MSG SIZE rcvd: 149
```
```console (paste your output after the line with the dig command)
$ dig files.pythonhosted.org A
; <<>> DiG 9.18.24-1-Debian <<>> files.pythonhosted.org A
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16264
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;files.pythonhosted.org. IN A
;; ANSWER SECTION:
files.pythonhosted.org. 8485 IN CNAME dualstack.python.map.fastly.net.
dualstack.python.map.fastly.net. 30 IN A 199.232.96.223
;; Query time: 15 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Fri Apr 05 03:37:31 UTC 2024
;; MSG SIZE rcvd: 112
```
```console (paste your output after the line with the dig command)
$ dig files.pythonhosted.org AAAA
; <<>> DiG 9.18.24-1-Debian <<>> files.pythonhosted.org AAAA
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15984
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 2
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;files.pythonhosted.org. IN AAAA
;; ANSWER SECTION:
files.pythonhosted.org. 19 IN CNAME dualstack.python.map.fastly.net.
dualstack.python.map.fastly.net. 11 IN AAAA 2a04:4e42:2000::223
dualstack.python.map.fastly.net. 11 IN AAAA 2a04:4e42:3000::223
dualstack.python.map.fastly.net. 11 IN AAAA 2a04:4e42:4000::223
dualstack.python.map.fastly.net. 11 IN AAAA 2a04:4e42:5000::223
;; ADDITIONAL SECTION:
dualstack.python.map.fastly.net. 19 IN A 199.232.96.223
;; Query time: 0 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Fri Apr 05 03:37:42 UTC 2024
;; MSG SIZE rcvd: 224
```
Traceroutes / IPv4
#### Good
```console (paste your output after the line with the traceroute command)
# traceroute --icmp pypi.org
traceroute: Warning: pypi.org has multiple addresses; using 151.101.64.223
traceroute to pypi.org (151.101.64.223), 64 hops max, 72 byte packets
1 192.168.1.1 (192.168.1.1) 3.533 ms 1.542 ms 4.531 ms
2 10.0.0.1 (10.0.0.1) 5.746 ms 9.024 ms 5.778 ms
3 172.16.1.1 (172.16.1.1) 9.176 ms 6.063 ms 4.993 ms
4 10.220.96.6 (10.220.96.6) 5.193 ms 15.406 ms 6.027 ms
5 81-196-118-216.rdsnet.ro (81.196.118.216) 5.779 ms 5.820 ms 21.479 ms
6 fastly.baja.espanix.net (193.149.1.137) 6.306 ms 5.911 ms 9.312 ms
7 151.101.64.223 (151.101.64.223) 5.711 ms 6.411 ms 4.974 ms
```
```console (paste your output after the line with the traceroute command)
# traceroute --icmp files.pythonhosted.org
traceroute to dualstack.python.map.fastly.net (151.101.132.223), 64 hops max, 72 byte packets
1 192.168.1.1 (192.168.1.1) 4.742 ms 4.116 ms 5.390 ms
2 10.0.0.1 (10.0.0.1) 6.575 ms 5.618 ms 6.411 ms
3 172.16.0.1 (172.16.0.1) 5.537 ms 5.281 ms 7.764 ms
4 * * *
5 86-120-71-48.rdsnet.ro (86.120.71.48) 10.439 ms 22.481 ms 31.988 ms
6 * * *
7 151.101.132.223 (151.101.132.223) 9.481 ms 7.458 ms 6.304 ms
```
#### Bad
```console (paste your output after the line with the traceroute command)
# traceroute --icmp pypi.org
traceroute to pypi.org (151.101.0.223), 30 hops max, 60 byte packets
1 * * *
2 103.244.50.100 (103.244.50.100) 10.794 ms 10.792 ms 10.821 ms
3 151.101.0.223 (151.101.0.223) 10.801 ms 10.799 ms 10.798 ms
```
```console (paste your output after the line with the traceroute command)
# traceroute --icmp files.pythonhosted.org
traceroute to files.pythonhosted.org (199.232.96.223), 30 hops max, 60 byte packets
1 * * *
2 ae-9.edge8.Denver1.Level3.net (4.68.110.133) 10.242 ms 10.267 ms 10.275 ms
3 * * *
4 4.15.102.114 (4.15.102.114) 31.816 ms 31.835 ms 31.899 ms
5 199.232.96.223 (199.232.96.223) 39.259 ms 39.386 ms 39.425 ms
```
> [!NOTE]
> Running the command repeatedly produces slightly different results, e.g. the penultimate hop doesn't always appear or has a diffeerent address.
Traceroutes / IPv6 (If available)
#### Good
```console (paste your output after the line with the traceroute command)
$ traceroute6 pypi.org
traceroute6: Warning: pypi.org has multiple addresses; using 2a04:4e42:200::223
connect: No route to host
```
```console (paste your output after the line with the traceroute command)
$ traceroute6 files.pythonhosted.org
connect: No route to host
```
#### Bad
```console (paste your output after the line with the traceroute command)
$ traceroute6 pypi.org
traceroute to pypi.org (2a04:4e42:400::223), 30 hops max, 80 byte packets
connect: Network is unreachable
```
```console (paste your output after the line with the traceroute command)
$ traceroute6 files.pythonhosted.org
traceroute to files.pythonhosted.org (2a04:4e42:3000::223), 30 hops max, 80 byte packets
connect: Network is unreachable
```
When downloading a 700+ MB wheel^1 from files.pythonhosted.org using a Google Cloud Compute Engine instance, I noticed that the first ~50 % of the file was being downloaded at full speed (~60 MB/s) and then it got throttled to less than ~1 MB/s.
At first, I wasn't able to reproduce the issue on my local workstation, where the download speed remained high and constant (~30 MB/s) across the process. On the Google Cloud instance, though, I was able to reliably reproduce the described throttling.
Then, I noticed that the domain resolved to a different IP address locally and on Google Cloud, due to the differences in geographical location. I was able to reproduce the issue also on my local workstation by using the IP address found on the Google Cloud DNS resolution.
Is Fastly throttling download speeds for 199.232.96.223, but not for 151.101.132.223?
Good (local)
Bad (Google Cloud)
Fastly Debug
DNS Resolution
Traceroutes / IPv4
Traceroutes / IPv6 (If available)
HTTPS Requests / IPv4
HTTPS Requests / IPv6 (If available)
No response
TLS Debug / IPv4
TLS Debug / IPv6 (If available)
No response
Code of Conduct