<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Case Studies on JVQ.net</title>
    <link>https://jvq.net/tags/case-studies/</link>
    <description>Recent content in Case Studies on JVQ.net</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Sat, 31 Oct 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://jvq.net/tags/case-studies/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>jvq Replays 26 of Its Own CI Runs and Blocks a Windows Test Bug Four Pushes in a Row</title>
      <link>https://jvq.net/jvq-replays-26-of-its-own-ci-runs-and-blocks-a-windows-test-bug-four-pushes-in-a-row/</link>
      <pubDate>Sat, 31 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://jvq.net/jvq-replays-26-of-its-own-ci-runs-and-blocks-a-windows-test-bug-four-pushes-in-a-row/</guid>
      <description>&lt;p&gt;The fastest way to find out what a flaky test gate does with real failures is to give it some. jvq has its own CI history on GitHub: 26 pushes to main between October 18 and October 31, 2026, each tested on Linux, macOS and Windows, with a second run under the race detector on Linux. Eight of those 26 runs went red.&lt;/p&gt;&#xA;&lt;p&gt;So we fed that history to &lt;code&gt;jvq flaky&lt;/code&gt; 0.7.0, run by run, in the order it happened, with each run&amp;rsquo;s real commit. One history per platform and test step, as the reference asks. A test that fails on Windows and passes on Linux has a Windows problem, and mixing the two would hide it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Crashed Writer Left Three Broken Lines in a 1 GiB Log and jq Stopped at the First</title>
      <link>https://jvq.net/a-crashed-writer-left-three-broken-lines-in-a-1-gib-log-and-jq-stopped-at-the-first/</link>
      <pubDate>Mon, 19 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://jvq.net/a-crashed-writer-left-three-broken-lines-in-a-1-gib-log-and-jq-stopped-at-the-first/</guid>
      <description>&lt;p&gt;Logs written by real services aren&amp;rsquo;t always valid JSON Lines. A process killed mid-write leaves half a line. The restarted process appends its first event straight after it, on the same line. Disk-full conditions, log shippers that split long lines and two writers sharing one file all do something similar. The file is 99.9999% fine and has a few lines that no parser will accept.&lt;/p&gt;&#xA;&lt;p&gt;jq treats the input as one stream of JSON, so the first bad line ends the run. This worked example shows what that looks like and what jvqq does instead. We took 1 GiB of generated logs, 3,073,492 lines, and cut three lines in half, each followed by the next line on the same line, the way a crashed writer leaves them. In the broken file they&amp;rsquo;re lines 812,345, 1,604,990 and 2,949,998. The commands below ran with jq 1.7.1 and jvqq 0.1.0 on a two-core cloud VM.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How jvqq Traced a 12-Minute Payments Outage Through 3 Million Log Lines</title>
      <link>https://jvq.net/how-jvqq-traced-a-12-minute-payments-outage-through-3-million-log-lines/</link>
      <pubDate>Mon, 19 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://jvq.net/how-jvqq-traced-a-12-minute-payments-outage-through-3-million-log-lines/</guid>
      <description>&lt;p&gt;The alert says checkout is slow. You have the last six hours of application logs as one JSON Lines file, 1 GiB and 3,073,492 lines, and a handful of questions to answer before anyone can fix anything. Which service? Since when? Which endpoint? Each question is a jq filter, and with jq the first one alone took half a minute.&lt;/p&gt;&#xA;&lt;p&gt;This is a worked example. The log is generated by jvqq&amp;rsquo;s benchmark generator, and we planted an incident in it: from 03:10 to 03:22, about 60% of the billing service&amp;rsquo;s payment requests fail with 503 after 2 to 4 seconds. Everything else in the file is ordinary traffic, with its usual background of errors. The commands and output below are real, run with jvqq 0.1.0 and jq 1.7.1 on a two-core cloud VM.&lt;/p&gt;</description>
    </item>
    <item>
      <title>jvq Blocks a Go Logging Change That Added Two Allocations to Every Request</title>
      <link>https://jvq.net/jvq-blocks-a-go-logging-change-that-added-two-allocations-to-every-request/</link>
      <pubDate>Mon, 19 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://jvq.net/jvq-blocks-a-go-logging-change-that-added-two-allocations-to-every-request/</guid>
      <description>&lt;p&gt;An access logger writes one JSON line per request. In Go, the usual way to make that cheap is to append into a buffer the caller owns: no &lt;code&gt;fmt&lt;/code&gt;, no &lt;code&gt;encoding/json&lt;/code&gt;, no strings built along the way. Done right, the benchmark says 0 allocs/op, and the garbage collector never hears about the logger at all.&lt;/p&gt;&#xA;&lt;p&gt;That property is easy to lose and hard to notice. Time per call wanders by several percent from run to run on a CI machine. An allocation count doesn&amp;rsquo;t wander. That&amp;rsquo;s why jvq compares allocations exactly, and why their budget can be an amount, here 0, instead of a percentage. This worked example is a small Go package set up to show it, with two real commits run through jvq 0.5.0 on a two-core cloud VM.&lt;/p&gt;</description>
    </item>
    <item>
      <title>jvq Catches a Python Cleanup That Made URL Parsing Nearly Five Times Slower</title>
      <link>https://jvq.net/jvq-catches-a-python-cleanup-that-made-url-parsing-nearly-five-times-slower/</link>
      <pubDate>Mon, 19 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://jvq.net/jvq-catches-a-python-cleanup-that-made-url-parsing-nearly-five-times-slower/</guid>
      <description>&lt;p&gt;A log pipeline pulls query parameters out of request paths, millions of times a day. The function that does it is eight lines of hand-written splitting. It&amp;rsquo;s fast, and it has a bug everyone has learned to live with: &lt;code&gt;%20&lt;/code&gt; and &lt;code&gt;+&lt;/code&gt; come through undecoded.&lt;/p&gt;&#xA;&lt;p&gt;So someone opens a pull request that fixes it the proper way, with the standard library. Two lines replace eight. The review is easy to approve. This is a worked example we set up to show what jvq does with a change like that: a small repository with a pytest-benchmark suite, four real commits, and jvq 0.5.0 run on each one on a two-core cloud VM.&lt;/p&gt;</description>
    </item>
    <item>
      <title>jvq Flags an Update Check That Made a Go Command-Line Tool Nearly Four Times Bigger</title>
      <link>https://jvq.net/jvq-flags-an-update-check-that-made-a-go-command-line-tool-nearly-four-times-bigger/</link>
      <pubDate>Mon, 19 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://jvq.net/jvq-flags-an-update-check-that-made-a-go-command-line-tool-nearly-four-times-bigger/</guid>
      <description>&lt;p&gt;Some tools are judged by their size. A small binary that gets copied onto every build agent, baked into container images, or downloaded at the start of each CI job pays for every megabyte many times a day. Nobody looks at the size in review, because the diff doesn&amp;rsquo;t show it.&lt;/p&gt;&#xA;&lt;p&gt;jvq can gate the size of files your build makes, next to the timings. This worked example is a small Go command-line tool, &lt;code&gt;lvl&lt;/code&gt;, that counts log levels in JSON Lines files. Two real commits were run through jvq 0.5.0 on a two-core cloud VM.&lt;/p&gt;</description>
    </item>
    <item>
      <title>jvqq Reads a Week of Gzipped Logs Faster Than zcat Can Unzip Them</title>
      <link>https://jvq.net/jvqq-reads-a-week-of-gzipped-logs-faster-than-zcat-can-unzip-them/</link>
      <pubDate>Mon, 19 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://jvq.net/jvqq-reads-a-week-of-gzipped-logs-faster-than-zcat-can-unzip-them/</guid>
      <description>&lt;p&gt;Most log files older than a day are compressed. Logrotate gzips them, object storage keeps them as &lt;code&gt;.gz&lt;/code&gt;, and the habit for querying them is a pipe: &lt;code&gt;zcat app-*.jsonl.gz | jq ...&lt;/code&gt;. It works, and it&amp;rsquo;s slow twice over. gzip unpacks on one core, and jq parses on one core, each waiting on the other.&lt;/p&gt;&#xA;&lt;p&gt;jvqq reads gzip and zstd files directly, recognized by their first bytes, and parses on every core. This worked example is a week of rotated application logs: seven daily files from jvqq&amp;rsquo;s benchmark generator, 150 MiB each uncompressed and about 23 MB each compressed, 161 MB in all and 3,151,367 lines. The commands below ran with jvqq 0.1.0 and jq 1.7.1 on a two-core cloud VM, with the files already in the page cache.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
