<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hermosilla</title>
    <description>The latest articles on DEV Community by Hermosilla (@rtxhermosilla).</description>
    <link>https://dev.to/rtxhermosilla</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4228613%2F66015e08-6f98-4a13-bfe7-237dc997a809.jpeg</url>
      <title>DEV Community: Hermosilla</title>
      <link>https://dev.to/rtxhermosilla</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rtxhermosilla"/>
    <language>en</language>
    <item>
      <title>Rust Observability in 2026: OTLP Logs and Metrics Are Stable—What About Traces?</title>
      <dc:creator>Hermosilla</dc:creator>
      <pubDate>Thu, 05 Nov 2026 13:37:39 +0000</pubDate>
      <link>https://dev.to/rtxhermosilla/rust-observability-in-2026-otlp-logs-and-metrics-are-stable-what-about-traces-4774</link>
      <guid>https://dev.to/rtxhermosilla/rust-observability-in-2026-otlp-logs-and-metrics-are-stable-what-about-traces-4774</guid>
      <description>&lt;p&gt;Rust has a strong observability ecosystem built around &lt;a href="https://crates.io/crates/tracing" rel="noopener noreferrer"&gt;&lt;code&gt;tracing&lt;/code&gt;&lt;/a&gt;, but getting its events into an observability backend involves a few distinct pieces: spans, log records, metrics, and exporters.&lt;/p&gt;

&lt;p&gt;There is a useful milestone in the current OpenTelemetry Rust release that makes this setup more interesting: &lt;strong&gt;as of OpenTelemetry Rust 0.33.1, the OTLP exporters for logs and metrics are stable, while the OTLP exporter for traces remains in beta.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That distinction is easy to miss if we just say “OpenTelemetry is stable.” Let’s look at what changed and how it maps to a real Rust service.&lt;/p&gt;

&lt;h2&gt;
  
  
  What became stable?
&lt;/h2&gt;

&lt;p&gt;The OpenTelemetry Rust 0.33.1 release, published on October 8, 2026, declared the OTLP exporters for &lt;strong&gt;Logs&lt;/strong&gt; and &lt;strong&gt;Metrics&lt;/strong&gt; stable after a release-candidate period. The &lt;strong&gt;Traces&lt;/strong&gt; exporter remains beta.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;th&gt;OTLP exporter status in 0.33.1&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Logs&lt;/td&gt;
&lt;td&gt;Stable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Metrics&lt;/td&gt;
&lt;td&gt;Stable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Traces&lt;/td&gt;
&lt;td&gt;Beta&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is specifically about the OTLP exporters in the Rust implementation—not a blanket statement that every OpenTelemetry crate or API has the same stability guarantee. The release notes also describe the Logs and Metrics APIs and SDK as stable, while Distributed Tracing remains pre-stable.&lt;/p&gt;

&lt;p&gt;There is another useful reliability improvement: starting in 0.33.0, OTLP retries are enabled by default for HTTP and gRPC exporters. The default policy uses exponential backoff and jitter, with up to three retries after the first attempt. In other words, a temporary collector hiccup no longer necessarily means an export is immediately lost.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;tracing&lt;/code&gt; events can become either logs or trace data
&lt;/h2&gt;

&lt;p&gt;One source of confusion is that two similarly named integrations do different jobs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://crates.io/crates/tracing-opentelemetry" rel="noopener noreferrer"&gt;&lt;code&gt;tracing-opentelemetry&lt;/code&gt;&lt;/a&gt; connects Rust &lt;code&gt;tracing&lt;/code&gt; spans and events to OpenTelemetry &lt;strong&gt;traces&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://crates.io/crates/opentelemetry-appender-tracing" rel="noopener noreferrer"&gt;&lt;code&gt;opentelemetry-appender-tracing&lt;/code&gt;&lt;/a&gt; forwards &lt;code&gt;tracing&lt;/code&gt; events to the OpenTelemetry &lt;strong&gt;Logs&lt;/strong&gt; pipeline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both can be installed as layers on a &lt;code&gt;tracing_subscriber&lt;/code&gt;. A log record and a span event are related, but they are not the same telemetry signal; the bridge you choose determines where the event goes.&lt;/p&gt;

