Grafana Tempo, by default, locks down your traces to the organization they were ingested into, but you can actually query across them with a bit of configuration.
Let’s see it in action. Imagine you have two organizations in Grafana, "Alpha" and "Beta." Normally, if you’re logged in as a user in "Alpha," queries to Tempo will only return traces ingested by "Alpha."
Here’s a typical Tempo query in Grafana’s Explore view, filtered by service name:
{service="my-app"}
If you’re in the "Alpha" org, this shows traces for my-app from "Alpha." If you switch to the "Beta" org, it shows traces for my-app from "Beta." They’re completely separate.
To enable cross-tenant querying, you need to modify the Tempo configuration. The key is the multi_tenant_enabled setting in the Tempo configuration file (often tempo.yaml or similar). When this is set to true, Tempo stops enforcing strict tenant isolation at the query layer.
Here’s a snippet of the relevant Tempo configuration:
distributor:
# ... other distributor settings
multi_tenant_enabled: true
ingester:
# ... other ingester settings
multi_tenant_enabled: true
query_frontend:
# ... other query frontend settings
multi_tenant_enabled: true
Setting multi_tenant_enabled: true across these components tells Tempo that it should not assume that a query originating from a specific tenant (organization) should be restricted to data from that same tenant. Instead, it will consider data from all tenants that the querying user has access to.
The magic happens within Grafana itself. When multi_tenant_enabled is true in Tempo, Grafana’s Tempo data source will automatically send queries that don’t explicitly filter by tenant ID to all accessible tenants. This means that when you run a query like {service="my-app"}, if your Grafana user has access to both "Alpha" and "Beta" organizations, the query sent to Tempo will effectively be an "OR" across those tenants.
So, after enabling multi_tenant_enabled: true in Tempo and restarting the Tempo components, if you’re logged into Grafana as a user who can see both "Alpha" and "Beta" organizations, the query {service="my-app"} will now return traces for my-app from both "Alpha" and "Beta" organizations.
The internal mechanism at play is that without multi_tenant_enabled: true, Tempo’s query path expects a tenant ID to be present or implied for every query, and it uses that to filter data at the storage layer. When enabled, it relaxes this constraint, allowing the query to traverse all accessible data partitions, irrespective of their original ingestion tenant. This is particularly useful for central observability platforms where you might want a global view of services, even if those services are deployed across different logical environments or teams represented as separate Grafana organizations.
The most surprising part for many is that this doesn’t require any change to the Grafana data source configuration itself, beyond ensuring it’s pointing to a Tempo instance with multi_tenant_enabled set. The complexity is entirely on the Tempo side.
Once you have cross-tenant querying enabled, the next logical step is to explore how to filter and aggregate traces across these multiple tenants using Grafana’s powerful dashboarding features.