{"id":25176688,"url":"https://github.com/conduitio/bwlimit","last_synced_at":"2025-04-04T23:06:52.188Z","repository":{"id":154089119,"uuid":"630434115","full_name":"ConduitIO/bwlimit","owner":"ConduitIO","description":"Limit the bandwidth of a connection.","archived":false,"fork":false,"pushed_at":"2025-03-25T03:14:12.000Z","size":94,"stargazers_count":58,"open_issues_count":4,"forks_count":12,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-28T22:11:33.644Z","etag":null,"topics":["bandwidth","connection","go","limit"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ConduitIO.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-20T11:22:50.000Z","updated_at":"2025-02-05T02:58:00.000Z","dependencies_parsed_at":"2023-11-06T03:25:32.154Z","dependency_job_id":"4dd5f799-b5ca-41a4-bf6b-7d6d7471f75a","html_url":"https://github.com/ConduitIO/bwlimit","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ConduitIO%2Fbwlimit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ConduitIO%2Fbwlimit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ConduitIO%2Fbwlimit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ConduitIO%2Fbwlimit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ConduitIO","download_url":"https://codeload.github.com/ConduitIO/bwlimit/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247261600,"owners_count":20910108,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bandwidth","connection","go","limit"],"created_at":"2025-02-09T13:17:53.878Z","updated_at":"2025-04-04T23:06:52.166Z","avatar_url":"https://github.com/ConduitIO.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# BWLimit\n\n[![License](https://img.shields.io/badge/license-Apache%202-blue)](https://github.com/ConduitIO/bwlimit/blob/main/LICENSE.md)\n[![Test](https://github.com/ConduitIO/bwlimit/actions/workflows/test.yml/badge.svg)](https://github.com/ConduitIO/bwlimit/actions/workflows/test.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/conduitio/bwlimit)](https://goreportcard.com/report/github.com/conduitio/bwlimit)\n[![Go Reference](https://pkg.go.dev/badge/github.com/conduitio/bwlimit.svg)](https://pkg.go.dev/github.com/conduitio/bwlimit)\n\nBWLimit lets you configure a bandwidth limit on [`net.Conn`](https://pkg.go.dev/net#Conn),\n[`io.Reader`](https://pkg.go.dev/io#Reader) and [`io.Writer`](https://pkg.go.dev/io#Writer).\n\n## Quick Start\n\nBWLimit can be used to throttle the bandwidth (bytes per second) either on the\nclient or server.\n\nInstall it with:\n\n```sh\ngo get github.com/conduitio/bwlimit\n```\n\nSee usage examples below:\n- [Server Side](#server-side)\n- [Client Side](#client-side)\n- [gRPC Client Interceptor](#grpc-client-interceptor)\n\nOr check out the [runnable examples](./examples).\n\n### Server Side\n\nTo limit the bandwidth on the server use\n[`bwlimit.NewListener`](https://pkg.go.dev/github.com/conduitio/bwlimit#NewListener).\n\n```go\npackage main\n\nimport (\n\t\"io\"\n\t\"log\"\n\t\"net\"\n\t\"net/http\"\n\n\t\"github.com/conduitio/bwlimit\"\n)\n\nconst (\n\twriteLimit = 1 * bwlimit.Mebibyte // write limit is 1048576 B/s\n\treadLimit  = 4 * bwlimit.KB       // read limit is 4000 B/s\n)\n\nfunc main() {\n\tln, err := net.Listen(\"tcp\", \":8080\")\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to listen: %v\", err)\n\t}\n\t// limit the listener bandwidth\n\tln = bwlimit.NewListener(ln, writeLimit, readLimit)\n\n\thttp.Handle(\"/echo\", http.HandlerFunc(echoHandler))\n\tsrv := \u0026http.Server{Addr: addr}\n\tlog.Fatalf(\"Failed to serve: %v\", srv.Serve(ln))\n}\n\nfunc echoHandler(w http.ResponseWriter, r *http.Request) {\n\tbody, _ := io.ReadAll(r.Body)\n\t_, _ = w.Write(body)\n}\n```\n\n### Client Side\n\nTo limit the bandwidth on the client use\n[`bwlimit.NewDialer`](https://pkg.go.dev/github.com/conduitio/bwlimit#NewDialer).\n\n```go\npackage main\n\nimport (\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/conduitio/bwlimit\"\n)\n\nconst (\n\twriteLimit = 1 * bwlimit.Mebibyte // write limit is 1048576 B/s\n\treadLimit  = 4 * bwlimit.KB       // read limit is 4000 B/s\n)\n\nfunc main() {\n\t// change dialer in the default transport to use a bandwidth limit\n\tdialer := bwlimit.NewDialer(\u0026net.Dialer{\n\t\tTimeout:   30 * time.Second,\n\t\tKeepAlive: 30 * time.Second,\n\t}, writeLimit, readLimit)\n\thttp.DefaultTransport.(*http.Transport).DialContext = dialer.DialContext\n\n\t// requests through the default client respect the bandwidth limit now\n\tresp, _ := http.DefaultClient.Get(\"http://localhost:8080/echo\")\n\t_, _ = io.ReadAll(resp.Body)\n}\n```\n\n### gRPC Client Interceptor\n\nThe gRPC interceptor is provided in a separate module, import it with:\n\n```sh\ngo get github.com/conduitio/bwlimit/bwgrpc\n```\n\nTo limit the bandwidth on a gRPC client use\n[`bwgrpc.WithBandwidthLimitedContextDialer`](https://pkg.go.dev/github.com/conduitio/bwlimit/bwgrpc#WithBandwidthLimitedContextDialer).\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\n\t\"github.com/conduitio/bwlimit\"\n\t\"github.com/conduitio/bwlimit/bwgrpc\"\n\t\"github.com/conduitio/bwlimit/bwgrpc/testproto\"\n\t\"google.golang.org/grpc\"\n)\n\nconst (\n\twriteLimit = 1 * bwlimit.Mebibyte // write limit is 1048576 B/s\n\treadLimit  = 4 * bwlimit.KB       // read limit is 4000 B/s\n)\n\nfunc main() {\n\t// open connection with limited bandwidth\n\tconn, err := grpc.DialContext(\n\t\tcontext.Background(),\n\t\t\"localhost:8080\",\n\t\t// limit the bandwidth\n\t\tbwgrpc.WithBandwidthLimitedContextDialer(writeLimit, readLimit, nil),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to dial: %v\", err)\n\t}\n\tdefer conn.Close()\n\n\t// create gRPC client with the limited connection\n\tc := testproto.NewTestServiceClient(conn)\n\t\n\t// use client to send request\n\t_, err = c.TestRPC(ctx, \u0026testproto.TestRequest{})\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to send RPC: %v\", err)\n\t}\n}\n```\n\n## Limitation\n\nPlease note that bwlimit limits the speed at which data is read from the local\nkernel's TCP buffer, and not directly from the remote connection. This means\nthat the local buffer may become filled and cause the network to be idle while\ndata is read slowly from the buffer, which can cause the actual bandwidth to\ndiffer from the one measured in Go code.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconduitio%2Fbwlimit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fconduitio%2Fbwlimit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconduitio%2Fbwlimit/lists"}