Library / SDK
hashicorp/memberlist avatar
hashicorp/memberlist

hashicorp/memberlist: gossip membership and failure detection for Go clusters

Golang package for gossip based membership and failure detection

4,115 stars483 forksGoMPL-2.0

At a glance

What is it?
memberlist is a Go library that keeps a cluster's member list and detects node failures over a gossip protocol. It is a building block for distributed systems, not a standalone service, and the hard part is configuration rather than the API.
Who is it for?
Adopt hashicorp/memberlist when you are writing a Go service that needs a self-maintaining member list and failure detection, and you accept that tuning the Config knobs is part of the work. Do not adopt it if you need a strongly consistent view of the cluster, a runnable daemon, or a non-Go client, since it is a library and eventual consistency is stated as a design property.
Can I use it commercially?
Yes, with conditions. MPL-2.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
Yes. The repository last received commits 9 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What memberlist solves, and who it is written for

Every distributed system needs an answer to two questions: which nodes are currently part of the cluster, and which ones have stopped responding. The README states the use cases are far-reaching because all distributed systems require membership, and positions memberlist as a re-usable solution to that problem rather than something each project builds again. The audience is therefore Go developers who are already building the distributed part of a system and do not want to write their own failure detector or gossip layer.

The library is not a service you run. There is no memberlist binary, no daemon, no HTTP endpoint. You import it into a Go program and it maintains membership information in the background, as the README's usage example puts it. That framing matters when evaluating it: the operational surface you get is a Go API plus a set of configuration knobs, and everything else (discovery of the first peer, TLS termination, metrics scraping) is your responsibility.

SWIM plus Lifeguard: how the protocol actually behaves

The README says memberlist is based on the SWIM paper, "Scalable Weakly-consistent Infection-style Process Group Membership Protocol", and then lists two families of extensions. One set increases propagation speed and convergence rate. The other, called Lifeguard, is aimed at slow message processing caused by CPU starvation, network delay or packet loss. The Lifeguard paper is linked from the README as arXiv 1707.00788.

The consistency model is stated plainly: memberlist is eventually consistent but converges quickly on average, and the convergence speed can be heavily tuned through protocol knobs. Failure detection is not all-or-nothing either. The README describes node failures as detected and network partitions as partially tolerated, by attempting to communicate with potentially dead nodes through multiple routes. So a node that looks dead from one path may still be reachable from another.

That combination is the honest description of the trade-off. You get a membership view that is usually right and self-heals, and you give up the guarantee that two nodes read the same list at the same instant. The repository layout reflects the machinery behind this: separate files for suspicion, awareness, broadcasts, queues, state, and a keyring, plus delegates for alive, conflict, merge, ping and events. The conflict_delegate.go and merge_delegate.go files in particular point at what happens when two nodes disagree about the same member.

Installing memberlist and joining a first cluster

memberlist is a Go module, so installation is a module fetch. The README's build section says you need Go installed and to verify it with `go version`, and the module path in go.mod is github.com/hashicorp/memberlist. The go.mod file declares `go 1.25.0`, which is the toolchain floor for this revision.

bash
go version
go get github.com/hashicorp/[email protected]

The first command prints your installed Go version so you can compare it against the 1.25.0 requirement. The second pulls the library at the v0.7.0 tag, which the release list dates to 2026-09-16.

The README's usage example is the shortest path to a working node. It creates a memberlist from the default local configuration, joins a known peer, and prints the members it knows about.

go
list, err := memberlist.Create(memberlist.DefaultLocalConfig())
if err != nil {
	panic("Failed to create memberlist: " + err.Error())
}

n, err := list.Join([]string{"1.2.3.4"})
if err != nil {
	panic("Failed to join cluster: " + err.Error())
}

for _, member := range list.Members() {
	fmt.Printf("Member: %s %s\n", member.Name, member.Addr)
}

After this runs you should see one line per known member, printed as name and address. The README notes that memberlist keeps maintaining membership in the background after this point, and that delegates can be registered to receive events when members join or leave. The example's `1.2.3.4` is a placeholder for at least one known member of an existing cluster; a node starting a brand new cluster has nothing to join yet.

If you are working on the library itself rather than consuming it, the Makefile is the entry point. Its default goal is `test`, and on macOS the `subnet` target must run first because the tests need a loopback subnet.

bash
make test
make integ

The first target runs the test suite after setting up that subnet. The second sets `INTEG_TESTS=yes` and runs the integration tests, which the Makefile keeps separate from the ordinary suite. There is also a `testrace` target that runs the race detector, and a `check` target that chains linting, `go mod tidy` verification and copyright header checks.

The configuration surface is the real cost of entry

The README is direct about this: the most difficult part of memberlist is configuring it, because it has many knobs for tuning state propagation delay and convergence times. The default configuration is described as a good starting point that errs on the side of caution, choosing values optimized for higher convergence at the cost of higher bandwidth usage.

That sentence is worth reading twice before you deploy anything. The out-of-the-box defaults are not tuned for a quiet network or a metered link; they are tuned to converge fast. If you run memberlist across regions or on a constrained network, the default behavior is the thing to measure first, and the Godoc entry for memberlist.Config is where the individual fields are documented. The README defers to Godoc for complete documentation, so the README alone will not tell you what each knob does.

