# Sensu Go: an agent-based monitoring system with an embedded etcd and JavaScript filters

> Sensu Go is a rewrite of Sensu in Go, an open source monitoring tool for ephemeral infrastructure and distributed applications, with built-in auto-discovery, service checks, telemetry collection, and well defined APIs for configuration and external data. It embeds etcd for persistence and embeds a JavaScript interpreter for filter expressions.

**sensu/sensu-go** — Simple. Scalable. Multi-cloud monitoring.

- Repository: https://github.com/sensu/sensu-go
- Website: https://sensu.io
- Stars: 1,114 · Forks: 181
- Language: Go
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/sensu-sensu-go

## What Sensu actually is

Sensu is an open source monitoring tool for ephemeral infrastructure and distributed applications. It is an agent based monitoring system with built-in auto-discovery, making it very well suited to cloud environments.

The agent-based model is the first thing to understand. A Sensu deployment has agents running on the machines being monitored, and those agents report. A server checks the health of a service, and the result becomes an event, and the event flows to a handler that decides what to do about it. The server does not reach out to the monitored machine; the monitored machine reaches out to the server. That inversion is what makes the design work for ephemeral infrastructure, where a host may exist for four minutes and you still need the check result.

Auto-discovery is the other half. Instead of a static list of entities and checks, Sensu can find things and register checks for them, which is what the summary means by being well suited to cloud environments. A cluster scaling up produces new instances, and the configuration follows.

The summary also lists the APIs explicitly: Sensu uses service checks to monitor service health and collect telemetry data, and it has a number of well defined APIs for configuration, for external data input, and for providing access to Sensu's own data. The last one is what lets other systems read the event stream rather than scraping it.

And then the nickname. Sensu is extremely extensible and is commonly referred to as the monitoring router. That phrase is the best summary of the architecture, because the extension points are numerous enough that the interesting question for a new user is not what Sensu can check but what Sensu can route to.

## The three things Sensu Go changed, and one it kept

Sensu Go is a complete rewrite of Sensu in Go, with new capabilities and reduced operational overhead, and it eliminates several sources of friction for new and experienced Sensu users. Three specific changes are named.

The first is storage. The original Sensu required external services like Redis or RabbitMQ. Sensu Go can rely on an embedded etcd datastore for persistence, making the product easier to get started with. External etcd services can also be used, in the event that you already have them deployed.

That is a genuine change in what you operate. A monitoring system that needs a message broker and a datastore is three things to install before it tells you anything, and a monitoring system with an embedded datastore is one. The tradeoff is the one etcd always has, which is that an embedded datastore is a single thing you now have to back up and reason about, and the escape hatch is there if you already run etcd.

The second is the expression language. Sensu Go replaces Ruby expressions with JavaScript filter expressions, by embedding a JavaScript interpreter. The original Sensu let you write Ruby in its filters, which was powerful and which tied the whole thing to a Ruby runtime. Embedding a JavaScript interpreter means the filter language is one most people already have in their heads, and the dependency is a single embeddable interpreter rather than a Ruby installation.

The third is the event model. Unlike the original Sensu, Sensu Go events are always handled, unless explicitly filtered. In the original, a check that produced an event which matched no handler was effectively dropped. In Sensu Go, every event is handled by something unless you write a filter to exclude it. That inverts the failure mode, and it is the kind of change that only matters when you are trying to work out why something was not alerted on.

The dependency list confirms the JavaScript choice. The `otto` package, a JavaScript interpreter in Go, is in the requirements, and there is no Ruby anywhere in it.

## Three binaries, and how to run them

The build section shows three commands in the `cmd/` directory, and the architecture follows from them.

You will first need Go >= 1.18 installed. Then you should clone this repository outside of the GOPATH since Sensu Go uses Go Modules:

```
$ git clone https://github.com/sensu/sensu-go.git
$ cd sensu-go
```

To compile and then run Sensu Go within a single step:

```
$ go run ./cmd/sensu-agent
$ go run ./cmd/sensu-backend
$ go run ./cmd/sensuctl
```

And to build the binaries into the `bin/` directory:

```
$ go build -o bin/sensu-agent ./cmd/sensu-agent
$ go build -o bin/sensu-backend ./cmd/sensu-backend
$ go build -o bin/sensuctl ./cmd/sensuctl
```

