{"id":26256935,"url":"https://github.com/sarthakmakhija/blast-core","last_synced_at":"2026-04-29T06:34:35.170Z","repository":{"id":218029135,"uuid":"745411301","full_name":"SarthakMakhija/blast-core","owner":"SarthakMakhija","description":"Load generator for TCP servers.","archived":false,"fork":false,"pushed_at":"2024-03-28T06:59:36.000Z","size":1813,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-02T16:43:52.053Z","etag":null,"topics":["blast","golang","load-generator","tcp"],"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/SarthakMakhija.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-19T09:26:40.000Z","updated_at":"2024-01-19T09:58:52.000Z","dependencies_parsed_at":"2024-06-21T18:58:54.583Z","dependency_job_id":"91b2285c-c246-4316-b50f-cd790d1b02fc","html_url":"https://github.com/SarthakMakhija/blast-core","commit_stats":null,"previous_names":["sarthakmakhija/blast-core"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/SarthakMakhija/blast-core","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SarthakMakhija%2Fblast-core","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SarthakMakhija%2Fblast-core/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SarthakMakhija%2Fblast-core/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SarthakMakhija%2Fblast-core/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SarthakMakhija","download_url":"https://codeload.github.com/SarthakMakhija/blast-core/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SarthakMakhija%2Fblast-core/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32414419,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T06:29:02.080Z","status":"ssl_error","status_checked_at":"2026-04-29T06:29:00.631Z","response_time":110,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["blast","golang","load-generator","tcp"],"created_at":"2025-03-13T20:20:00.404Z","updated_at":"2026-04-29T06:34:35.155Z","avatar_url":"https://github.com/SarthakMakhija.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\t\u003cimg alt=\"blast\" src=\"https://github.com/SarthakMakhija/blast-core/assets/21108320/5c55527f-ece4-478f-b6a3-f26c536c232a\" /\u003e\n\u003c/p\u003e\n\n\n| Platform      | Build Status                                                                                                                                                                                                       |\n|---------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| Ubuntu latest | [![blast_ubuntu_latest](https://github.com/SarthakMakhija/blast-core/actions/workflows/build_ubuntu_latest.yml/badge.svg)](https://github.com/SarthakMakhija/blast-core/actions/workflows/build_ubuntu_latest.yml) |\n| macOS 12      | [![blast_macos_12](https://github.com/SarthakMakhija/blast-core/actions/workflows/build_macos_12.yml/badge.svg)](https://github.com/SarthakMakhija/blast-core/actions/workflows/build_macos_12.yml)                |\n\n\n**blast** is a load generator for TCP servers, especially if such servers maintain persistent connections.\n\n## Content Organization\n\n- [Why blast](#why-blast)\n- [blast-core](#blast-core)\n- [Features](#features)\n- [FAQs](#faqs)\n- [References](#references)\n\n## Why blast\n\nI am a part of the team that is developing a strongly consistent distributed key/value storage engine with support for rich queries.\nThe distributed key/value storage engine has TCP servers that implement [Single Socket Channel](https://martinfowler.com/articles/patterns-of-distributed-systems/single-socket-channel.html) and [Request Pipeline\n](https://martinfowler.com/articles/patterns-of-distributed-systems/request-pipeline.html). \n\nWe needed a way to send load on our servers and get a report with details including total connections established, total requests sent, total responses read and time to get those responses back etc.\n\nAnother detail, our servers accept protobuf encoded messages as byte slices, so the tool should be able to send the load (/byte slice) in a format that the target servers\ncan decode. Almost all distributed systems accept payloads in a very specific format. For example, [JunoDB](https://github.com/paypal/junodb) sends \n(and receives) [OperationalMessage](https://github.com/paypal/junodb/blob/ca68aa14734768fd047b66ea0b7e6316b15fef16/pkg/proto/opMsg.go#L33) encoded as byte slice.\n\nAll we needed was a tool that can send load (or specific load) on target TCP servers, read responses from those servers and present a decent :) report. This was an opportunity to build **blast**. **blast** is inspired from [hey](https://github.com/rakyll/hey), which is an HTTP load generator in golang.\n\n## blast-core\n\n**blast-core** is the heart of [blast CLI](https://github.com/SarthakMakhija/blast). It provides support for sending requests, reading payload from file, reading responses and generating reports.\nIt also provides support parsing command line arguments to simplify building a custom CLI. More on this in the [FAQs](#faqs).  \n\n## Features\n\n**blast-core** provides the following features:\n1. Support for sending **N requests per second per worker**.\n2. Support for **reading N total responses** from the target server.\n3. Support for **reading N successful responses** from the target server.\n4. Support for **customizing** the **load** **duration**. By default, blast runs for 20 seconds.\n5. Support for sending requests to the target server with the specified **concurrency level**.\n6. Support for **establishing N connections** to the target server.\n7. Support for specifying the **connection timeout**.\n8. Support for **printing** the **report**.\n9. Support for sending dynamic payloads with **PayloadGenerator**.\n\n## FAQs\n\n1. **How does blast-core support dynamic payload?**\n\n**blast-core** provides an interface called `PayloadGenerator` and ships with an implementation called `ConstantPayloadGenerator`. Anyone can implement\nthe interface `PayloadGenerator` to generate dynamic payload.\n\n2. **Does blast (CLI) provide support for dynamic payload?**\n\nNo, [blast CLI](https://github.com/SarthakMakhija/blast) does not provide support for dynamic payload. To implement dynamic payload, one needs to create their\nown CLI. **blast-core** makes it easy to build a thin CLI. Creating a custom CLI involves the following:\n\n  - Express the dependency on **blast-core** in `go.mod`\n  - Write a thin `main` function that provides the implementation of `PayloadGenerator`\n\nThe `main` looks like the following:\n\n```go\nfunc main() {\n    commandArguments := blast.NewCommandArguments()\n    blastInstance := commandArguments.ParseWithDynamicPayload(executableName, \u003c\u003cAn implementation of PayloadGenerator\u003e\u003e)\n\n    interruptChannel := make(chan os.Signal, 1)\n    signal.Notify(interruptChannel, os.Interrupt)\n\n    go func() {\n        \u003c-interruptChannel\n        blastInstance.Stop()\n    }()\n\n    blastInstance.WaitForCompletion()\n}\n```\n\n3. **Can I create custom CLI without using the parsing of command line arguments supported by blast-core?**\n\nYes, you can always create a custom CLI that leverages **blast-core**'s features. The custom CLI must create an \ninstance of [Blast struct](https://github.com/SarthakMakhija/blast-core/blob/main/cmd/blast.go) which acts as an orchestrator between `Workers`, `ResponseReader` and `Reporter`.\n\n\n## References\n[hey](https://github.com/rakyll/hey)\n\n*The logo is built using [logo.com](https://logo.com/)*.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsarthakmakhija%2Fblast-core","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsarthakmakhija%2Fblast-core","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsarthakmakhija%2Fblast-core/lists"}