&lt;p&gt;In our service setup, the key pieces look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;trace_layer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;tracing_opentelemetry&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;layer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.with_tracer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;log_layer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;OpenTelemetryTracingBridge&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;logger_provider&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The trace provider and logger provider each receive exporters. The metrics provider is separate again: it creates instruments and collects measurements on its configured interval. All three can share the same OpenTelemetry &lt;code&gt;Resource&lt;/code&gt;, so telemetry is attributed to the same service name and version.&lt;/p&gt;

&lt;h2&gt;
  
  
  A small configuration example
&lt;/h2&gt;

&lt;p&gt;The AICC crate wraps provider and subscriber setup behind a builder-style API. With a local OpenTelemetry Collector listening on gRPC port &lt;code&gt;4317&lt;/code&gt;, initialization is just a few lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;aicc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;o11y&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;prelude&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;tracing&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;TracingOptions&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;.with_service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"orders-api"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"1.2.0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.with_otlp_exporter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;OtlpExporterOptions&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://localhost:4317"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_guard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;init_tracing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;info!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Order accepted"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exporter options enable all three signals by default. In the implementation, separate builders create the OTLP span, metric, and log exporters, and the resulting providers are attached to the subscriber or registered as global providers where needed.&lt;/p&gt;

&lt;p&gt;The returned guard matters. Keep it alive for the lifetime of the application: when it is dropped, it shuts down the providers and flushes pending telemetry. If you create a provider manually, make sure your shutdown path does the equivalent.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical detail: exporters can produce telemetry too
&lt;/h2&gt;

&lt;p&gt;The OTLP exporter and its transport stack can emit &lt;code&gt;tracing&lt;/code&gt; events of their own. If those events are sent through the log bridge, exporting a log could produce another log, which could trigger another export, and so on.&lt;/p&gt;

&lt;p&gt;The service code avoids that feedback loop by filtering infrastructure targets out of the OpenTelemetry log layer. It still allows warnings and errors from that infrastructure to appear in the console layer, which is useful when the collector is unavailable.&lt;/p&gt;

&lt;p&gt;This is a small implementation detail, but it is exactly the sort of thing that turns a “hello, telemetry” demo into a setup you can operate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Metrics are collected when requested
&lt;/h2&gt;

&lt;p&gt;OpenTelemetry observable instruments use callbacks that run during collection. They are a good fit for values such as current CPU or memory usage: the application registers how to read the value, and the SDK asks for it when a metrics reader collects data.&lt;/p&gt;

&lt;p&gt;In this project, the server registers observable system metrics using &lt;code&gt;sysinfo&lt;/code&gt;. The callbacks refresh and read the relevant values; there is no separate polling task that wakes up just to update gauges. If you adapt the example for your own service, you can add application counters or histograms alongside those system metrics.&lt;/p&gt;

&lt;p&gt;One caveat for a demo: the OTLP example initializes all three pipelines and emits spans and log records, but it does not record a custom metric. To demonstrate all three signals end to end, add a metric instrument or run the server path that registers the system metrics.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should you take away?
&lt;/h2&gt;

&lt;p&gt;OpenTelemetry Rust 0.33.1 is a meaningful point to revisit your observability setup:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Logs and metrics have stable OTLP exporters.&lt;/strong&gt; That is useful if you want to standardize your output format and backend integration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tracing is still beta.&lt;/strong&gt; Treat its API stability separately rather than assuming every signal has the same guarantee.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retries are now on by default for OTLP exporters.&lt;/strong&gt; That improves resilience to transient failures, but it is still worth monitoring exporter errors and having a clear shutdown path.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;tracing&lt;/code&gt; can feed more than one signal.&lt;/strong&gt; Use the trace bridge for spans and the appender for OpenTelemetry log records, and filter exporter-generated events to prevent feedback loops.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The interesting question is no longer just “Can Rust send telemetry to OpenTelemetry?” It can. The more useful question is: &lt;strong&gt;which signals are stable in the versions you deploy, and what does your application do when the collector is slow or unavailable?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/open-telemetry/opentelemetry-rust/blob/opentelemetry-0.33.0/docs/release_0.33.md" rel="noopener noreferrer"&gt;OpenTelemetry Rust 0.33 release notes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/open-telemetry/opentelemetry-rust/blob/main/opentelemetry-otlp/CHANGELOG.md" rel="noopener noreferrer"&gt;&lt;code&gt;opentelemetry-otlp&lt;/code&gt; changelog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.rs/opentelemetry-otlp/0.33.1/opentelemetry_otlp/" rel="noopener noreferrer"&gt;&lt;code&gt;opentelemetry-otlp&lt;/code&gt; 0.33.1 documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.rs/opentelemetry-appender-tracing/0.33.1/opentelemetry_appender_tracing/" rel="noopener noreferrer"&gt;&lt;code&gt;opentelemetry-appender-tracing&lt;/code&gt; documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>opentelemetry</category>
      <category>observability</category>
      <category>devops</category>
    </item>
    <item>
      <title>What Cargo Generates When You Build a Small Rust Project</title>
      <dc:creator>Hermosilla</dc:creator>
      <pubDate>Thu, 05 Nov 2026 13:15:05 +0000</pubDate>
      <link>https://dev.to/rtxhermosilla/what-cargo-generates-when-you-build-a-small-rust-project-3706</link>
      <guid>https://dev.to/rtxhermosilla/what-cargo-generates-when-you-build-a-small-rust-project-3706</guid>
      <description>&lt;p&gt;When I first started using Rust, I ran &lt;code&gt;cargo build&lt;/code&gt;, saw an executable appear in &lt;code&gt;target/&lt;/code&gt;, and moved on. But Cargo creates more than just a binary: it also keeps metadata and intermediate artifacts that help it decide what needs to be rebuilt.&lt;/p&gt;

&lt;p&gt;Let's create a tiny project, inspect its build output, and compare a clean build with a repeat build.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Create a project
&lt;/h2&gt;

&lt;p&gt;You'll need Rust and Cargo installed. Check with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rustc &lt;span class="nt"&gt;--version&lt;/span&gt;
cargo &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a binary project and move into its directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo new cargo-lab
&lt;span class="nb"&gt;cd &lt;/span&gt;cargo-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cargo creates a small project structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo-lab/
├── Cargo.toml
└── src/
    └── main.rs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the contents of &lt;code&gt;src/main.rs&lt;/code&gt; with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{message}, Cargo!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Build the project
&lt;/h2&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo build &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-v&lt;/code&gt; (verbose) option shows more detail, including compiler commands when Cargo runs them. The first build may also create a &lt;code&gt;Cargo.lock&lt;/code&gt; file and a &lt;code&gt;target/&lt;/code&gt; directory. The exact output depends on your operating system and Rust toolchain, but the project will look roughly like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo-lab/
├── Cargo.lock
├── Cargo.toml
├── src/
│   └── main.rs
└── target/
    └── debug/
        └── cargo-lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The executable is at &lt;code&gt;target/debug/cargo-lab&lt;/code&gt; (on Windows, it has an &lt;code&gt;.exe&lt;/code&gt; extension). You can build and run the program with one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Look inside &lt;code&gt;target/debug&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;List some of the generated files with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find target/debug &lt;span class="nt"&gt;-maxdepth&lt;/span&gt; 2 &lt;span class="nt"&gt;-type&lt;/span&gt; f
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact contents vary by platform, toolchain, and project. You may see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The executable&lt;/strong&gt;, such as &lt;code&gt;target/debug/cargo-lab&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;deps/&lt;/code&gt;&lt;/strong&gt;, which can contain compiled dependencies and other build artifacts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;.fingerprint/&lt;/code&gt;&lt;/strong&gt;, with metadata Cargo uses to determine whether a package needs rebuilding.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;incremental/&lt;/code&gt;&lt;/strong&gt;, when incremental compilation is enabled for the build.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;build/&lt;/code&gt;&lt;/strong&gt;, when a dependency or package uses a build script.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not every project has every directory. This example has no third-party dependencies, so its output is relatively small. Rust's standard library is generally supplied by the installed toolchain; Cargo does not rebuild the standard library from source for every ordinary project build.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Why is the second build usually faster?
&lt;/h2&gt;

&lt;p&gt;Without changing any files, run the build again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo build &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cargo will usually report that the package is fresh instead of compiling it again. It tracks the inputs and previous build results so it can skip work when nothing relevant has changed.&lt;/p&gt;

&lt;p&gt;Now change the message in &lt;code&gt;src/main.rs&lt;/code&gt; and build again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hello from Rust"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{message}, Cargo!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo build &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cargo needs to recompile the changed program. In a project with dependencies, changing your own source does not necessarily mean that every dependency must be rebuilt.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Measure it on your machine
&lt;/h2&gt;

&lt;p&gt;Build times depend on your machine, Rust version, and previous build artifacts. For a simple comparison, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo clean
&lt;span class="nb"&gt;time &lt;/span&gt;cargo build
&lt;span class="nb"&gt;time &lt;/span&gt;cargo build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;cargo clean&lt;/code&gt; removes generated build artifacts from &lt;code&gt;target/&lt;/code&gt;; it does not delete your source files. The first timing is for a clean build. The second is for a build with no source changes.&lt;/p&gt;

&lt;p&gt;Record your own results:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Run&lt;/th&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;First build&lt;/td&gt;
&lt;td&gt;cargo build  0.17s user 0.12s system 49% cpu 0.581 total&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build with no changes&lt;/td&gt;
&lt;td&gt;cargo build  0.02s user 0.02s system 67% cpu 0.049 total&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Don't compare these numbers directly with someone else's machine. The useful comparison is between the two runs in the same environment.&lt;/p&gt;

&lt;p&gt;You can also ask Cargo for a visual report of build timings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo build &lt;span class="nt"&gt;--timings&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cargo writes an HTML report under &lt;code&gt;target/cargo-timings/&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. What changes with &lt;code&gt;--release&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;Try a release build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo build &lt;span class="nt"&gt;--release&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Its output goes into &lt;code&gt;target/release/&lt;/code&gt;, separate from &lt;code&gt;target/debug/&lt;/code&gt;. Cargo uses different build profiles for development and release builds. The release profile applies optimizations, which can make compilation take longer while producing a program intended for distribution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Cargo.toml&lt;/code&gt; describes the package and its dependencies; &lt;code&gt;Cargo.lock&lt;/code&gt; records the resolved dependency versions.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;target/&lt;/code&gt; contains generated outputs: executables, intermediate artifacts, and metadata.&lt;/li&gt;
&lt;li&gt;Cargo checks whether previous outputs can be reused, so a build with no changes usually does much less work.&lt;/li&gt;
&lt;li&gt;Debug and release builds use separate output directories and profiles.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You generally don't need to commit &lt;code&gt;target/&lt;/code&gt; to Git because Cargo can regenerate it. Projects created with &lt;code&gt;cargo new&lt;/code&gt; normally include it in &lt;code&gt;.gitignore&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your turn:&lt;/strong&gt; How long does a clean build take on your machine, and how long does the second build take? What does &lt;code&gt;cargo build -v&lt;/code&gt; report after you change only &lt;code&gt;main.rs&lt;/code&gt;?&lt;/p&gt;

</description>
      <category>rust</category>
      <category>beginners</category>
      <category>cargo</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