So there are three roles. The agent runs on every monitored machine. The backend is the server that receives events, stores them, and routes them. And sensuctl is the command line client, the thing you use to configure checks and query events.

The build also supports stamping version information in through linker flags, with the version package path and a git rev-parse for the build SHA. The example values in the documentation are old, with a version of 5.14.0 and a build date of 2019-10-08, so the command is a template rather than something to copy verbatim.

For installation rather than development, the summary says the easiest way to get started is the official Docker image, sensu/sensu, with installer packages also available for a number of computing platforms such as Debian, Ubuntu, RHEL, and CentOS. The `docker-compose.yaml` at the root shows the production shape of the system, with three backend services named backend1, backend2, and backend3, each running sensu-backend with its own etcd configuration, sharing a three-node etcd cluster, with the peer URLs on port 2380 and the client URLs on 2379, and each with a distinct state directory under `/var/lib/sensu/sensu-backend/`.

## The web UI split out, and what the tree says about the scope

There is one note in the installation section that changes what you are installing, and it is easy to skim past.

Starting with Sensu Go version 6.0, for instances built from source, the web UI is now a standalone product. It is no longer included with the Sensu backend, and to build the web UI from source you use the installation instructions in the Sensu Go Web repository.

That is a meaningful change for an operator, because a monitoring system's dashboard is usually the first thing anyone asks about. A build from source now gives you the agent, the backend, and sensuctl, and the dashboard is a separate thing to run and to keep in step with the backend version.

The repository layout shows how large the project is. There is `agent/`, `backend/`, and `cli/` for the three binaries, and then `asset/`, `bonsai/`, `command/`, `dynamic/`, `handler/`, `metrics/`, `process/`, `system/`, `token/`, `transport/`, `util/`, and `version/` as the internal packages. The `graphql/` directory and the `graph-gophers/dataloader` dependency indicate a GraphQL layer, which is the API through which the web UI and other clients read Sensu's data. There is a `js/` directory, which is where the embedded JavaScript interpreter and its runtime live, and a `dashboard/` directory. `licenses/` is a directory of third-party licence files, `testing/` holds test helpers, and there is a `docker-compose.yaml`, a `build.sh`, and a `build.ps1` for the two platforms the maintainers build on.

The tooling in the tree is worth noting for anyone who wants to contribute. There is a `.semgrep.yml` for static analysis with Semgrep, a `staticcheck.conf` for Staticcheck, a `.clang-format` even though the main language is Go, and an `editorconfig` file. The `DCO` file at the root means the project requires a Developer Certificate of Origin sign-off on commits, which is a contributor requirement rather than a licence thing, and the LICENSE file is MIT with the `licenses/` directory holding the notices for the vendored dependencies.

## The open core split, stated plainly

The contributing section explains the relationship between this repository and the commercial product, and it is unusually direct about the mechanics.

Sensu is and always will be open source, and the packages being released for new versions are from the Enterprise repo. Sensu Go is the upstream for Sensu Enterprise, in the Go community's terms, Sensu Go is vendored into the Sensu Enterprise Go repo. The encouragement is to download new versions, as the functionality will be identical to what you find in the public repo, and access to the enterprise-only features can be enabled with a license key.

The last part of the paragraph is the one that surprises people who come from projects with a single public repository. Because the releases are made in the Enterprise repo, there may be times that you do not see the actual work being done on an issue you open, but that does not mean the team is not working on it. The team is committed to updating progress on open issues in the sensu-go repo, even if that work is being done in the Enterprise repo.

So the development model is a one-way vendoring from the public repository into the commercial one, and the public repository is upstream for everything, including the enterprise features. The practical consequence for a user of the open source version is that the code you read is the code the commercial product is built on, and the practical consequence for a contributor is that an issue filed in the public repo may be worked on in a repository you cannot see.

That is a legitimate model for a company-led open source project, and it is also a real difference from a community-run one. A team choosing a monitoring system should know which model they are buying into, because it determines where they file issues and what they can expect to see happen.

## Where Sensu Go is the wrong choice

The limits are mostly about what Sensu assumes and what it has deliberately left out.

First, the architecture is three processes plus a dashboard, plus an etcd cluster in production. A team with a handful of static servers and a scrape-based tool in mind is buying a distributed system to check a static fleet. The agent-based model is a liability there, because you now run an agent on every host, and the auto-discovery that makes it work for ephemeral infrastructure is extra machinery for a fleet that does not move.

