<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Docker on tsvinc</title>
    <link>https://tsvinc.dev/tags/docker/</link>
    <description>Recent content in Docker on tsvinc</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Tue, 07 Jul 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://tsvinc.dev/tags/docker/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Native Image Grew to 734 MB</title>
      <link>https://tsvinc.dev/posts/five-numbers-18-branches/</link>
      <pubDate>Tue, 07 Jul 2026 00:00:00 +0000</pubDate>
      <guid>https://tsvinc.dev/posts/five-numbers-18-branches/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part 20 of &lt;a href=&#34;https://tsvinc.dev/series/micronaut-256mb/&#34;&gt;the Micronaut native image series&lt;/a&gt;. Field notes from running benchmark scenarios across 18 branches — three frameworks, three runtimes, four memory tiers. No narrative arc. Just five things that surprised me.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;1-native-is-not-automatically-small&#34;&gt;1. Native is not automatically small&lt;/h2&gt;&#xA;&lt;p&gt;The pitch: GraalVM native images are lean. Sub-100 MB footprint. Container-friendly. Cloud-native.&lt;/p&gt;&#xA;&lt;p&gt;The CRUD workload confirms this. Native RSS across all frameworks ranges from 31 to 86 MB. JVM containers running the same code: 351-643 MB. The marketing copy is accurate — for CRUD.&lt;/p&gt;</description>
    </item>
    <item>
      <title>-Xmx Won&#39;t Save Your Native Image</title>
      <link>https://tsvinc.dev/posts/xmx-wont-save-native-image/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>https://tsvinc.dev/posts/xmx-wont-save-native-image/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part 19 of &lt;a href=&#34;https://tsvinc.dev/series/micronaut-256mb/&#34;&gt;the Micronaut native image series&lt;/a&gt;. Follows &lt;a href=&#34;https://tsvinc.dev/posts/counter-reset-benchmark-lied/&#34;&gt;Part 18&lt;/a&gt;, where a reset Prometheus counter made the benchmark lie. Assumes familiarity with GraalVM native image and Docker memory limits.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-confident-wrong-fix&#34;&gt;The Confident Wrong Fix&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# docker-compose.yml — the JVM reflex&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;environment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;JAVA_TOOL_OPTIONS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;-Xmx128m&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Standard. Reliable. Every JVM deployment in every Kubernetes cluster in the world does this. It has never not worked.&lt;/p&gt;&#xA;&lt;p&gt;It is a no-op on a native binary.&lt;/p&gt;&#xA;&lt;p&gt;GraalVM native images are not JVMs. They don&amp;rsquo;t read &lt;code&gt;JAVA_TOOL_OPTIONS&lt;/code&gt;. They don&amp;rsquo;t read &lt;code&gt;-Xmx&lt;/code&gt; from environment variables. &lt;a href=&#34;https://github.com/oracle/graal/issues/4650&#34;&gt;GraalVM issue #4650&lt;/a&gt; requested this capability. &lt;a href=&#34;https://github.com/oracle/graal/issues/9504&#34;&gt;Issue #9504&lt;/a&gt; confirmed it&amp;rsquo;s still not supported. Your heap cap does nothing. No warning. No error. The binary starts, ignores the variable, sizes its heap however it wants.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Loom Carrier on a Reactive Stack: 78 MB for Free</title>
      <link>https://tsvinc.dev/posts/loom-carrier-reactive/</link>
      <pubDate>Wed, 17 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://tsvinc.dev/posts/loom-carrier-reactive/</guid>
      <description>&lt;p&gt;&amp;ldquo;Virtual threads don&amp;rsquo;t help reactive apps.&amp;rdquo; You&amp;rsquo;ve heard this. Probably said it. The reasoning is sound: a fully reactive stack — &lt;code&gt;Mono&lt;/code&gt;/&lt;code&gt;Flux&lt;/code&gt; from HTTP client through R2DBC to Netty — never blocks a platform thread. Virtual threads solve blocking. No blocking, no benefit. QED.&lt;/p&gt;&#xA;&lt;p&gt;We ran the benchmark anyway. The conventional wisdom is correct about throughput and wrong about everything else.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-stack&#34;&gt;The Stack&lt;/h2&gt;&#xA;&lt;p&gt;Space Observatory: Micronaut 5.0.0, Netty, R2DBC PostgreSQL, Reactor Core, Micrometer. Reactive end-to-end — no &lt;code&gt;subscribeOn(Schedulers.boundedElastic())&lt;/code&gt;, no blocking JDBC, no thread-per-request anywhere. GraalVM CE 25, Java 25.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Three Bugs in a Trenchcoat Pretending to Be One Hang</title>
      <link>https://tsvinc.dev/posts/aot-three-bugs-trenchcoat/</link>
      <pubDate>Sun, 07 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://tsvinc.dev/posts/aot-three-bugs-trenchcoat/</guid>
      <description>&lt;p&gt;The CLAUDE.md for this project had a one-liner that persisted for a week: &amp;ldquo;Micronaut AOT hangs — keep disabled.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;Every developer who touched the project read that line, nodded, and moved on. AOT disabled. Property set to false. Life continued. Nobody questioned it because it was technically true — AOT &lt;em&gt;had&lt;/em&gt; hung — and the project worked without it.&lt;/p&gt;&#xA;&lt;p&gt;Then the benchmark numbers arrived. Non-heap at 119 MB. Container limit at 256 MB. JVM OOM-killing at 150 concurrent users. And a footnote in the Micronaut AOT docs: &amp;ldquo;build-time service loading reduces runtime metaspace by eliminating classpath scanning.&amp;rdquo;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Your JVM Reports 151 MB. Your Container Uses 248.</title>
      <link>https://tsvinc.dev/posts/jvm-memory-anatomy/</link>
      <pubDate>Fri, 05 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://tsvinc.dev/posts/jvm-memory-anatomy/</guid>
      <description>&lt;p&gt;151 MB. That&amp;rsquo;s what micrometer-prometheus reports for the JVM at 256 MB after serving 1.66 million requests. Heap 35 MB, metaspace 72 MB, compressed class space 13 MB, code cache 16 MB, direct buffers 0.75 MB. Add it up. 137 MB. Rounded generously: 151 MB with some measurement timing jitter.&lt;/p&gt;&#xA;&lt;p&gt;Docker stats says 244.2 MiB. Out of 256 MiB. 95.38%.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-visible-budget&#34;&gt;The Visible Budget&lt;/h2&gt;&#xA;&lt;p&gt;After 1.66 million requests, Serial GC, &lt;code&gt;-Xms64m -Xmx64m -Xss256k&lt;/code&gt;, here&amp;rsquo;s what the JVM admits to owning:&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
