bitset — fast Go bitsets
Description: A high-performance Go library that maps between non-negative integers and boolean values. Set operations, serialization, and SIMD-accelerated routines.

Go library · BSD-style license

# Bitsets, done fast in Go.

A compact, high-performance mapping between non-negative integers and boolean values — far leaner than `map[uint]bool`. Set, clear, flip, test, and run union / intersection / difference at native speed.

Get started API docs ↗
`go get github.com/bits-and-blooms/bitset`
main.go

    var b bitset.BitSet
    b.Set(10).Set(11).Set(1000)

    if b.Test(11) {
        fmt.Println("bit 11 is set")
    }

    // rich set algebra
    hits := b.Intersection(other).Count()

    // iterate set bits (Go 1.23+)
    for i := range b.EachSet() {
        fmt.Println("set:", i)
    }

1 bitper element
60+methods
SIMDaccelerated
Go 1.16+supported

Why bitset

## Everything you need to push bits around

⚡

### Memory efficient

Roughly one bit of storage per element — orders of magnitude smaller than a hash map of booleans, with cache-friendly word layout.

🧮

### Full set algebra

Union, intersection, difference, symmetric difference and complement — each with in-place and cardinality-only variants.

🔗

### Chainable API

`Set`, `Clear`, and `Flip` return the bitset, so mutations read naturally: `b.Set(10).Set(11)`.

🔁

### Fast iteration

Walk set or clear bits with `NextSet` / `NextClear`, or range over `EachSet()` on Go 1.23+.

💾

### Portable serialization

`WriteTo` / `ReadFrom` give a stable byte layout across platforms, plus `MarshalBinary` and JSON support.

🚀

### Battle-tested

Fuzz-tested and used in production by databases, search engines, blockchains and CNCF projects worldwide.

Quick start

## From zero to bits in seconds

1

### Install

    go get github.com/bits-and-blooms/bitset

2

### Use it

    package main

    import (
        "fmt"
        "math/rand"

        "github.com/bits-and-blooms/bitset"
    )

    func main() {
        var b bitset.BitSet

        // play some Go Fish
        for i := 0; i < 100; i++ {
            card1 := uint(rand.Intn(52))
            card2 := uint(rand.Intn(52))
            b.Set(card1)
            if b.Test(card2) {
                fmt.Println("Go Fish!")
            }
            b.Clear(card1)
        }

        // chaining
        b.Set(10).Set(11)

        for i, e := b.NextSet(0); e; i, e = b.NextSet(i + 1) {
            fmt.Println("the following bit is set:", i)
        }

        if b.Intersection(bitset.New(100).Set(10)).Count() == 1 {
            fmt.Println("intersection works.")
        }
    }

Serialization

## Save and restore, portably

Serialize a bitset to a stable, platform-independent stream of bytes with `WriteTo`, then read it back with `ReadFrom` — which reuses the existing instance to minimize allocations.

Performance tip: wrap files and network connections in `bufio` readers and writers for the best throughput.

Full API reference ↗
serialize.go

    bs := bitset.New(9585)
    for i := uint(0); i < 9585; i += 97 {
        bs = bs.Set(i)
    }

    // write
    var buf bytes.Buffer
    n, err := bs.WriteTo(&buf)

    // read back into an existing bitset
    bs = bitset.New()
    n, err = bs.ReadFrom(&buf)

In production

## Trusted by demanding systems

Part of the awesome-go collection and depended on across databases, search, blockchain and infrastructure.

MilvusVector database BleveFull-text search gnarkzk-SNARKs Cosmos SDKBlockchain SDK HugoStatic sites SwarmKitDocker Swarm Apache PulsarMessaging CubeFSCNCF storage NVIDIA DCGMGPU metrics PomeriumAccess proxy RoaringCompressed bitmaps gorseRecommenders

…and many more across the Go ecosystem.

## Working with billions of bits?

A bitset of `N` bits uses at least `N/8` bytes and grows to fit the largest index you touch. For very large, sparse sets, consider compressed Roaring bitmaps — you can convert freely between the two.

Roaring for Go ↗

Go deeper

## Mastering Programming:
From Testing to Performance in Go

Want to write Go like the code behind bitset? This book takes you from solid testing practices all the way to squeezing real performance out of Go — the same techniques used to keep this library fast.

Get the book on Amazon ↗
↑