Menu
Open source

Receive profiles from Pyroscope SDKs

The pyroscope.receive_http component in Alloy receives profiles from applications instrumented with Pyroscope SDKs. This approach provides several benefits:

  • Lower latency by sending profiles to a local Alloy instance instead of over internet
  • Separation of infrastructure concerns (auth, routing) from application code
  • Centralized management of authentication and metadata enrichment

For more information about this component, refer to the pyroscope.receive_http component documentation.

Note

The pyroscope.receive_http component is currently in public preview. To use this component, set the --stability.level flag to public-preview. For more information about Alloy’s run usage, refer to the run command documentation documentation.

To set up profile receiving, you need to:

  1. Configure Alloy components
  2. Configure your application’s SDK
  3. Start Alloy

Configure Alloy components

The configuration requires at least two components:

Here’s a basic configuration that sets up a simple profile collection pipeline. It creates a receiver to collect profiles from your applications and forwards them through a writer component to send them to the Pyroscope backend:

alloy
// Receives profiles over HTTP
pyroscope.receive_http "default" {
   http {
       listen_address = "0.0.0.0"
       listen_port = 9999
   }
   forward_to = [pyroscope.write.backend.receiver]
}

// Forwards profiles to Pyroscope
pyroscope.write "backend" {
   endpoint {
       url = "http://pyroscope:4040"
   }
}

Configure application SDK

Update your application’s SDK configuration to point to Alloy’s receive endpoint instead of Pyroscope directly. For example, in Go:

Go
config := pyroscope.Config{
    ApplicationName: "my.service.cpu",
    ServerAddress:   "http://localhost:9999", // Alloy's receive endpoint
}

Check your specific language SDK documentation for the exact configuration options.

Examples

The examples in this section provide samples you can use as a starting point for your own configurations.

Basic receiving setup

This example shows a basic setup receiving profiles on port 9090 and forwarding them to a local Pyroscope instance:

alloy
pyroscope.receive_http "default" {
    http {
        listen_address = "0.0.0.0"
        listen_port = 9090
    }
    forward_to = [pyroscope.write.backend.receiver]
}

pyroscope.write "production" {
    endpoint {
        url = "http://localhost:4040"
    }
}

Authentication

To send profiles to an authenticated Pyroscope endpoint:

alloy
pyroscope.write "production" {
    endpoint {
        url = "http://pyroscope:4040"
        basic_auth {
            username = env("PYROSCOPE_USERNAME")
            password = env("PYROSCOPE_PASSWORD")
        }
    }
}

Adding external labels

External labels are added to all profiles forwarded through the write component. This is useful for adding infrastructure metadata:

alloy
pyroscope.receive_http "default" {
    http {
        listen_address = "0.0.0.0"
        listen_port = 9999
    }
    forward_to = [pyroscope.write.backend.receiver]
}

pyroscope.write "backend" {
    endpoint {
        url = "http://pyroscope:4040"
    }
    external_labels = {
        "env"      = "production",
        "region"   = "us-west-1",
        "instance" = env("HOSTNAME"),
        "cluster"  = "main",
    }
}

Multiple destinations

Forward received profiles to multiple destinations - useful for testing or migration scenarios:

alloy
pyroscope.receive_http "default" {
    http {
        listen_address = "0.0.0.0"
        listen_port = 9999
    }
    forward_to = [pyroscope.write.staging.receiver, pyroscope.write.production.receiver]
}

// Send profiles to staging
pyroscope.write "staging" {
    endpoint {
        url = "http://pyroscope-staging:4040"
    }
    external_labels = {
        "env" = "staging",
    }
}

// Send profiles to production
pyroscope.write "production" {
    endpoint {
        url = "http://pyroscope-production:4041"
    }
    external_labels = {
        "env" = "production",
    }
}

Note

This configuration will duplicate the received profiles and send a copy to each configured pyroscope.write component.

Another approach is to configure multiple receivers with multiple destinations:

alloy
pyroscope.receive_http "staging" {
    http {
        listen_address = "0.0.0.0"
        listen_port = 9998
    }
    forward_to = [pyroscope.write.staging.receiver]
}

pyroscope.receive_http "production" {
    http {
        listen_address = "0.0.0.0"
        listen_port = 9999
    }
    forward_to = [pyroscope.write.production.receiver]
}

// Send profiles to staging
pyroscope.write "staging" {
    endpoint {
        url = "http://pyroscope-staging:4040"
    }
    external_labels = {
        "env" = "staging",
    }
}

// Send profiles to production
pyroscope.write "production" {
    endpoint {
        url = "http://pyroscope-production:4041"
    }
    external_labels = {
        "env" = "production",
    }
}

For more information about component configuration options, refer to: