<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Go-Guru]]></title><description><![CDATA[Go-Guru]]></description><link>https://go-guru.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Wed, 09 Sep 2026 09:37:47 GMT</lastBuildDate><atom:link href="https://go-guru.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Highlights of the Go 1.25 Release]]></title><description><![CDATA[The new release of the Go language brings several interesting updates. Let’s take a closer look at some of the most notable ones.
Module path
You can now use subdirectories of a repository as module paths.If the module path has a VCS qualifier at the...]]></description><link>https://go-guru.hashnode.dev/highlights-of-the-go-125-release</link><guid isPermaLink="true">https://go-guru.hashnode.dev/highlights-of-the-go-125-release</guid><category><![CDATA[go 1.25]]></category><category><![CDATA[Go Language]]></category><category><![CDATA[Go]]></category><category><![CDATA[programming languages]]></category><dc:creator><![CDATA[Vladimir Aleshin]]></dc:creator><pubDate>Sun, 19 Oct 2025 14:47:52 GMT</pubDate><content:encoded><![CDATA[<p>The new release of the Go language brings several interesting updates. Let’s take a closer look at some of the most notable ones.</p>
<h3 id="heading-module-path">Module path</h3>
<p>You can now use subdirectories of a repository as module paths.<br />If the module path has a VCS qualifier at the end of a path component, the Go command will split the path by that qualifier.<br />The first part is treated as the repository, and the second part as the module’s subdirectory.<br />Example:</p>
<pre><code class="lang-bash">go get example.com/foo.git/bar@v1.1.1
</code></pre>
<p>The Go command downloads the repository <a target="_blank" href="http://example.com/foo"><strong>example.com/foo</strong></a> and takes the module from the <strong>bar</strong> subdirectory.</p>
<p>If a module path doesn’t include a VCS qualifier, Go sends a GET request to the module address with the <code>?go-get=1</code>parameter.<br />In the response, Go expects an HTML document containing a <code>&lt;meta&gt;</code> tag with the <code>go-import</code> attribute.<br />Example:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"go-import"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"company.com/api git https://gitlab.com/company/api"</span>&gt;</span>
</code></pre>
<p>After that, you can use the command:</p>
<pre><code class="lang-bash">go get company.com/api
</code></pre>
<p>to download the module.</p>
<p>This is a good way to keep the module path short and clear.</p>
<h3 id="heading-waitgroup-analyser-for-go-vet">WaitGroup analyser for <code>go vet</code></h3>
<p>If <code>sync.WaitGroup.Add</code> is called in the wrong place, the <code>vet</code> command will report an error.</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">var</span> wg sync.WaitGroup

    <span class="hljs-keyword">go</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> {
        wg.Add(<span class="hljs-number">1</span>) <span class="hljs-comment">// &lt;-- WRONG</span>
        <span class="hljs-keyword">defer</span> wg.Done()
    }()
    wg.Wait()
}
</code></pre>
<pre><code class="lang-bash">go vet
<span class="hljs-comment"># ert</span>
<span class="hljs-comment"># [ert]</span>
./main.go:8:9: WaitGroup.Add called from inside new goroutine
</code></pre>
<h3 id="heading-container-aware-gomaxprocs">Container-aware GOMAXPROCS</h3>
<p>In previous versions, GOMAXPROCS defaulted to the number of logical CPUs — <code>runtime.NumCPU()</code>.</p>
<p>Starting with Go 1.25, this behavior has changed:</p>
<ol>
<li><p>On Linux, the runtime now reads the CPU bandwidth limit from the <strong>cgroups</strong> that contain the process. If the bandwidth limit is lower than the number of available logical CPUs, <code>GOMAXPROCS</code> is set to that lower limit. In Kubernetes, this corresponds to the container’s <strong>CPU limit.</strong></p>
</li>
<li><p>The runtime periodically checks the number of available logical CPUs or cgroup bandwidth limits and updates <code>GOMAXPROCS</code> dynamically if they change.</p>
</li>
<li><p>A manually set <code>GOMAXPROCS</code> (via environment variable or runtime.GOMAXPROCS()) always takes priority and disables automatic updates.</p>
</li>
</ol>
<h3 id="heading-trace-flight-recorder">Trace flight recorder</h3>
<p>Previously, if we wanted to trace the execution of an application, we had to use <code>runtime/trace</code>. However, this approach often caused issues — large trace files, high CPU overhead, and overall performance impact<br />.<br />Now we can use <code>runtime/trace.FlightRecorder</code>, which records traces in an in-memory ring buffer and saves them to disk only when needed. For example, you can capture just the last 5 seconds of execution and write it to a file using <code>io.Writer</code>. FlightRecorder can be configured through the <strong>FlightRecorderConfig</strong> structure.</p>
<p>These are just a few interesting highlights — you can find the full release information on the official website <a target="_blank" href="https://go.dev/doc/go1.25">Go 1.25 Release Notes</a></p>
]]></content:encoded></item></channel></rss>