You can use https://github.com/ConduitIO/bwlimit to limit the bandwidth of requests on the server and the client. It differs from other libraries, because it respects read/write deadlines (timeouts) and limits the bandwidth of the whole request including headers, not only the request body.
Here's how to use it on the client:
package main
import (
"io"
"net"
"net/http"
"time"
"github.com/conduitio/bwlimit"
)
const (
writeLimit = 1 * bwlimit.Mebibyte // write limit is 1048576 B/s
readLimit = 4 * bwlimit.KB // read limit is 4000 B/s
)
func main() {
// change dialer in the default transport to use a bandwidth limit
dialer := bwlimit.NewDialer(&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}, writeLimit, readLimit)
http.DefaultTransport.(*http.Transport).DialContext = dialer.DialContext
// requests through the default client respect the bandwidth limit now
resp, _ := http.DefaultClient.Get("http://google.com")
_, _ = io.Copy(resp.Body)
}
However, as Graham King pointed out, keep in mind that reads from remote will still fill the TCP buffer as fast as possible, this library will only read slowly from the buffer. Limiting the bandwidth of writes produces the expected result though.