The repository also ships a keyring.go file and a security.go file, and the README does not walk through message encryption or key rotation. If your threat model includes an attacker on the gossip network, treat the keyring source and Godoc as the reference rather than the README.

When memberlist is the wrong tool

The clearest limitation is the consistency model. The README states memberlist is eventually consistent. If your workload needs a single authoritative answer about cluster membership at a given moment, a gossip-based view is the wrong foundation, and no amount of tuning changes that property.

Language is the second boundary. This is a Go library with a Go API, and the repository is Go throughout. A service written in Rust, PHP or anything else cannot import it; the related search phrases about a Rust memberlist or a PHP memberlist view profile point at a demand this repository does not serve. Those users need a different implementation of the same protocol, or a sidecar.

The third boundary is scope. memberlist handles membership and failure detection. It does not store your application data, it does not give you a leader, and it does not give you a consistent key-value store. The README's own framing is that it is a re-usable solution to one specific problem. Teams that expect a cluster manager to also solve coordination will be disappointed, and the delegates exist precisely because the library expects you to layer your own semantics on top of membership events.

Finally, the README says network partitions are only partially tolerated. Partial tolerance is not a partition-proof guarantee. If your system must keep serving correctly on both sides of a split, that logic lives in your application, not in memberlist.

Alternatives and what actually differs

The most direct alternative in the Go ecosystem is to implement the SWIM protocol yourself against the same paper memberlist cites. That gives you control over message formats and failure detection thresholds, and it costs you the years of extensions the README describes: the propagation-speed changes and the Lifeguard additions for slow message processing. Writing a working SWIM loop is not the hard part; making it behave under CPU starvation and packet loss is.

A second alternative is to use a separate coordination service and treat membership as a lookup rather than a gossip problem. That inverts the dependency: instead of every node exchanging state with every other node, nodes ask an external system who is alive. The difference in approach is where the failure domain sits. memberlist keeps working with no external dependency and degrades partially under partition; an external coordinator gives you a more authoritative view but adds a component that can itself become unreachable or a bottleneck.

A third option is the delegate pattern inside memberlist itself. The repository exposes alive_delegate.go, event_delegate.go, merge_delegate.go, conflict_delegate.go and ping_delegate.go, so an application that only needs to react to joins and leaves can plug into the existing protocol instead of replacing it. That is usually less work than either alternative above, and it keeps the failure detection logic in one place.

Maintenance, licensing and what to check before you depend on it

The repository is not archived, and the last push was on 2026-09-21. Releases are tagged rather than continuous: v0.7.0 on 2026-09-16, v0.6.0 on 2026-07-08, and v0.5.4 on 2025-12-15. The gap between v0.5.4 and v0.6.0 was roughly seven months, and the gap between v0.6.0 and v0.7.0 was roughly two. If you pin to a tag, budget for the possibility of a long quiet period followed by a jump, and read CHANGELOG.md rather than assuming the version number tells you the size of the change.

Upgrade cost is mostly the config surface. Because the README describes many tunable knobs and the Godoc as the complete reference, a version bump can change what the defaults mean for your convergence and bandwidth profile even when your own code does not change. The Makefile's `tidy` target, which fails the build if go.mod or go.sum drift, is a signal that the project treats dependency hygiene as part of its own checks; you should treat the go.mod `go 1.25.0` line as a real constraint on your build image.

The licence is MPL-2.0, per the LICENSE file at the repository root. MPL-2.0 is a file-level copyleft licence. For a library you import, the practical question is whether your distribution triggers the licence's source-availability obligations for modified covered files. That is a question for your own legal review, not something this article can settle, and the SECURITY.md and CONTRIBUTING.md files are the right places to look for how the project handles reports and contributions.

Editorial conclusion

Adopt hashicorp/memberlist when you are writing a Go service that needs a self-maintaining member list and failure detection, and you accept that tuning the Config knobs is part of the work. Do not adopt it if you need a strongly consistent view of the cluster, a runnable daemon, or a non-Go client, since it is a library and eventual consistency is stated as a design property. Before committing, read the Godoc entry for memberlist.Config, check the go.mod requirement of Go 1.25.0 against your toolchain, and confirm the MPL-2.0 terms against how you intend to distribute your binary.

Frequently asked questions

What is hashicorp/memberlist?

It is a Go library that manages cluster membership and member failure detection using a gossip based protocol. The README describes it as a re-usable solution to the membership problem that all distributed systems share.

How do I install hashicorp/memberlist?

It is a Go module, so you fetch it with go get against the github.com/hashicorp/memberlist module path. The go.mod file declares go 1.25.0, so check your toolchain with go version first.

Is hashicorp/memberlist strongly consistent?

No. The README states that memberlist is eventually consistent but converges quickly on average, and that the convergence speed can be tuned through protocol knobs.

Can I use hashicorp/memberlist from a language other than Go?

Not directly. The repository is a Go library with a Go API, so a service in another language would need a different implementation of the same protocol rather than this package.

What protocol does hashicorp/memberlist use?

It is based on the SWIM paper, with documented extensions for faster propagation and a set of extensions called Lifeguard for slow message processing. The Lifeguard paper is linked from the README.

Official sources

  1. hashicorp/memberlist on GitHub
  2. Issues
  3. License: MPL-2.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/hashicorp-memberlist.svg)](https://hysenlabs.com/projects/hashicorp-memberlist)