DuckDB  · 

DuckDB Upgrade Speed, Measured from 110M Extension Loads

Nine months of telemetry from Query.Farm's DuckDB extensions — 110 million loads — show each release landing slower than the one before it. Fourteen days in, v1.5.0 reached 33.7% of the population I can see; v1.5.5 reached 12.1%. The decline survives excluding CI traffic, excluding the v1.4 LTS line, and restricting to patch releases only.

Nearly every DuckDB release since v1.5.0 has been adopted more slowly than the one before it. Fourteen days after first appearing, v1.5.0 was running on 33.7% of the population I can see; the four that followed reached 26.4%, 21.1%, 12.3% and 15.3%, and v1.5.5 managed 12.1%.

I can see this because the telemetry client I ship in Query.Farm’s extensions sends one small JSON payload each time an extension loads: 110,413,978 events over 270 days, across 111 countries and 14 platforms. Nine columns wide, no device identifier, nothing about the data being queried. All of it comes from my own 34 extensions, which bounds everything below — not DuckDB itself, not the rest of the community catalog, not anyone who uses DuckDB happily without ever installing one.

That population isn’t a random sample either. These are people who went looking for something the engine doesn’t ship, and who therefore depend on somebody rebuilding that extension for each new engine version. That biases the level: this group should sit further behind than a DuckDB user carrying no extensions at all. It does not explain the trend, and a population that is itself growing and changing composition could produce a falling curve without anyone slowing down. I can’t rule that out, and it’s the weakest joint in the argument.

Extension loads are not installations

The telemetry payload carries no device identifier. That was the right privacy call and I’d make it again, but it means I cannot count people. I can only count loads, and loads are wildly unequal: a laptop that opens DuckDB twice a day and one cloud deployment whose containers restart a hundred thousand times an hour land in the same column.

Group every event by the identifying fields the payload does carry — extension, DuckDB version, platform, country, region — and 110 million events collapse into 9,397 distinct combinations. The ten largest are 61.33% of the entire dataset. The biggest is one extension, on one DuckDB version, on linux_arm64, in one AWS region in Ohio: 15,078,763 loads by itself. Meanwhile 1,687 of those 9,397 combinations were seen exactly once in nine months.

Any statistic computed per-event is therefore mostly a statistic about a handful of autoscaling policies.

If you count extension loads, you're measuring one customer's autoscaler. If you count places, you're measuring everyone else.

So I changed the unit. Rather than counting loads, I count a config-day: one distinct combination of date, country, region, platform, DuckDB version, and extension. A deployment that loads an extension ten million times in one region on one day contributes exactly one. A laptop that loads it once also contributes exactly one.

One day, counted two ways
Every load recorded on 4 August 2026. However many times a source loaded that day — 121,799 or once — it becomes a single config-day.
Counted as loads, quickjs is 54.5% of that day across all its rows, and the catalog looks like a monopoly. Counted as config-days, quickjs is 2.8% and it's one extension among many. Neither number is wrong. They answer different questions.
Bars are scaled to the largest single source; the four named rows are the top four groups by load count that day. The deployment that loaded 121,799 times and the laptop that loaded once both count as 1. That flattening is what makes the unit useful, and it's also what the unit can't see: a hundred separate people on the same platform in the same cloud region collapse together too.

That gives 164,445 config-days. Seventy percent of them come from configurations that load nearly the entire extension catalog every day.

Two populations, and nothing in between
Every config-day in the window, grouped by how many extensions that configuration loaded that day.
19–32 extensions
nearly the whole catalog
70.1%
1 extension
20.4%
2–5
7.4%
6–18
2.1%
164,445 config-days. The 6–18 band matters most: at 2.1% it is essentially empty, so the split is a gap in the data rather than a threshold I picked.

In July that traffic is 42 configurations in 11 country/region pairs — all linux_amd64 in cloud regions, present on 20 to 31 days out of 31, loading 28 to 32 extensions daily. It is continuous-integration infrastructure verifying that the catalog still builds, and some of it is very likely mine.

A CI job that installs every extension gives every extension the same number of config-days: about 695 each in July, whether anyone uses it or not.

Counting only configurations that loaded five or fewer extensions in a day removes that traffic. I’ll call those selective config-days — 45,696 of the 164,445 — and every figure below is computed on them.

The selective population is growing, and not because the same deployments got busier. It lands in new places at a steady rate:

Not the same deployments getting busier
Daily selective config-day population, and country/region pairs seen for the very first time each month.
Selective config-day growth and new locations per month Selective config-days per day 300 150 41 341 New places, first ever seen 135 59 50 41 56 45 55 33 61 Nov Dec Jan Feb Mar Apr May Jun Jul 2025 – 2026, complete months only
The daily selective population grew 8.2x, from 41 config-days a day to 341. Underneath it, between 33 and 61 country/region pairs turn up for the first time every month with no sign of tailing off — 535 distinct places by the end of July. November's bar is faded because everything is new in the first month of collection. August is excluded; it was four days old when I pulled this.