Second, the JavaScript filter expressions are a trade. They remove a Ruby dependency and they give you a language most people know, and they also give you a full interpreter embedded in the hot path of event processing. A team whose filters are simple could do the same thing in a much smaller language, and a team whose filters are complex now has a language where a typo is a runtime error rather than a compile error.

Third, the web UI is a separate product, so the dashboard is a deployment of its own with its own version to track, and a from-source install no longer gives you one.

Fourth, the release model means the tags in this repository and the packages you download are not the same artefacts. The summary says the released packages come from the Enterprise repo, and the version numbers in the linker flag example in the documentation are from the 5.14 era, so the documentation's build examples have drifted from the current 6.x line. The changelog situation reflects the same split, with `CHANGELOG-6.md` and `CHANGELOG-7.md` at the root, which suggests a 7.x line is in preparation alongside the current one.

Fifth, the event model, while better, has a consequence. Events are always handled unless explicitly filtered, so a misconfigured filter or a handler that fires on everything produces noise, and the fix is to write filters. A system that drops what it does not understand is quieter; a system that handles everything is noisier and more predictable, and which of those you want is a genuine choice rather than a bug.

Sixth, and this is the operational one, this is a monitoring system that stores its own data. The embedded etcd is convenient to start with and a thing to own later, and the docker-compose file shows the shape of a real deployment, three backends forming an etcd cluster, with a state directory per node and peer and client ports exposed. Running that in production is a distributed systems exercise, and a team that has never run etcd will be learning that alongside the monitoring.

## Conclusion

Sensu Go fits a team whose infrastructure comes and goes, where checks have to be discovered and registered rather than configured by hand, and where a scripting language in the filter layer is worth the cost. It is the wrong choice for a static fleet where a simple agent or a scrape-based tool would do, and the wrong choice for a team that wants the web UI bundled with the backend, since that has been a separate product since 6.0. Check three things before you commit: that you are comfortable with a three-process architecture of agent, backend, and sensuctl, that you read what the embedded etcd means for your own datastore plans, and that you check the version pairing, since the current release line is 6.x while the changelog in the tree is split into CHANGELOG-6.md and CHANGELOG-7.md.

## FAQ

### What is Sensu Go and what makes it different from the original Sensu?

Sensu Go is a complete rewrite of Sensu in Go, an agent based monitoring system with built-in auto-discovery for ephemeral infrastructure. It can rely on an embedded etcd datastore for persistence instead of requiring external services like Redis or RabbitMQ, it replaces Ruby expressions with JavaScript filter expressions by embedding a JavaScript interpreter, and unlike the original Sensu its events are always handled unless explicitly filtered.

### How do I build Sensu Go from source?

You need Go >= 1.18, and you should clone the repository outside of the GOPATH since Sensu Go uses Go Modules. Then `go run ./cmd/sensu-agent`, `go run ./cmd/sensu-backend`, and `go run ./cmd/sensuctl` compile and run each component in one step, and `go build -o bin/sensu-agent ./cmd/sensu-agent` and its equivalents put the binaries in the `bin/` directory.

### Where does the Sensu Go web UI live now?

Since Sensu Go version 6.0, the web UI is a standalone product and is no longer included with the Sensu backend, so a from-source build gives you the agent, the backend, and sensuctl without the dashboard. To build the web UI from source you use the installation instructions in the Sensu Go Web repository.

### How does the open source Sensu Go relate to Sensu Enterprise?

Sensu Go is the upstream for Sensu Enterprise, and in the Go community's terms Sensu Go is vendored into the Sensu Enterprise Go repo. The packages released for new versions come from the Enterprise repo, with enterprise-only features unlocked by a license key, which means work on an issue opened in the public repo may happen in a repository you cannot see.

## Sources

- [License: MIT](https://github.com/sensu/sensu-go/blob/main/LICENSE)
- [Project website](https://sensu.io)
- [README](https://github.com/sensu/sensu-go/blob/main/README.md)
- [Releases](https://github.com/sensu/sensu-go/releases)
- [sensu/sensu-go on GitHub](https://github.com/sensu/sensu-go)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/sensu-sensu-go
