• 11 min read

What is Perses?

Perses is a CNCF (Cloud Native Computing Foundation) sandbox project designed to fill the missing gap in the observability landscape. If you've worked with observability tools before, you would understand how challenging it can be to centralize visualization of your traces, metrics, and logs.

You can have traces from Jaeger, which has its own user interface running separately. Prometheus metrics, which you can visualize in any given number of ways. Plus, logs on a different system. All these would require your developers to keep track of different tools.


The Perses project provides an open standard for creating dashboards for observability data. At the time of writing, the Perses project supports Prometheus, Thanos, and Jaeger as data sources. If you are curious as to what it looks like, here is a screenshot:

Perses Dashboard

Node exporter dashboard using the Perses project

The image above is a screenshot of the node exporter dashboard using the Perses project; if you're familiar with Grafana, you'd instantly recognize it as it provides all the same panels and graphs; this is made possible due to Perses’ native support for Prometheus metrics.


This article will start by sharing a brief history of Perses and its key features. After that, you will learn how Perses works, from its installation to usage. Towards the end, this article will explain how Perses differs from Grafana.

Perses’s journey to CNCF sandbox project

Before Perses, if you explored the vendor-neutral and CNCF-stamped tools, you would notice a gap in observability tooling. There were tools for:

  • Metrics format — Open Metrics, OpenTelemetry
  • Endpoints discovery, metrics ingestion— Prometheus
  • Prometheus at scale, long-term storage — Thanos, cortex


But there were no tools for visualization. This prompted the creation of the Perses project in 2021. 

Perses Journey to a CNCF sandbox project

Perses Journey to a CNCF Sandbox Project

