<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>R2dbc on tsvinc</title>
    <link>https://tsvinc.dev/tags/r2dbc/</link>
    <description>Recent content in R2dbc 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/r2dbc/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>2492, 2495, 2508</title>
      <link>https://tsvinc.dev/posts/benchmark-measuring-orm/</link>
      <pubDate>Tue, 07 Jul 2026 00:00:00 +0000</pubDate>
      <guid>https://tsvinc.dev/posts/benchmark-measuring-orm/</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/eight-connections-zero-available/&#34;&gt;Part 18&lt;/a&gt;, which chased a connection pool cancellation leak. Assumes familiarity with JDBC, R2DBC, and JPA/Hibernate.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-table-that-ended-the-argument&#34;&gt;The Table That Ended the Argument&lt;/h2&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Workload&lt;/th&gt;&#xA;          &lt;th&gt;Framework&lt;/th&gt;&#xA;          &lt;th&gt;rps&lt;/th&gt;&#xA;          &lt;th&gt;p95&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;jdbc-synth&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Quarkus&lt;/td&gt;&#xA;          &lt;td&gt;2508.4&lt;/td&gt;&#xA;          &lt;td&gt;1.2 ms&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;jdbc-synth&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Micronaut&lt;/td&gt;&#xA;          &lt;td&gt;2495.0&lt;/td&gt;&#xA;          &lt;td&gt;1.8 ms&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;jdbc-synth&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Spring Boot&lt;/td&gt;&#xA;          &lt;td&gt;2491.8&lt;/td&gt;&#xA;          &lt;td&gt;1.6 ms&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;r2dbc-synth&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Quarkus&lt;/td&gt;&#xA;          &lt;td&gt;2501.2&lt;/td&gt;&#xA;          &lt;td&gt;1.4 ms&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;r2dbc-synth&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Micronaut&lt;/td&gt;&#xA;          &lt;td&gt;2480.2&lt;/td&gt;&#xA;          &lt;td&gt;2.2 ms&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;r2dbc-synth&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Spring Boot&lt;/td&gt;&#xA;          &lt;td&gt;2478.7&lt;/td&gt;&#xA;          &lt;td&gt;2.3 ms&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;Native images at 256 MB. Same k6 load. Same Postgres. Zero errors across the board.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Eight Connections, Zero Available</title>
      <link>https://tsvinc.dev/posts/eight-connections-zero-available/</link>
      <pubDate>Tue, 07 Jul 2026 00:00:00 +0000</pubDate>
      <guid>https://tsvinc.dev/posts/eight-connections-zero-available/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part 18 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/28-apis-same-throughput/&#34;&gt;Part 17&lt;/a&gt;, which found that reactive and imperative produced identical throughput on the 28-API workload. Assumes familiarity with R2DBC and Project Reactor.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;608-and-599&#34;&gt;60.8 and 59.9&lt;/h2&gt;&#xA;&lt;p&gt;Two frameworks. Different HTTP servers, different dependency trees, different teams maintaining them. Under load, both reactive stacks land at almost the same throughput:&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Framework&lt;/th&gt;&#xA;          &lt;th&gt;Model&lt;/th&gt;&#xA;          &lt;th&gt;Runtime&lt;/th&gt;&#xA;          &lt;th&gt;Mem&lt;/th&gt;&#xA;          &lt;th&gt;rps&lt;/th&gt;&#xA;          &lt;th&gt;p95&lt;/th&gt;&#xA;          &lt;th&gt;k6 errors&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Micronaut&lt;/td&gt;&#xA;          &lt;td&gt;Reactive&lt;/td&gt;&#xA;          &lt;td&gt;Native&lt;/td&gt;&#xA;          &lt;td&gt;128 MB&lt;/td&gt;&#xA;          &lt;td&gt;60.8&lt;/td&gt;&#xA;          &lt;td&gt;15000.6 ms&lt;/td&gt;&#xA;          &lt;td&gt;14.1%&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Spring Boot&lt;/td&gt;&#xA;          &lt;td&gt;Reactive&lt;/td&gt;&#xA;          &lt;td&gt;Native&lt;/td&gt;&#xA;          &lt;td&gt;128 MB&lt;/td&gt;&#xA;          &lt;td&gt;59.9&lt;/td&gt;&#xA;          &lt;td&gt;13548.7 ms&lt;/td&gt;&#xA;          &lt;td&gt;2.0%&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Micronaut&lt;/td&gt;&#xA;          &lt;td&gt;Imperative&lt;/td&gt;&#xA;          &lt;td&gt;Native&lt;/td&gt;&#xA;          &lt;td&gt;256 MB&lt;/td&gt;&#xA;          &lt;td&gt;251.9&lt;/td&gt;&#xA;          &lt;td&gt;2554.8 ms&lt;/td&gt;&#xA;          &lt;td&gt;0%&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Spring Boot&lt;/td&gt;&#xA;          &lt;td&gt;Imperative&lt;/td&gt;&#xA;          &lt;td&gt;Native&lt;/td&gt;&#xA;          &lt;td&gt;256 MB&lt;/td&gt;&#xA;          &lt;td&gt;220.6&lt;/td&gt;&#xA;          &lt;td&gt;2588.9 ms&lt;/td&gt;&#xA;          &lt;td&gt;0%&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Quarkus&lt;/td&gt;&#xA;          &lt;td&gt;Reactive&lt;/td&gt;&#xA;          &lt;td&gt;Native&lt;/td&gt;&#xA;          &lt;td&gt;256 MB&lt;/td&gt;&#xA;          &lt;td&gt;258.7&lt;/td&gt;&#xA;          &lt;td&gt;—&lt;/td&gt;&#xA;          &lt;td&gt;0%&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;Imperative hits 220–252. Quarkus reactive hits 259. Micronaut and Spring Boot reactive: 60.&lt;/p&gt;</description>
    </item>
    <item>
      <title>265 req/s on All Three Runtimes (Until You Add a Memory Limit)</title>
      <link>https://tsvinc.dev/posts/seven-scenarios-one-table/</link>
      <pubDate>Sat, 27 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://tsvinc.dev/posts/seven-scenarios-one-table/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part 15 of &lt;a href=&#34;https://tsvinc.dev/series/micronaut-256mb/&#34;&gt;the Micronaut native image series&lt;/a&gt;. Assumes familiarity with reactive Java (Mono/Flux) and container memory limits.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-draw&#34;&gt;The Draw&lt;/h2&gt;&#xA;&lt;p&gt;Native image, JVM, and virtual threads walk into a benchmark. Same reactive Micronaut service. Same k6 load profile. Same PostgreSQL. Same mock APIs with realistic latency jitter.&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Runtime&lt;/th&gt;&#xA;          &lt;th&gt;Req/s&lt;/th&gt;&#xA;          &lt;th&gt;Errors&lt;/th&gt;&#xA;          &lt;th&gt;RSS (avg)&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Native (unlimited)&lt;/td&gt;&#xA;          &lt;td&gt;264&lt;/td&gt;&#xA;          &lt;td&gt;1.0%&lt;/td&gt;&#xA;          &lt;td&gt;273 MB&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;JVM (unlimited)&lt;/td&gt;&#xA;          &lt;td&gt;266&lt;/td&gt;&#xA;          &lt;td&gt;1.0%&lt;/td&gt;&#xA;          &lt;td&gt;551 MB&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Virtual threads (unlimited)&lt;/td&gt;&#xA;          &lt;td&gt;265&lt;/td&gt;&#xA;          &lt;td&gt;1.0%&lt;/td&gt;&#xA;          &lt;td&gt;543 MB&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;265 req/s. All three. The error rates match the mock server&amp;rsquo;s configured failure rate — the application itself isn&amp;rsquo;t failing. Reactive code runs identically on native image, HotSpot, and loom-carrier Netty.&lt;/p&gt;</description>
    </item>
    <item>
      <title>flatMap&#39;s Second Argument Saved 1.7 Million Requests</title>
      <link>https://tsvinc.dev/posts/flatmap-backpressure/</link>
      <pubDate>Mon, 15 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://tsvinc.dev/posts/flatmap-backpressure/</guid>
      <description>&lt;p&gt;Midway through a code review of the reactive pipeline, staring at this line in &lt;code&gt;NeoService.java&lt;/code&gt;:&lt;/p&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-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;flatMap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;neo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;saveAsteroidWithApproaches&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sessionId&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;n&#34;&gt;neo&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s &lt;code&gt;Flux.flatMap()&lt;/code&gt; with one argument. The function. No concurrency limit. Reactor&amp;rsquo;s default: 256 concurrent inner subscriptions.&lt;/p&gt;&#xA;&lt;p&gt;The R2DBC connection pool has 20 connections. Netty has 4 worker threads. &lt;code&gt;flatMap&lt;/code&gt; will cheerfully create 256 concurrent database save operations on 20 connections and 4 threads, queuing 236 of them in memory. Every one holds a &lt;code&gt;NeoAsteroidRecord&lt;/code&gt; entity, a &lt;code&gt;NeoCloseApproach&lt;/code&gt; list, and whatever intermediate state Reactor needs for the inner publisher chain.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Seven Fixes, Zero Errors</title>
      <link>https://tsvinc.dev/posts/seven-fixes-zero-errors/</link>
      <pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://tsvinc.dev/posts/seven-fixes-zero-errors/</guid>
      <description>&lt;p&gt;The fix for &amp;ldquo;JVM dies at 256 MB under load&amp;rdquo; was not a JVM flag.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://tsvinc.dev/posts/every-gc-failed-256mb/&#34;&gt;Part 4&lt;/a&gt; ended with Serial GC — the only GC that fits in 256 MB — serving 4,550 requests before the OOM killer showed up. 81% error rate. Same flags, same container, same load profile. Seven code changes later: 1,740,000 requests. Zero errors.&lt;/p&gt;&#xA;&lt;p&gt;No GC tuning. No new JVM flags at all. The problem was never the runtime. It was the code asking the runtime to hold things it didn&amp;rsquo;t need to hold.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Micronaut 5 Native Image: 14 Entries vs 1,913</title>
      <link>https://tsvinc.dev/posts/micronaut-5-native-image/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>https://tsvinc.dev/posts/micronaut-5-native-image/</guid>
      <description>&lt;p&gt;Micronaut 5.0.0 dropped on May 20, 2026. The &lt;a href=&#34;https://micronaut.io/2026/05/20/micronaut-framework-5-0-0-released/&#34;&gt;launch blog post&lt;/a&gt; promises first-class GraalVM native image support. The documentation is correct. It is also incomplete in ways that cost hours.&lt;/p&gt;&#xA;&lt;p&gt;This is what building a non-trivial native image app looks like on day one: 4 HTTP clients hitting real APIs, reactive R2DBC pipeline into PostgreSQL, Liquibase migrations, &lt;code&gt;@Scheduled&lt;/code&gt; cron jobs, Swagger UI. Everything that should Just Work and mostly does — except when it doesn&amp;rsquo;t, and the failure modes are silent.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
