<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Get started with Grafana Alloy on Grafana Labs</title><link>https://grafana.com/docs/alloy/v1.15/get-started/</link><description>Recent content in Get started with Grafana Alloy on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/alloy/v1.15/get-started/index.xml" rel="self" type="application/rss+xml"/><item><title>Components</title><link>https://grafana.com/docs/alloy/v1.15/get-started/components/</link><pubDate>Mon, 30 Mar 2026 15:47:22 +0000</pubDate><guid>https://grafana.com/docs/alloy/v1.15/get-started/components/</guid><content><![CDATA[&lt;h1 id=&#34;components&#34;&gt;Components&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;Components&lt;/em&gt; are the building blocks of Alloy.
Each component performs a single task, such as retrieving secrets, collecting metrics, or processing data.&lt;/p&gt;
&lt;p&gt;You learned about blocks, attributes, and expressions in the previous section.
Components use the same syntax structure. They&amp;rsquo;re special blocks that Alloy knows how to execute.
When you define a component block in your configuration, Alloy creates a running instance that performs the component&amp;rsquo;s specific task.&lt;/p&gt;
&lt;p&gt;Components are the key to the flexibility of Alloy.
You can combine them to create data pipelines that collect, transform, and send telemetry data exactly how you need.&lt;/p&gt;
&lt;h2 id=&#34;component-structure&#34;&gt;Component structure&lt;/h2&gt;
&lt;p&gt;Every component has two main parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Arguments:&lt;/strong&gt; Settings that configure the component&amp;rsquo;s behavior. These are the attributes and blocks you define inside the component block.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Exports:&lt;/strong&gt; Values that the component makes available to other components. The running component generates these exports and they can change over time.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When Alloy loads your configuration:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It reads the arguments you provided in each component block.&lt;/li&gt;
&lt;li&gt;It creates a running instance of the component with those arguments.&lt;/li&gt;
&lt;li&gt;The component starts its work and may update its exports as it runs.&lt;/li&gt;
&lt;li&gt;Other components can reference these exports in their arguments.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;component-syntax&#34;&gt;Component syntax&lt;/h2&gt;
&lt;p&gt;Components use the block syntax you learned about earlier.
The general pattern is:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;COMPONENT_NAME &amp;#34;LABEL&amp;#34; {
  // Arguments (attributes and nested blocks)
  attribute_name = &amp;#34;value&amp;#34;

  nested_block {
    setting = &amp;#34;value&amp;#34;
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;COMPONENT_NAME&lt;/code&gt; tells Alloy which type of component to create.
The &lt;code&gt;&amp;quot;LABEL&amp;quot;&lt;/code&gt; is a unique identifier you choose to distinguish between multiple instances of the same component type.&lt;/p&gt;
&lt;h2 id=&#34;component-names&#34;&gt;Component names&lt;/h2&gt;
&lt;p&gt;Each component has a name that describes its purpose.
For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;local.file&lt;/code&gt; retrieves file contents from disk.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;prometheus.scrape&lt;/code&gt; collects Prometheus metrics.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;loki.write&lt;/code&gt; sends log data to Loki.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You define components by specifying the component name with a user-defined label:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;local.file &amp;#34;my_config&amp;#34; {
  filename = &amp;#34;/etc/app/config.yaml&amp;#34;
}