A share-of-population metric has one more failure mode worth naming: it inflates whatever is unattended whenever the humans leave. Over the 2025 holidays the daily population fell by about a quarter while the always-on machines kept going. The version analysis below therefore stays inside 2026-03 onward, where the seasonal swing is small.

How fast a DuckDB release takes over

Every release since v1.5.0 falls inside the data window, and the date I first see a version in the wild matches its published release date to within a day. So I can line up six releases at day zero.

Each release climbs slower than the last
Share of the daily selective population, by days since the version first appeared. 7-day trailing mean.
DuckDB v1.5.x adoption curves, CI excluded 40% 30% 20% 10% day 14 v1.5.0 v1.5.1 v1.5.2 v1.5.3 v1.5.4 v1.5.5 0 7 14 21 28 35 42 days since the version first appeared in telemetry
Gold is v1.5.5, which is only 14 days old, so its line stops at the dotted mark. Green is v1.5.4; the four faded lines are v1.5.0 to v1.5.3. Lines fall away on the right because a later release took share from them.

One inversion in six, and otherwise a straight descent. v1.5.5 at two weeks old has roughly a third of the foothold v1.5.0 had at the same age.

The obvious objection is that v1.5.0 is a minor release and everything after it is a patch, so this could just be “people move eagerly to a new minor and lazily to its patches.” That would be ordinary, and not worth a post. It doesn’t hold: comparing patch releases only, across both the v1.4 and v1.5 lines, day-14 share runs v1.4.2 49.4%, v1.4.3 41.2%, v1.4.4 18.1%, v1.5.1 26.3%, v1.5.2 21.1%, v1.5.3 12.3%, v1.5.4 15.3%, v1.5.5 12.1%. Eight patches over nine months, no minor in the set, same decline.

Nor is it people parking on the v1.4 LTS line: that share has fallen every month, from 67.6% in March to 22.4% in August.

ReleaseFirst seen Days to 10%Days to 20% Days to 30%Best it ever did
v1.5.02026-03-0923940.8%
v1.5.12026-03-2314936.0%
v1.5.22026-04-133101541.3%
v1.5.32026-05-2082128.8%
v1.5.42026-06-176202738.4%
v1.5.52026-07-21214.9% so far

Days to 20% went 3, 4, 10, 21, 20, and v1.5.5 hasn’t reached it in 14 days. The first week barely changed — every release still crosses 10% within about a week. What changed is the middle of the curve, which is where you’d expect a supply constraint rather than an appetite problem.

My best guess is the extension availability gap: people upgrade when the extension they depend on has a build for the new engine, and the tail of that catalog takes weeks. Consistent with it, v1.5.5 uptake in the last complete week ranges from 9.7% to 25.5% depending on which extension the configuration was loading — a 2.6x spread in the same week. That’s a hypothesis, not a proof; making it stick needs per-extension build timestamps joined to this, which I haven’t done.

The six v1.5.x releases arrived 14, 21, 37, 28 and 34 days apart, a mean of 26.8 days. v1.5.4 needed 27 days to reach 30%. The release train is running at roughly the speed people climb aboard.

Two releases back is normal

Here is the last complete week, 2,523 selective config-days:

What DuckDB people are actually running
Share of selective config-days, 2026-07-29 to 2026-08-04. Gold is the current release.
v1.5.4
23.3%
v1.4.4
LTS line
20.0%
v1.5.3
13.8%
v1.5.5
current
12.1%
v1.5.1
8.6%
v1.5.2
8.2%
v1.4.2
4.2%
v1.4.3
3.4%
v1.5.0
2.7%
everything else
3.6%
Bars are scaled to a 25% axis, not to each other. "Everything else" is v1.4.1, v1.4.0, v1.3.x, nightly builds and one client reporting v0.0.1.

Half the population — 50.7% — is more than two releases back. A little over a quarter, 28.5%, is on the v1.4 LTS line, which is where the support policy invites people to be. Calling them behind is just complaining that LTS works. The median configuration is on an engine 76 days old; the 90th percentile is 189 days.

One thing inside that line stands out. v1.4.4 is 70.0% of it, while v1.4.5 — the LTS patch — accounts for 0.42%. It shipped on 17 June, the same day as v1.5.4, which may be most of the answer. Whatever process moved these configurations onto v1.4.4 doesn’t seem to be running any more.

What I can’t tell you

I can’t tell you how many people use these extensions. Not approximately, not within an order of magnitude. There is no identifier in the payload and I’m not going to add one.

I can’t tell you whether the slowdown is causal. The curves are real, they survive excluding CI, excluding the LTS line, and restricting to patch releases only — but the population I’m measuring is growing and changing composition, and generalizing any of it to DuckDB at large requires an assumption I can’t test: that the people I can see upgrade like the people I can’t.

What this is, precisely, is a picture of the people who depend on community extensions. Among them, half are more than two releases back, and each release lands slower than the one before it. If the availability gap really is the mechanism, this is the group that would feel it first — which makes them the wrong sample for measuring DuckDB and close to the right one for measuring the gap.

DuckDB DuckDB Extensions Telemetry Query.Farm Data Engineering

Related reading