At the PromCon EU 2023, Perses` maintainers — Augustin Husson & Antoine Thebaud — presented Perses as a CNCF candidate for observability visualization with a strong goal of being GitOps friendly, this meant that it needed to support static validation, have native Kubernetes support and be declarative in nature. 


In March of 2024, Perses submitted its application to join the CNCF, and in August of 2024, having delivered on its initial goals, as you will see shortly, it was accepted into the CNCF as a sandbox project.

Key features of Perses

While the core of the Perses project remains to provide an open specification for visualizing observability data, it also provides a set of features that complements its core focus.

Dashboards-as-Code (DaC)

A big part of why the Perses project is able to provide an open specification is because dashboards are defined as code. This enables you to define any kind of components in libraries, from simple color codes to complex templates, for re-usage across as many dashboards as you want. In the next section, we will discuss how DaC works and what it looks like.

GitOps friendly

The Perses project also caters to teams looking to declaratively manage their dashboards. Using the Perses CLI, you can manage your dashboards and perform actions in CI/CD pipelines.

Kubernetes native

Perses aims to be Kubernetes native; this means that it understands Kubernetes resources, and you can build visualizations much more easily than with a separate plugin. The Perses operator is currently a priority on the roadmap. It uses an interesting architecture where the standard perses model is as in the image below.

Perses Database Model

Source: Perses Github

Has been mapped to Kubernetes:

Kubernetes Database Model

Source: Perses Github

From the diagram above, the data source becomes each resource, such as pods, deployments, and secrets; instead of having a project, namespaces are used to group resources. This will also hold true for custom resource definitions (CRDs) you have deployed in your cluster.

Embeddable components

Beyond providing panels within dashboards, the Perses project allows you to embed visualizations within your web application using embedded panels. This is useful because, at times, you do not want to spin up an entire dashboard for the insights you're looking for. This approach is much more compatible when you are trying to embed visualizations in existing applications.

For example, RedHat OpenShift powers part of its new tracing UI by embedding a Perses panel in the OpenShift web UI.

How Perses works

Perses works using a combination of data sources and plugins; data sources work similarly to other visualization tools; examples of data sources are Jaeger traces or metrics from Prometheus.

Plugins, however, allow you to bring in your own data source. At the time of writing, plugins are undergoing a redesign, and you can follow the development on the public roadmap.

Installing Perses

To get started with the Perses, project, you have options to install it using:

  • Precompiled binaries
  • Docker images

To use precompiled binaries, you can download a release for you operating system on GitHub. Using the latest release binary is the recommended way of installing the Perses CLI.

You can start Perses in a container using its Docker images. The following is an example docker command:

sh
0
docker run --name perses -d -p 127.0.0.1:8080:8080 persesdev/perses

You can learn more about running the Perses project in containers by checking out its documentation.

Interacting with Perses

Besides the Perses application, you can interact with its backend REST API via the Perses CLI (percli). With the Perses CLI, you can manage resources such as dashboards, data sources, projects, etc.

The core of the Perses project lies in its Dashboard-as-Code approach, this means you define your dashboards using the Cue or Golang SDKs. 

The following is an example of a dashboard written in Golang:

go
01234567891011121314151617181920212223242526272829303132333435363738394041424344454647
package main
import (
"flag"
"GitHub.com/perses/perses/go-sdk"
"GitHub.com/perses/perses/go-sdk/dashboard"
"GitHub.com/perses/perses/go-sdk/panel"
"GitHub.com/perses/perses/go-sdk/prometheus/query"
"GitHub.com/perses/perses/go-sdk/panel-group"
timeSeriesPanel "GitHub.com/perses/perses/go-sdk/panel/time-series"
promDs "GitHub.com/perses/perses/go-sdk/prometheus/datasource"
labelValuesVar "GitHub.com/perses/perses/go-sdk/prometheus/variable/label-values"
listVar "GitHub.com/perses/perses/go-sdk/variable/list-variable"
)
func main() {
flag.Parse()
exec := sdk.NewExec()
builder, buildErr := dashboard.New("ContainersMonitoring",
dashboard.ProjectName("MyProject"),
dashboard.AddVariable("stack",
listVar.List(
labelValuesVar.PrometheusLabelValues("paas",
labelValuesVar.Matchers("thanos_build_info{}"),
labelValuesVar.Datasource("promDemo"),
),
listVar.DisplayName("My Super PaaS"),
),
),
dashboard.AddPanelGroup("Resource usage",
panelgroup.PanelsPerLine(3),
panelgroup.AddPanel("Container memory",
timeSeriesPanel.Chart(),
panel.AddQuery(
query.PromQL("max by (container) (container_memory_rss{paas=\"$paas\",namespace=\"$namespace\",pod=\"$pod\",container=\"$container\"})"),
),
),
),
dashboard.AddDatasource("promDemo", promDs.Prometheus(promDs.HTTPProxy("https://demo.prometheus.com"))),
)
exec.BuildDashboard(builder, buildErr)
}

In the Go code snippet above, the dashboard is initialized with the dashboard.New function:

go
0123
builder, buildErr := dashboard.New("ContainersMonitoring",
dashboard.ProjectName("MyProject"),
...
)

Here:

  • "ContainersMonitoring": Is the name of the dashboard.
  • dashboard.ProjectName("MyProject"): Associates the dashboard with a project named "MyProject."

This creates a container for all the panels, variables, and datasources that will make up the dashboard.

The data source defines where the dashboard will fetch data. This example adds a Prometheus datasource using the dashboard.AddDatasource method:

go
012
dashboard.AddDatasource("promDemo",
promDs.Prometheus(promDs.HTTPProxy("https://demo.prometheus.com"))
),

promDs.HTTPProxy("https://demo.prometheus.com"): Points to the Prometheus server URL.

The panel group organizes related panels into a grid layout. Each panel visualizes a specific metric.

go
012345678
dashboard.AddPanelGroup("Resource usage",
panelgroup.PanelsPerLine(3),
panelgroup.AddPanel("Container memory",
timeSeriesPanel.Chart(),
panel.AddQuery(
query.PromQL("max by (container) (container_memory_rss{paas=\"$paas\",namespace=\"$namespace\",pod=\"$pod\",container=\"$container\"})"),
),
),
),

The PromQL query is then added using the panel.AddQuery method:

go
012
panel.AddQuery(
query.PromQL("max by (container) (container_memory_rss{paas=\"$paas\",namespace=\"$namespace\",pod=\"$pod\",container=\"$container\"})"),
)

Finally, the exec.BuildDashboard function compiles everything into a usable dashboard.

To put this in action, you would run the following command to build the final dashboard definition (i.e., Perses dashboard in JSON or YAML format):

sh
0
percli dac build -f main.go -o json

If the build is successful and you are satisfied with the result of your DaC definition for a given dashboard, you can finally deploy it to Perses with the apply command:

sh
0
percli apply -f built/my_dashboard.json

To learn more about this example, study the Perses Dashboard-as-Code documentation.

Using Perses with Prometheus metrics

As mentioned earlier, Perses supports Prometheus metrics and provides different types of visualizations. For example, below is a screenshot of the graph view when running Prometheus queries.

Perses Graph on Prometheus Metrics

Perses Graph on Prometheus Metrics

Also supported are table and finder views. The table view provides a quick summary of individual metrics based on your query, and the finder view is used for discovering possible queries and existing metrics.


If you’re looking to get hands-on experience with Perses without installation, try out the demo instance over here.

How does Perses differ from Grafana?

If Perses reminds you of Grafana, you're not alone! Perses is designed with a similar user experience in mind. Beyond familiarity, Perses boasts robust support for all major data sources and a flexible plugin system that empowers you to integrate custom metrics as a data source.


While both Perses and Grafana are fundamentally tools for visualization, Perses aims to provide an open standard for creating dashboards. To achieve this, Perses offers a way to define dashboards as code using Golang or CUE, although it might seem counterintuitive as you usually want to define your dashboard using a web interface where you can drag and drop things.


When using a tool such as Grafana, modifying your dashboard often entails modifying a json file in some capacity, which isn't always ideal as you can very easily break your configuration, especially in complex dashboards.


Dashboards as Code (DaC) brings advantages such as compile time checks, refactoring and, more importantly, allows you to create truly reusable dashboards using familiar programming concepts.

On top of that Grafana is licensed under the AGPL, which may, or may not be problematic, while Perses is fully open source under the much friendlier Apache 2.0 license.

Conclusion

The Perses project is taking a different approach to building dashboards, one that involves building repeatable dashboards through its SDKs and embraces shift left methodology by being GitOps friendly. Beyond providing an open specification for dashboards, Perses also aims to be compatible with your existing observability stack, which is essential if you are just testing the waters.


It has also seen adoption from prominent industry players such as RedHat and SAP, with Perses powering the new openshift traces UI and Chronosphere, which are making significant code contributions.

Perses in Dash0

If you use the Perses project and want to make observability easy for developers, even those not familiar with CUE or Go, try Dash0. Dash0 dashboards are fully compatible with Perses, and you can easily import your Perses dashboards using JSON and enjoy flexibility and control over your telemetry data.


Kubernetes users are in luck, as the Dash0 operator will watch for Perses dashboard resources in all namespaces that have a Dash0 monitoring resource deployed and synchronize the Perses dashboard resources with the Dash0 backend.