prometheus.scrape &amp;#34;api_metrics&amp;#34; {
  targets = [{&amp;#34;__address__&amp;#34; = &amp;#34;localhost:8080&amp;#34;}]
  forward_to = [prometheus.remote_write.default.receiver]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;component-references&#34;&gt;Component references&lt;/h2&gt;
&lt;p&gt;You reference components by combining their name with their label.
For example, you can reference the &lt;code&gt;local.file&lt;/code&gt; component labeled &lt;code&gt;my_config&lt;/code&gt; as &lt;code&gt;local.file.my_config&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The combination of component name and label must be unique in your configuration.
This allows you to define multiple instances of the same component type:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;prometheus.scrape &amp;#34;api&amp;#34; {
  targets = [{&amp;#34;__address__&amp;#34; = &amp;#34;api.example.com:8080&amp;#34;}]
  forward_to = [prometheus.remote_write.production.receiver]
}

prometheus.scrape &amp;#34;database&amp;#34; {
  targets = [{&amp;#34;__address__&amp;#34; = &amp;#34;db.example.com:9090&amp;#34;}]
  forward_to = [prometheus.remote_write.production.receiver]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;component-exports&#34;&gt;Component exports&lt;/h2&gt;
&lt;p&gt;Components can share data through exports.
When one component references another component&amp;rsquo;s export, it creates a connection between them.
You&amp;rsquo;ll learn more about these component references in &lt;a href=&#34;../expressions/&#34;&gt;Expressions&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;local.file &amp;#34;api_key&amp;#34; {
  filename = &amp;#34;/etc/secrets/api.key&amp;#34;
}

prometheus.remote_write &amp;#34;production&amp;#34; {
  endpoint {
    url = &amp;#34;https://prometheus.example.com/api/v1/write&amp;#34;

    basic_auth {
      username = &amp;#34;metrics&amp;#34;
      password = local.file.api_key.content  // Reference the file content
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In this example:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;local.file&lt;/code&gt; component reads a file and exports its content.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;prometheus.remote_write&lt;/code&gt; component uses that content as a password.&lt;/li&gt;
&lt;li&gt;When the file changes, Alloy automatically updates the &lt;code&gt;local.file&lt;/code&gt; component&amp;rsquo;s exports.&lt;/li&gt;
&lt;li&gt;This causes Alloy to re-evaluate the &lt;code&gt;prometheus.remote_write&lt;/code&gt; component with the new password.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You&amp;rsquo;ll learn the details of how to write these references in &lt;a href=&#34;../expressions/&#34;&gt;Expressions&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next steps&lt;/h2&gt;
&lt;p&gt;Now that you understand what components are and how they work, learn how to use them effectively:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;./configure-components/&#34;&gt;Configure components&lt;/a&gt; - Learn how to define and configure components with arguments and blocks&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;./build-pipelines/&#34;&gt;Build data pipelines&lt;/a&gt; - Connect components together to create data processing workflows&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;./component-controller/&#34;&gt;Component controller&lt;/a&gt; - Understand how Alloy manages components at runtime&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To extend component functionality:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;./custom-components/&#34;&gt;Custom components&lt;/a&gt; - Create reusable custom components for your specific needs&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;./community-components/&#34;&gt;Community components&lt;/a&gt; - Use components shared by the Alloy community&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For hands-on learning:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../../tutorials/&#34;&gt;Tutorials&lt;/a&gt; - Build complete data collection pipelines step by step&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For reference:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../expressions/&#34;&gt;Expressions&lt;/a&gt; - Use component exports in dynamic configurations&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../syntax/&#34;&gt;Alloy syntax&lt;/a&gt; - Explore advanced syntax features and patterns&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/&#34;&gt;Component reference&lt;/a&gt; - Browse all available components and their options&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="components">Components&lt;/h1>
&lt;p>&lt;em>Components&lt;/em> are the building blocks of Alloy.
Each component performs a single task, such as retrieving secrets, collecting metrics, or processing data.&lt;/p>
&lt;p>You learned about blocks, attributes, and expressions in the previous section.
Components use the same syntax structure. They&amp;rsquo;re special blocks that Alloy knows how to execute.
When you define a component block in your configuration, Alloy creates a running instance that performs the component&amp;rsquo;s specific task.&lt;/p></description></item><item><title>Expressions</title><link>https://grafana.com/docs/alloy/v1.15/get-started/expressions/</link><pubDate>Mon, 30 Mar 2026 15:47:22 +0000</pubDate><guid>https://grafana.com/docs/alloy/v1.15/get-started/expressions/</guid><content><![CDATA[&lt;h1 id=&#34;expressions&#34;&gt;Expressions&lt;/h1&gt;
&lt;p&gt;You learned about components and how they work together in pipelines in the previous sections.
Now you&amp;rsquo;ll learn about &lt;em&gt;expressions&lt;/em&gt;. These are the mechanism that makes your configurations dynamic by computing values and connecting components together.&lt;/p&gt;
&lt;p&gt;Expressions are the key to Alloy&amp;rsquo;s flexibility.
They let you reference data from other components, transform values using functions, and create dynamic configurations that respond to changing conditions.&lt;/p&gt;
&lt;h2 id=&#34;how-expressions-work&#34;&gt;How expressions work&lt;/h2&gt;
&lt;p&gt;Expressions compute values that you assign to component arguments.
The component controller evaluates expressions when components start and whenever their dependencies change.&lt;/p&gt;
&lt;p&gt;Basic expressions are literal values like &lt;code&gt;&amp;quot;Hello, world!&amp;quot;&lt;/code&gt; or &lt;code&gt;true&lt;/code&gt;.
More powerful expressions can reference component exports, call functions, or perform calculations.&lt;/p&gt;
&lt;p&gt;All component arguments have an underlying &lt;a href=&#34;./types_and_values/&#34;&gt;type&lt;/a&gt;.
Alloy checks the expression type during evaluation to ensure compatibility before assigning the result to an attribute.
This type checking prevents configuration errors and ensures your pipelines work correctly.&lt;/p&gt;
&lt;h2 id=&#34;expression-types&#34;&gt;Expression types&lt;/h2&gt;
&lt;p&gt;The four main types of expressions you&amp;rsquo;ll use are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Literal values&lt;/strong&gt;: Constants like &lt;code&gt;&amp;quot;debug&amp;quot;&lt;/code&gt;, &lt;code&gt;8080&lt;/code&gt;, or &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Component references&lt;/strong&gt;: Values from other components like &lt;code&gt;local.file.config.content&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Function calls&lt;/strong&gt;: Built-in functions like &lt;code&gt;sys.env(&amp;quot;HOME&amp;quot;)&lt;/code&gt; or &lt;code&gt;encoding.from_json(local.file.data.content)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Arithmetic operations&lt;/strong&gt;: Mathematical calculations like &lt;code&gt;1 &#43; 2&lt;/code&gt; or &lt;code&gt;port_base &#43; offset&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can combine these types to create complex expressions that transform data and connect components in sophisticated ways.&lt;/p&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next steps&lt;/h2&gt;
&lt;p&gt;Now that you understand how expressions work, learn to write different types of expressions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;./referencing_exports/&#34;&gt;Component exports&lt;/a&gt; - Reference data from other components to connect your pipeline&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;./types_and_values/&#34;&gt;Types and values&lt;/a&gt; - Understand data types and how they work with expressions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For advanced expression features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;./function_calls/&#34;&gt;Function calls&lt;/a&gt; - Transform and compute values using built-in functions&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;./operators/&#34;&gt;Operators&lt;/a&gt; - Combine and manipulate values using mathematical and logical operators&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="expressions">Expressions&lt;/h1>
&lt;p>You learned about components and how they work together in pipelines in the previous sections.
Now you&amp;rsquo;ll learn about &lt;em>expressions&lt;/em>. These are the mechanism that makes your configurations dynamic by computing values and connecting components together.&lt;/p></description></item><item><title>Alloy syntax</title><link>https://grafana.com/docs/alloy/v1.15/get-started/syntax/</link><pubDate>Mon, 30 Mar 2026 15:47:22 +0000</pubDate><guid>https://grafana.com/docs/alloy/v1.15/get-started/syntax/</guid><content><![CDATA[&lt;h1 id=&#34;alloy-syntax&#34;&gt;Alloy syntax&lt;/h1&gt;
&lt;p&gt;You learned about components, expressions, and basic configuration elements in the previous sections.
Now you&amp;rsquo;ll learn the detailed syntax rules that govern how to write Alloy configuration files.&lt;/p&gt;
&lt;p&gt;Understanding the syntax ensures your configurations are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Correctly parsed&lt;/strong&gt;: Follow rules that the Alloy parser expects.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Maintainable&lt;/strong&gt;: Use consistent patterns and formatting.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Readable&lt;/strong&gt;: Structure code clearly for yourself and your team.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Error-free&lt;/strong&gt;: Avoid common syntax mistakes that prevent successful evaluation.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The Alloy configuration syntax is &lt;em&gt;declarative&lt;/em&gt;, meaning you describe what you want rather than how to achieve it.
The parser evaluates all dependencies between elements automatically, so the order of blocks and attributes doesn&amp;rsquo;t matter.&lt;/p&gt;
&lt;h2 id=&#34;comments&#34;&gt;Comments&lt;/h2&gt;
&lt;p&gt;Alloy configuration files support single-line &lt;code&gt;//&lt;/code&gt; comments and block &lt;code&gt;/* */&lt;/code&gt; comments.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;// This is a single-line comment

/*
This is a block comment
that can span multiple lines
*/&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;identifiers&#34;&gt;Identifiers&lt;/h2&gt;
&lt;p&gt;An identifier in Alloy syntax is valid if it contains one or more UTF-8 letters, digits, or underscores.
Identifiers can&amp;rsquo;t start with a digit.&lt;/p&gt;
&lt;p&gt;The parser uses identifiers for:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Attribute names&lt;/strong&gt;: Keys in key-value pairs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Component names&lt;/strong&gt;: Parts of block names like &lt;code&gt;prometheus&lt;/code&gt; in &lt;code&gt;prometheus.scrape&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Component labels&lt;/strong&gt;: User-defined names to distinguish component instances.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Variable references&lt;/strong&gt;: Names used in expressions and function calls.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Valid identifiers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;my_component&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Component123&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;_private&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;métrica_café&lt;/code&gt; (Unicode letters are supported)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Invalid identifiers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;123component&lt;/code&gt; (starts with digit)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;my-component&lt;/code&gt; (contains hyphen)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;my component&lt;/code&gt; (contains space)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;my.component&lt;/code&gt; (contains dot, which has special meaning)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;attributes-and-blocks&#34;&gt;Attributes and Blocks&lt;/h2&gt;
&lt;p&gt;Alloy configurations are built using two main syntax elements: attributes and blocks.
Attributes set individual values, while blocks group related configuration and create component instances.&lt;/p&gt;
&lt;h3 id=&#34;attributes&#34;&gt;Attributes&lt;/h3&gt;
&lt;p&gt;Attributes configure individual settings using the format &lt;code&gt;ATTRIBUTE_NAME = ATTRIBUTE_VALUE&lt;/code&gt;.
The parser evaluates attributes during component configuration to determine runtime behavior.&lt;/p&gt;
&lt;p&gt;You can place attributes as:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Top-level settings&lt;/strong&gt;: Global Alloy configuration.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Component arguments&lt;/strong&gt;: Settings within component blocks.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nested block settings&lt;/strong&gt;: Configuration within nested blocks.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Examples of different attribute contexts:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;// Top-level attribute
log_level = &amp;#34;debug&amp;#34;

// Component block with attributes
prometheus.scrape &amp;#34;app&amp;#34; {
  targets    = [{ &amp;#34;__address__&amp;#34; = &amp;#34;localhost:9090&amp;#34; }]
  scrape_interval = &amp;#34;15s&amp;#34;

  // Nested block with attributes
  basic_auth {
    username = &amp;#34;admin&amp;#34;
    password = sys.env(&amp;#34;ADMIN_PASSWORD&amp;#34;)
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;ATTRIBUTE_NAME&lt;/code&gt; must be a valid Alloy &lt;a href=&#34;#identifiers&#34;&gt;identifier&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;ATTRIBUTE_VALUE&lt;/code&gt; can be:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Constant values&lt;/strong&gt;: Strings, numbers, booleans, arrays, or objects.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Expressions&lt;/strong&gt;: Function calls, component references, or calculations that compute dynamic values.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;blocks&#34;&gt;Blocks&lt;/h3&gt;
&lt;p&gt;Blocks configure Alloy components and organize related settings using curly braces.
The parser processes blocks to create and configure component instances.&lt;/p&gt;
&lt;p&gt;Block structure:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Block name&lt;/strong&gt;: Identifies the component type (required).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Block label&lt;/strong&gt;: User-defined identifier to distinguish multiple instances (optional).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Block body&lt;/strong&gt;: Contains attributes and nested blocks (required).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Some blocks can appear multiple times in your configuration when they have different labels:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;// Multiple instances of the same component type
prometheus.scrape &amp;#34;frontend&amp;#34; {
  targets = [{ &amp;#34;__address__&amp;#34; = &amp;#34;frontend:8080&amp;#34; }]
}

prometheus.scrape &amp;#34;backend&amp;#34; {
  targets = [{ &amp;#34;__address__&amp;#34; = &amp;#34;backend:9090&amp;#34; }]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Nested blocks provide structured configuration:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;prometheus.remote_write &amp;#34;production&amp;#34; {
  endpoint {
    url = &amp;#34;https://prometheus.example.com/api/v1/write&amp;#34;

    basic_auth {
      username = &amp;#34;metrics&amp;#34;
      password = local.file.credentials.content
    }
  }

  queue_config {
    capacity = 10000
    max_samples_per_send = 2000
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h4 id=&#34;examples&#34;&gt;Examples&lt;/h4&gt;
&lt;p&gt;Use the following pattern to create an unlabeled block.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;BLOCK_NAME {
  // Block body can contain attributes and nested unlabeled blocks
  IDENTIFIER = EXPRESSION // Attribute

  NESTED_BLOCK_NAME {
    // Nested block body
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Use the following pattern to create a labeled block.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;// Pattern for creating a labeled block:
BLOCK_NAME &amp;#34;BLOCK_LABEL&amp;#34; {
  // Block body can contain attributes and nested unlabeled blocks
  IDENTIFIER = EXPRESSION // Attribute

  NESTED_BLOCK_NAME {
    // Nested block body
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h4 id=&#34;block-naming-rules&#34;&gt;Block naming rules&lt;/h4&gt;
&lt;p&gt;The parser enforces specific rules for block names and labels:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Block names&lt;/strong&gt; must be either:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Valid component names&lt;/strong&gt;: Dot-separated identifiers like &lt;code&gt;prometheus.scrape&lt;/code&gt; or &lt;code&gt;local.file&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Special configuration blocks&lt;/strong&gt;: Built-in blocks for global settings like &lt;code&gt;logging&lt;/code&gt; or &lt;code&gt;tracing&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Block labels&lt;/strong&gt; (when required) must be:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Valid identifiers&lt;/strong&gt;: Follow the same rules as attribute names.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Double-quoted strings&lt;/strong&gt;: Wrapped in double quotes, not single quotes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unique within scope&lt;/strong&gt;: No two blocks of the same type can have identical labels.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Example showing proper block naming:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;// Component name: &amp;#34;local.file&amp;#34;, Label: &amp;#34;api_key&amp;#34;
local.file &amp;#34;api_key&amp;#34; {
  filename  = sys.env(&amp;#34;API_KEY_PATH&amp;#34;)
  is_secret = true
}

// Component name: &amp;#34;prometheus.scrape&amp;#34;, Label: &amp;#34;web_servers&amp;#34;
prometheus.scrape &amp;#34;web_servers&amp;#34; {
  targets = discovery.kubernetes.services.targets
  metrics_path = &amp;#34;/metrics&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The parser validates that:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Component names exist&lt;/strong&gt;: The component type must be available in Alloy.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Labels are unique&lt;/strong&gt;: Within the same component type.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Syntax is correct&lt;/strong&gt;: Follows the identifier and quoting rules.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;terminators&#34;&gt;Terminators&lt;/h2&gt;
&lt;p&gt;The parser requires terminators to separate statements and determine where expressions end.
All block and attribute definitions must end with a newline, which Alloy calls a &lt;em&gt;terminator&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;A newline acts as a terminator when it follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Complete expressions&lt;/strong&gt;: After any value, calculation, or function call.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Closing delimiters&lt;/strong&gt;: After &lt;code&gt;]&lt;/code&gt;, &lt;code&gt;)&lt;/code&gt;, or &lt;code&gt;}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Statement endings&lt;/strong&gt;: After attribute assignments or block definitions.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The parser ignores newlines in other contexts, allowing flexible formatting:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;// This formatting is valid - extra newlines are ignored
local.file &amp;#34;example&amp;#34; {
  filename = &amp;#34;/path/to/file&amp;#34;


  is_secret = true


  // Comments can also have extra spacing
}

// Expressions can span multiple lines
targets = [
  { &amp;#34;__address__&amp;#34; = &amp;#34;server1:9090&amp;#34; },
  { &amp;#34;__address__&amp;#34; = &amp;#34;server2:9090&amp;#34; },
  { &amp;#34;__address__&amp;#34; = &amp;#34;server3:9090&amp;#34; }
]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;formatting&#34;&gt;Formatting&lt;/h2&gt;
&lt;p&gt;Alloy provides a built-in formatter to ensure consistent code style.
Use the &lt;a href=&#34;../../reference/cli/fmt/&#34;&gt;&lt;code&gt;alloy fmt&lt;/code&gt; command&lt;/a&gt; to format your configuration files.&lt;/p&gt;
&lt;p&gt;The formatter:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Standardizes indentation&lt;/li&gt;
&lt;li&gt;Removes unnecessary whitespace&lt;/li&gt;
&lt;li&gt;Ensures consistent line endings&lt;/li&gt;
&lt;li&gt;Validates syntax&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next steps&lt;/h2&gt;
&lt;p&gt;Now that you understand the syntax fundamentals, learn how to use these elements to build working configurations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../components/&#34;&gt;Components&lt;/a&gt; - Learn about the building blocks that collect, transform, and send data&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../expressions/&#34;&gt;Expressions&lt;/a&gt; - Create dynamic configurations using functions and component references&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For advanced configuration techniques:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/cli/fmt/&#34;&gt;Formatting&lt;/a&gt; - Use &lt;code&gt;alloy fmt&lt;/code&gt; to automatically format your configuration files&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="alloy-syntax">Alloy syntax&lt;/h1>
&lt;p>You learned about components, expressions, and basic configuration elements in the previous sections.
Now you&amp;rsquo;ll learn the detailed syntax rules that govern how to write Alloy configuration files.&lt;/p></description></item><item><title>Modules</title><link>https://grafana.com/docs/alloy/v1.15/get-started/modules/</link><pubDate>Mon, 30 Mar 2026 15:47:22 +0000</pubDate><guid>https://grafana.com/docs/alloy/v1.15/get-started/modules/</guid><content><![CDATA[&lt;h1 id=&#34;modules&#34;&gt;Modules&lt;/h1&gt;
&lt;p&gt;You learned about components, expressions, and the configuration syntax in the previous sections.
Now you&amp;rsquo;ll learn about modules, the organizational structure that lets you package and reuse Alloy configurations.&lt;/p&gt;
&lt;p&gt;Modules enable powerful configuration management capabilities:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Code reuse&lt;/strong&gt;: Package common pipeline patterns into reusable custom components.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Organization&lt;/strong&gt;: Structure complex configurations into maintainable units.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sharing&lt;/strong&gt;: Distribute configurations across teams and projects.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Composition&lt;/strong&gt;: Combine multiple modules to build sophisticated data collection systems.&lt;/li&gt;
&lt;/ol&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;Most Alloy users don&amp;rsquo;t need modules when they first get started.
You can collect, process, and export metrics, logs, traces, and profiles using built-in components directly in your configuration.
Modules don&amp;rsquo;t add capabilities to Alloy or enable signal types, they&amp;rsquo;re purely a way to organize and reuse configuration.
Think of a module as a function in programming: it packages logic you already have so you can reuse it cleanly.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re just getting started, you can skip modules for now and return to them when your configuration grows or you need reuse.
However, if you plan to use &lt;a href=&#34;/docs/grafana-cloud/send-data/fleet-management/&#34;&gt;Fleet Management&lt;/a&gt; to manage multiple collectors, understanding modules helps you create reusable configurations that can be distributed across your fleet.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;A &lt;em&gt;module&lt;/em&gt; is a unit of Alloy configuration that contains components, custom component definitions, and import statements.
The module you pass to &lt;a href=&#34;../../reference/cli/run/&#34;&gt;the &lt;code&gt;run&lt;/code&gt; command&lt;/a&gt; becomes the &lt;em&gt;main configuration&lt;/em&gt; that Alloy executes.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&#34;#import-modules&#34;&gt;import modules&lt;/a&gt; to reuse &lt;a href=&#34;../components/custom-components/&#34;&gt;custom components&lt;/a&gt; defined by that module.&lt;/p&gt;
&lt;h2 id=&#34;when-to-use-a-module&#34;&gt;When to use a module&lt;/h2&gt;
&lt;p&gt;Create a module when you want to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reuse the same pipeline pattern multiple times&lt;/li&gt;
&lt;li&gt;Reduce duplicated configuration&lt;/li&gt;
&lt;li&gt;Hide complex pipelines behind a single interface&lt;/li&gt;
&lt;li&gt;Standardize pipelines across teams or environments&lt;/li&gt;
&lt;li&gt;Make large Alloy configurations easier to maintain&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If your configuration is small and each pipeline is unique, you probably don&amp;rsquo;t need a module.
If you find yourself copying and pasting the same group of components with small changes, a module can help.&lt;/p&gt;
&lt;h2 id=&#34;why-modules-help&#34;&gt;Why modules help&lt;/h2&gt;
&lt;p&gt;Without modules, repeated pipelines can look like this:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.receiver.otlp &amp;#34;app1&amp;#34; { ... }
otelcol.processor.batch &amp;#34;app1&amp;#34; { ... }
otelcol.exporter.otlp &amp;#34;app1&amp;#34; { ... }

otelcol.receiver.otlp &amp;#34;app2&amp;#34; { ... }
otelcol.processor.batch &amp;#34;app2&amp;#34; { ... }
otelcol.exporter.otlp &amp;#34;app2&amp;#34; { ... }&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;With a module, you define the pipeline once and reuse it:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;import.file &amp;#34;pipeline&amp;#34; {
  filename = &amp;#34;pipeline.alloy&amp;#34;
}

pipeline.app &amp;#34;app1&amp;#34; { ... }
pipeline.app &amp;#34;app2&amp;#34; { ... }&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This reduces duplication, improves readability, and makes updates safer because you only change the logic in one place.&lt;/p&gt;
&lt;h2 id=&#34;example&#34;&gt;Example&lt;/h2&gt;
&lt;p&gt;This example demonstrates how modules integrate with the component and expression concepts you learned earlier.
The module defines a reusable log filtering component that showcases:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Custom component definition&lt;/strong&gt;: Using &lt;code&gt;declare&lt;/code&gt; to create reusable logic.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Arguments&lt;/strong&gt;: Accepting configuration from component users.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Exports&lt;/strong&gt;: Exposing values for other components to reference.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Internal pipeline&lt;/strong&gt;: Using built-in components within the custom component.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Module definition&lt;/strong&gt; &lt;code&gt;helpers.alloy&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;declare &amp;#34;log_filter&amp;#34; {
  // argument.write_to is a required argument that specifies where filtered
  // log lines are sent.
  //
  // The value of the argument is retrieved in this file with
  // argument.write_to.value.
  argument &amp;#34;write_to&amp;#34; {
    optional = false
  }

  // loki.process.filter is our component which executes the filtering,
  // passing filtered logs to argument.write_to.value.
  loki.process &amp;#34;filter&amp;#34; {
    // Drop all debug- and info-level logs.
    stage.match {
      selector = `{job!=&amp;#34;&amp;#34;} |~ &amp;#34;level=(debug|info)&amp;#34;`
      action   = &amp;#34;drop&amp;#34;
    }

    // Send processed logs to our argument.
    forward_to = argument.write_to.value
  }

  // export.filter_input exports a value to the module consumer.
  export &amp;#34;filter_input&amp;#34; {
    // Expose the receiver of loki.process so the module importer can send
    // logs to our loki.process component.
    value = loki.process.filter.receiver
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Use the module&lt;/strong&gt; &lt;code&gt;main.alloy&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;// Import our helpers.alloy module, exposing its custom components as
// helpers.COMPONENT_NAME.
import.file &amp;#34;helpers&amp;#34; {
  filename = &amp;#34;helpers.alloy&amp;#34;
}

loki.source.file &amp;#34;self&amp;#34; {
  targets = LOG_TARGETS

  // Forward collected logs to the input of our filter.
  forward_to = [helpers.log_filter.default.filter_input]
}

helpers.log_filter &amp;#34;default&amp;#34; {
  // Configure the filter to forward filtered logs to loki.write below.
  write_to = [loki.write.default.receiver]
}

loki.write &amp;#34;default&amp;#34; {
  endpoint {
    url = LOKI_URL
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This example shows how:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Modules encapsulate logic&lt;/strong&gt;: The filtering logic is contained within the module.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Arguments provide flexibility&lt;/strong&gt;: The &lt;code&gt;write_to&lt;/code&gt; argument lets users specify where filtered logs go.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Exports enable connections&lt;/strong&gt;: The &lt;code&gt;filter_input&lt;/code&gt; export allows other components to send data to the filter.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Component references work across modules&lt;/strong&gt;: The main configuration references exports from the imported module using &lt;code&gt;helpers.log_filter.default.filter_input&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;import-modules&#34;&gt;Import modules&lt;/h2&gt;
&lt;p&gt;To use modules in your configuration, you import them using one of the &lt;code&gt;import&lt;/code&gt; configuration blocks.
The component controller processes import statements during configuration loading to make custom components available in the importing module&amp;rsquo;s namespace.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/config-blocks/import.file/&#34;&gt;&lt;code&gt;import.file&lt;/code&gt;&lt;/a&gt;: Imports a module from a file on disk.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/config-blocks/import.git/&#34;&gt;&lt;code&gt;import.git&lt;/code&gt;&lt;/a&gt;: Imports a module from a file in a Git repository.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/config-blocks/import.http/&#34;&gt;&lt;code&gt;import.http&lt;/code&gt;&lt;/a&gt;: Imports a module from an HTTP request response.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/config-blocks/import.string/&#34;&gt;&lt;code&gt;import.string&lt;/code&gt;&lt;/a&gt;: Imports a module from a string.&lt;/li&gt;
&lt;/ol&gt;


&lt;div class=&#34;admonition admonition-warning&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Warning&lt;/p&gt;&lt;p&gt;You can&amp;rsquo;t import a module that contains top-level blocks other than &lt;code&gt;declare&lt;/code&gt; or &lt;code&gt;import&lt;/code&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;You import modules into a &lt;em&gt;namespace&lt;/em&gt;.
This exposes the top-level custom components of the imported module to the importing module.
The label of the import block specifies the namespace of an import.&lt;/p&gt;
&lt;p&gt;For example, if a configuration contains a block called &lt;code&gt;import.file &amp;quot;my_module&amp;quot;&lt;/code&gt;, then custom components defined by that module appear as &lt;code&gt;my_module.CUSTOM_COMPONENT_NAME&lt;/code&gt;.
Namespaces for imports must be unique within a given importing module.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-warning&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Warning&lt;/p&gt;&lt;p&gt;If you use a label for an &lt;code&gt;import&lt;/code&gt; or &lt;code&gt;declare&lt;/code&gt; block that matches a built-in component namespace, such as &lt;code&gt;prometheus&lt;/code&gt; or &lt;code&gt;mimir&lt;/code&gt;, the built-in namespace becomes shadowed and unavailable in your configuration.
For example, if you use the label &lt;code&gt;import.file &amp;quot;mimir&amp;quot;&lt;/code&gt;, you can&amp;rsquo;t use components starting with &lt;code&gt;mimir&lt;/code&gt;, such as &lt;code&gt;mimir.rules.kubernetes&lt;/code&gt;, because the label refers to the imported module.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;security&#34;&gt;Security&lt;/h2&gt;
&lt;p&gt;Since modules can load arbitrary configurations from potentially remote sources, you must carefully consider the security implications.
The component controller executes all module content with the same privileges as the main Alloy process.&lt;/p&gt;
&lt;p&gt;Best practices for secure module usage:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Protect main configuration&lt;/strong&gt;: Ensure attackers can&amp;rsquo;t modify the Alloy configuration files.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Secure remote sources&lt;/strong&gt;: Protect modules fetched from remote locations, such as Git repositories or HTTP servers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Validate module content&lt;/strong&gt;: Review imported modules for malicious or unintended behavior.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use authentication&lt;/strong&gt;: When fetching modules over HTTP or Git, use appropriate authentication mechanisms.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Network security&lt;/strong&gt;: Restrict network access for Alloy processes that load remote modules.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;File permissions&lt;/strong&gt;: Set appropriate file system permissions for module files and directories.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next steps&lt;/h2&gt;
&lt;p&gt;To learn more about modules, explore these resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../components/custom-components/&#34;&gt;Custom components&lt;/a&gt; - Learn how to create reusable components that you can package in modules&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../components/&#34;&gt;Component configuration&lt;/a&gt; - Understand how built-in components work within module contexts&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/config-blocks/&#34;&gt;Import configuration blocks&lt;/a&gt; - Detailed reference for different module import methods&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/cli/run/&#34;&gt;Run command reference&lt;/a&gt; - Module configuration and execution options&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="modules">Modules&lt;/h1>
&lt;p>You learned about components, expressions, and the configuration syntax in the previous sections.
Now you&amp;rsquo;ll learn about modules, the organizational structure that lets you package and reuse Alloy configurations.&lt;/p></description></item><item><title>Clustering</title><link>https://grafana.com/docs/alloy/v1.15/get-started/clustering/</link><pubDate>Mon, 30 Mar 2026 15:47:22 +0000</pubDate><guid>https://grafana.com/docs/alloy/v1.15/get-started/clustering/</guid><content><![CDATA[&lt;h1 id=&#34;clustering&#34;&gt;Clustering&lt;/h1&gt;
&lt;p&gt;You learned about components, expressions, syntax, and modules in the previous sections.
Now you&amp;rsquo;ll learn about clustering, which allows multiple Alloy deployments to work together for distributed data collection.&lt;/p&gt;
&lt;p&gt;Clustering provides workload distribution and high availability.
It enables horizontally scalable deployments with minimal resource and operational overhead.&lt;/p&gt;
&lt;p&gt;Alloy uses an eventually consistent model with a gossip protocol to achieve clustering.
This model assumes all participating Alloy deployments are interchangeable and use identical configurations.
The cluster uses a consistent hashing algorithm to distribute work among nodes.&lt;/p&gt;
&lt;p&gt;A standalone, non-clustered Alloy behaves the same as a single-node cluster.&lt;/p&gt;
&lt;p&gt;You configure clustering by passing &lt;code&gt;--cluster.*&lt;/code&gt; command-line flags to the &lt;a href=&#34;../../reference/cli/run/#clustering&#34;&gt;&lt;code&gt;alloy run&lt;/code&gt;&lt;/a&gt; command.
Cluster-enabled components must explicitly enable clustering through a &lt;code&gt;clustering&lt;/code&gt; block in their configuration.&lt;/p&gt;
&lt;h2 id=&#34;use-cases&#34;&gt;Use cases&lt;/h2&gt;
&lt;p&gt;Clustering serves several purposes in Alloy deployments, with the primary focus being workload distribution and scalability.&lt;/p&gt;
&lt;h3 id=&#34;target-auto-distribution&#34;&gt;Target auto-distribution&lt;/h3&gt;
&lt;p&gt;Target auto-distribution is the most common use case of clustering.
It lets scraping components running on all peers distribute the scrape load among themselves.&lt;/p&gt;
&lt;p&gt;For target auto-distribution to work:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;All Alloy deployments in the same cluster must access the same service discovery APIs.&lt;/li&gt;
&lt;li&gt;All deployments must scrape the same targets.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You must explicitly enable target auto-distribution on components by defining a &lt;code&gt;clustering&lt;/code&gt; block.
This integrates with the component system you learned about in previous sections:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;prometheus.scrape &amp;#34;default&amp;#34; {
    targets = discovery.kubernetes.pods.targets

    clustering {
        enabled = true
    }

    forward_to = [prometheus.remote_write.default.receiver]
}

prometheus.remote_write &amp;#34;default&amp;#34; {
    endpoint {
        url = &amp;#34;https://prometheus.example.com/api/v1/write&amp;#34;
    }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When a cluster detects state changes (when a node joins or leaves), all participating components locally recalculate target ownership using a consistent hashing algorithm.
Components re-balance the targets they&amp;rsquo;re scraping without explicitly communicating ownership over the network.
Each node uses 512 tokens in the hash ring for optimal load distribution.&lt;/p&gt;
&lt;p&gt;Target auto-distribution lets you dynamically scale the number of Alloy deployments to handle workload peaks.
It also provides resiliency because remaining node peers automatically pick up targets if a node leaves the cluster.&lt;/p&gt;
&lt;p&gt;Alloy uses a local consistent hashing algorithm to distribute targets.
When the cluster size changes, this algorithm redistributes only approximately 1/N of the targets, minimizing disruption.&lt;/p&gt;
&lt;p&gt;Refer to the component reference documentation to check if a component supports clustering, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/prometheus/prometheus.scrape/#clustering&#34;&gt;&lt;code&gt;prometheus.scrape&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/pyroscope/pyroscope.scrape/#clustering&#34;&gt;&lt;code&gt;pyroscope.scrape&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/prometheus/prometheus.operator.podmonitors/#clustering&#34;&gt;&lt;code&gt;prometheus.operator.podmonitors&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/prometheus/prometheus.operator.servicemonitors/#clustering&#34;&gt;&lt;code&gt;prometheus.operator.servicemonitors&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;best-practices&#34;&gt;Best practices&lt;/h2&gt;
&lt;p&gt;Follow these guidelines to ensure effective clustering in your Alloy deployments.&lt;/p&gt;
&lt;h3 id=&#34;avoid-issues-with-disproportionately-large-targets&#34;&gt;Avoid issues with disproportionately large targets&lt;/h3&gt;
&lt;p&gt;When your environment has a mix of very large and average-sized targets, avoid running too many cluster instances.
While clustering generally does a good job of sharding targets to achieve balanced workload distribution, significant target size disparity can lead to uneven load distribution.
When you have a few disproportionately large targets among many instances, the nodes assigned these large targets experience much higher load compared to others, for example samples per second for Prometheus metrics, potentially causing uneven load balancing or hitting resource limitations.
In these scenarios, it&amp;rsquo;s often better to scale vertically rather than horizontally to reduce the impact of outlier large targets.
This approach ensures more consistent resource utilization across your deployment and prevents overloading specific instances.&lt;/p&gt;
&lt;h3 id=&#34;use---clusterwait-for-size-but-with-caution&#34;&gt;Use &lt;code&gt;--cluster.wait-for-size&lt;/code&gt;, but with caution&lt;/h3&gt;
&lt;p&gt;When you use clustering in a deployment where a single instance can&amp;rsquo;t handle the entire load, use the &lt;code&gt;--cluster.wait-for-size&lt;/code&gt; flag to ensure a minimum cluster size before accepting traffic.
However, leave a significant safety margin when you configure this value by setting it significantly smaller than your typical expected operational number of instances.
When this condition isn&amp;rsquo;t met, the instances stop processing traffic in cluster-enabled components, so it&amp;rsquo;s important to leave room for any unexpected events.&lt;/p&gt;
&lt;p&gt;For example, if you&amp;rsquo;re using Horizontal Pod Autoscalers (HPA) or PodDisruptionBudgets (PDB) in Kubernetes, set the &lt;code&gt;--cluster.wait-for-size&lt;/code&gt; flag to a value well below what your HPA and PDB minimums allow.
This prevents traffic from stopping when Kubernetes instance counts temporarily drop below these thresholds during normal operations like Pod termination or rolling updates.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s recommended to use the &lt;code&gt;--cluster.wait-timeout&lt;/code&gt; flag to set a reasonable timeout for the waiting period to limit the impact of potential misconfiguration.
You can base the timeout duration on how quickly you expect your orchestration or incident response team to provision the required number of instances.
Be aware that when the timeout passes, the cluster may be too small to handle traffic and can run into further issues.&lt;/p&gt;
&lt;h3 id=&#34;dont-enable-clustering-if-you-dont-need-it&#34;&gt;Don&amp;rsquo;t enable clustering if you don&amp;rsquo;t need it&lt;/h3&gt;
&lt;p&gt;While clustering scales to very large numbers of instances, it introduces additional overhead in the form of logs, metrics, potential alerts, and processing requirements.
If you&amp;rsquo;re not using components that specifically support and benefit from clustering, it&amp;rsquo;s best to not enable clustering at all.
A particularly common mistake is enabling clustering on logs collecting DaemonSets.
Collecting logs from Pods on the mounted node doesn&amp;rsquo;t benefit from having clustering enabled since each instance typically collects logs only from Pods on its own node.
In such cases, enabling clustering only adds unnecessary complexity and resource usage without providing functional benefits.&lt;/p&gt;
&lt;h2 id=&#34;cluster-monitoring-and-troubleshooting&#34;&gt;Cluster monitoring and troubleshooting&lt;/h2&gt;
&lt;p&gt;You can monitor your cluster status using the Alloy UI &lt;a href=&#34;../../troubleshoot/debug/#clustering-page&#34;&gt;clustering page&lt;/a&gt;.
Refer to &lt;a href=&#34;../../troubleshoot/debug/#debug-clustering-issues&#34;&gt;Debug clustering issues&lt;/a&gt; for additional troubleshooting information.&lt;/p&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next steps&lt;/h2&gt;
&lt;p&gt;Now that you understand how clustering works with Alloy components, explore these topics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../../set-up/deploy/&#34;&gt;Deploy Alloy&lt;/a&gt; - Set up clustered deployments in production environments.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../monitor/&#34;&gt;Monitor Alloy&lt;/a&gt; - Learn about monitoring cluster health and performance.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../troubleshoot/debug/#debug-clustering-issues&#34;&gt;Troubleshooting&lt;/a&gt; - Debug clustering issues and interpret cluster metrics.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For detailed configuration:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/cli/run/#clustering&#34;&gt;&lt;code&gt;alloy run&lt;/code&gt; command reference&lt;/a&gt; - Configure clustering using command-line flags.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/&#34;&gt;Component reference&lt;/a&gt; - Explore clustering-enabled components like &lt;code&gt;prometheus.scrape&lt;/code&gt; and &lt;code&gt;pyroscope.scrape&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="clustering">Clustering&lt;/h1>
&lt;p>You learned about components, expressions, syntax, and modules in the previous sections.
Now you&amp;rsquo;ll learn about clustering, which allows multiple Alloy deployments to work together for distributed data collection.&lt;/p></description></item></channel></rss>