{"id":13342914,"url":"https://github.com/domsolutions/xk6-fasthttp","last_synced_at":"2026-01-17T18:10:40.858Z","repository":{"id":215634960,"uuid":"739354760","full_name":"domsolutions/xk6-fasthttp","owner":"domsolutions","description":"A k6 extension using fasthttp library for improved speed of HTTP/1.1 requests","archived":false,"fork":false,"pushed_at":"2025-02-15T17:01:19.000Z","size":145,"stargazers_count":5,"open_issues_count":5,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-15T18:15:15.202Z","etag":null,"topics":["fasthttpclient","http-client","k6","load-testing","xk6"],"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/domsolutions.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2024-01-05T11:13:14.000Z","updated_at":"2025-02-15T17:00:07.000Z","dependencies_parsed_at":"2024-02-17T15:28:36.990Z","dependency_job_id":"96a2e233-70b4-4214-bbd4-7351a96c8845","html_url":"https://github.com/domsolutions/xk6-fasthttp","commit_stats":null,"previous_names":["domsolutions/xk6-fasthttp"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/domsolutions%2Fxk6-fasthttp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/domsolutions%2Fxk6-fasthttp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/domsolutions%2Fxk6-fasthttp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/domsolutions%2Fxk6-fasthttp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/domsolutions","download_url":"https://codeload.github.com/domsolutions/xk6-fasthttp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243150672,"owners_count":20244438,"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":["fasthttpclient","http-client","k6","load-testing","xk6"],"created_at":"2024-07-29T19:30:06.932Z","updated_at":"2026-01-17T18:10:40.840Z","avatar_url":"https://github.com/domsolutions.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# xk6-fasthttp\n\n[![Build status](https://github.com/domsolutions/xk6-fasthttp/actions/workflows/go.yml/badge.svg)](https://github.com/domsolutions/xk6-fasthttp/actions/workflows/go.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/domsolutions/xk6-fasthttp)](https://goreportcard.com/report/github.com/domsolutions/xk6-fasthttp)\n[![GoDoc](https://godoc.org/github.com/domsolutions/xk6-fasthttp?status.svg)](http://godoc.org/github.com/domsolutions/xk6-fasthttp)\n\nThe xk6-fasthttp project is a k6 [extension](https://k6.io/docs/extensions/guides/what-are-k6-extensions/) that enables k6 users to send a higher RPS (request per second) for HTTP/1.1 than with the standard k6 build. It achieves this by using the [fasthttp](https://github.com/valyala/fasthttp) library which has lots of memory/CPU optimization and by optimizing the library which checks the response status.\n\nThis is intended for users who wish to stress test a HTTP/1.1 server with a higher RPS than normally possible with k6.\n\nNote this extension **only supports HTTP/1.1.** \n\n## Features\n- Increased RPS on HTTPS connections of **74%**\n- Increased RPS on HTTP connections of **75%**\n- Ability to stream files from disk with `FileStream` so k6 doesn't run out of memory\n- Supports JSON/DOM manipulation same as `k6/http`\n\n## Benchmarks\n\nUsing the standard `k6/http` library:\n\n```javascript\nimport http from 'k6/http';\nimport { check } from 'k6';\n\nexport const options = {\n\tinsecureSkipTLSVerify: true,\n};\n\n// Simulated user behavior\nexport default function () {\n\tlet res = http.post(\"https://localhost:8080\");\n\tcheck(res, { 'status was 200': (r) =\u003e r.status == 200 });\n}\n```\n\nResults:\n\n```shell\n./k6 run -u 250 -d 10s -q ./std-k6.js \n\n     ✓ status was 200\n\n     checks.........................: 100.00% ✓ 65683       ✗ 0    \n     data_received..................: 9.9 MB  988 kB/s\n     data_sent......................: 2.6 MB  260 kB/s\n     http_req_blocked...............: avg=2.47ms   min=650ns    med=1.22µs   max=1.27s    p(90)=1.55µs   p(95)=1.68µs  \n     http_req_connecting............: avg=8.39µs   min=0s       med=0s       max=26ms     p(90)=0s       p(95)=0s      \n     http_req_duration..............: avg=33.81ms  min=427.75µs med=25.52ms  max=854.5ms  p(90)=67.87ms  p(95)=86.46ms \n       { expected_response:true }...: avg=33.81ms  min=427.75µs med=25.52ms  max=854.5ms  p(90)=67.87ms  p(95)=86.46ms \n     http_req_failed................: 0.00%   ✓ 0           ✗ 65683\n     http_req_receiving.............: avg=9.06ms   min=35.49µs  med=4.06ms   max=135.34ms p(90)=22.82ms  p(95)=35.3ms  \n     http_req_sending...............: avg=362.49µs min=71.45µs  med=108.92µs max=166.3ms  p(90)=155.04µs p(95)=246.26µs\n     http_req_tls_handshaking.......: avg=2.45ms   min=0s       med=0s       max=1.27s    p(90)=0s       p(95)=0s      \n     http_req_waiting...............: avg=24.38ms  min=0s       med=18.07ms  max=850.99ms p(90)=50.25ms  p(95)=63.8ms  \n     http_reqs......................: 65683   6554.766172/s\n     iteration_duration.............: avg=37.55ms  min=705.75µs med=26.87ms  max=1.37s    p(90)=70.37ms  p(95)=90.76ms \n     iterations.....................: 65683   6554.766172/s\n     vus............................: 250     min=250       max=250\n     vus_max........................: 250     min=250       max=250\n\n\n```\n\nUsing `k6/x/fasthttp` library:\n\n```javascript\nimport { Request, Client, checkstatus } from \"k6/x/fasthttp\"\n\nconst config = {\n\tmax_conns_per_host: 1,\n\ttls_config: {\n\t\tinsecure_skip_verify: true,\n\t}\n}\n\n\nconst client = new Client(config);\n\nlet req = new Request(\"https://localhost:8080/\");\n\n\n// Simulated user behavior\nexport default function () {\n\t\tlet res = client.get(req);\n\t\tcheckstatus(200, res);\n}\n\n```\n\nResults:\n\n```shell\n./k6 run -u 250 -d 10s -q ./file-stream-upload.js \n\n     ✓ check status is 200\n\n     checks...............: 100.00% ✓ 117129       ✗ 0    \n     data_received........: 0 B     0 B/s\n     data_sent............: 0 B     0 B/s\n     http_req_duration....: avg=20.44ms min=223.18µs med=12.93ms max=1.38s p(90)=41.39ms p(95)=55.58ms\n     http_reqs............: 116879  11671.351065/s\n     iteration_duration...: avg=21.17ms min=311.78µs med=13.5ms  max=1.38s p(90)=43.01ms p(95)=57.71ms\n     iterations...........: 117129  11696.315668/s\n     vus..................: 250     min=250        max=250\n     vus_max..............: 250     min=250        max=250\n\n\n```\n\nCan see improved RPS of `11671.351065/s` compared to `6554.766172/s`\n\n## Streaming\n\nK6 currently doesn't allow streaming files from disk when uploading. This extension introduces this feature which can be useful to keep the memory footprint low as the whole file does not need loading into memory first and allows for faster uploads:\n\n\n```javascript\nimport { Request, Client, FileStream, checkstatus } from \"k6/x/fasthttp\"\n\nconst config = {\n\tmax_conns_per_host: 1,\n\ttls_config: {\n\t\tinsecure_skip_verify: true,\n\t}\n}\n\nconst client = new Client(config);\n\nconst binFile = new FileStream('/home/john/my-large-data.bin');\n\n\nlet req = new Request(\"https://localhost:8080/\", {\n\tbody : binFile\n});\n\n\n// Simulated user behavior\nexport default function () {\n\t\tlet res = client.post(req);\n\t\tcheckstatus(200, res);\n}\n```\n\n## Install\n\nRequires Go \u003e= 1.23\n\n1. Install xk6:\n```shell\ngo install go.k6.io/xk6/cmd/xk6@latest\n```\n2. Build the binary with the latest extension:\n```shell\nxk6 build --with github.com/domsolutions/xk6-fasthttp@latest\n```\n\n## Configuration\n\n### Client\n\nThe `Client` object takes the following configuration options in its constructor with default values as below:\n\n```javascript\n{\n  // timeout for attempting connection\n  \"dial_timeout\": 5, \n  // optional proxy to connect to i.e. \"username:password@localhost:9050\"    \n  \"proxy\": \"\",\n  // max connection duration, 0 is unlimited\n  \"max_conn_duration\": 0,\n  // user agent to send in HTTP header\n  \"user_agent\": \"\",\n  // Per-connection buffer size for responses' reading. 0 is unlimited\n  \"read_buffer_size\": 0,\n  // Per-connection buffer size for requests' writing.\n  \"write_buffer_size\": 0,\n  // Maximum duration for full response reading (including body). 0 is unlimited\n  \"read_timeout\": 0,\n  // Maximum duration for full request writing (including body).\n  \"write_timeout\": 0,\n  // Maximum number of connections per each host which may be established.\n  \"max_conns_per_host\": 1,\n  \"tls_config\": {\n        // skip CA signer verification - useful for localhost testing\n        \"insecure_skip_verify\": false,\n        // private key file path for mTLS handshake\n        \"private_key\": \"\",\n        // certificate file path for mTLS handshake\n        \"certificate\": \"\"    \n  }\n}\n```\n\n### Request\n\nThe `Request` object takes the following configuration options in its constructor with default values as below:\n\n```javascript\n{\n    // whehter to exit with error if a request fails\n    \"throw\": false,\n    // disable keeping connection alive between requests\n    \"disable_keep_alive\": false,\n    // override the host header\n    \"host\": \"\",\n    // object of HTTP headers\n    \"headers\":{},\n    // body to send\n    \"body\": \"\u003cFileStream\u003e\u003cString\u003e\",\n    // expected response type: text,binary,none. If none response body will be discarded\n    \"response_type\": \"text\"\n}\n```\n\n## Not supported\n\n- The [fasthttp](https://github.com/valyala/fasthttp) library lacks certain observability features which the standard HTTP package has so we lose these metrics:\n\n```shell\n     data_received..................: 9.9 MB  988 kB/s\n     data_sent......................: 2.6 MB  260 kB/s\n     http_req_blocked...............: avg=2.47ms   min=650ns    med=1.22µs   max=1.27s    p(90)=1.55µs   p(95)=1.68µs  \n     http_req_connecting............: avg=8.39µs   min=0s       med=0s       max=26ms     p(90)=0s       p(95)=0s      \n     http_req_duration..............: avg=33.81ms  min=427.75µs med=25.52ms  max=854.5ms  p(90)=67.87ms  p(95)=86.46ms \n       { expected_response:true }...: avg=33.81ms  min=427.75µs med=25.52ms  max=854.5ms  p(90)=67.87ms  p(95)=86.46ms \n     http_req_failed................: 0.00%   ✓ 0           ✗ 65683\n     http_req_receiving.............: avg=9.06ms   min=35.49µs  med=4.06ms   max=135.34ms p(90)=22.82ms  p(95)=35.3ms  \n     http_req_sending...............: avg=362.49µs min=71.45µs  med=108.92µs max=166.3ms  p(90)=155.04µs p(95)=246.26µs\n     http_req_tls_handshaking.......: avg=2.45ms   min=0s       med=0s       max=1.27s    p(90)=0s       p(95)=0s      \n     http_req_waiting...............: avg=24.38ms  min=0s       med=18.07ms  max=850.99ms p(90)=50.25ms  p(95)=63.8ms  \n```\n\nIn future releases this may become available, will work on creating a PR against [fasthttp](https://github.com/valyala/fasthttp)\n\n- Currently doesn't support cookie jars\n- Uncompressing response bodies i.e. gzip\n\nIf these features are required, should consider using `k6/http` package, or create an [issue](https://github.com/domsolutions/xk6-fasthttp/issues) and the work can be planned.\n\n## Optimization tips\n\nCreate the request object in the `init` context so it doesn't repeatedly get created on every iteration (safe for reuse within VU) i.e:\n\n```javascript\nimport { Request, Client, checkstatus } from \"k6/x/fasthttp\"\n\nconst config = {\n\tmax_conns_per_host: 1,\n\ttls_config: {\n\t\tinsecure_skip_verify: true,\n\t}\n}\n\nconst client = new Client();\nlet req = new Request(\"http://localhost:8080/\");\n\nexport default function () {\n\t\tlet res = client.post(req);\n\t\tcheckstatus(200, res);\n}\n```\n\nAlso use `checkstatus` to verify the status instead of:\n\n```javascript\nimport { check } from 'k6';\n```\n\nas `checkstatus` doesn't use a closure, so no assertion needed so less CPU cycles.\n\n## Examples\n\nCan find more examples [here](./examples)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdomsolutions%2Fxk6-fasthttp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdomsolutions%2Fxk6-fasthttp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdomsolutions%2Fxk6-fasthttp/lists"}