Why this matters
Deprecating an old SDK version is easy — git rm, ship a note. Deprecating without breaking 30% of your customers is the hard part. Without per-version distribution data you’re guessing whether the upgrade-or-fail email goes to 12 customers or 1,200.
Most teams find out only after the deprecation breaks production for a large account. That call is uniquely terrible because it’s 100% preventable — the data was always there in your API logs, you just never queried it.
Agentry treats SDK version as a property on api_request events. One HogQL pass gives you the distribution + customer list per version. The deprecation conversation becomes specific instead of “let’s wait another quarter to be safe.”
What you get
- Distribution of distinct customers per SDK version
- Same distribution by request volume (sometimes one customer on the old SDK is 90% of your old-SDK traffic)
- A clear list of “customers still on N-2 or older” — your outbound list
Walk through it
Look at the sdk_version property of api_request events. What % of distinct customers are on the latest vs N-1 vs N-2 or older?
Distinct customers per version, then a rollup.
agentry_analytics_query {
project_id: "default",
query: "
select
properties.sdk_version as ver,
count(distinct properties.customer_id) as customers,
count() as requests
from events
where event = 'api_request' and timestamp > now() - interval 30 day
group by ver
order by ver desc
"
}
{
"rows": [
{ "ver": "3.4.0", "customers": 142, "requests": 4200000 },
{ "ver": "3.3.2", "customers": 610, "requests": 38400000 },
{ "ver": "3.3.1", "customers": 240, "requests": 6800000 },
{ "ver": "3.3.0", "customers": 120, "requests": 2400000 },
{ "ver": "3.2.4", "customers": 42, "requests": 180000 },
{ "ver": "3.1.9", "customers": 18, "requests": 840000 },
{ "ver": "2.8.1", "customers": 3, "requests": 2200000 }
]
}
Two ways to slice the picture:
By customer count:
| Version | Customers | % of customers |
|---|---|---|
| 3.4.0 (latest) | 142 | 11.7% |
| 3.3.x (N-1) | 970 | 80.1% |
| 3.2.x (N-2) | 42 | 3.5% |
| 3.1.x | 18 | 1.5% |
| 2.x | 3 | 0.2% |
By request volume: (this is where it gets interesting)
| Version | Requests | % of traffic |
|---|---|---|
| 3.4.0 | 4.2M | 7.6% |
| 3.3.x | 47.6M | 86.6% |
| 3.2.x | 0.18M | 0.3% |
| 3.1.x | 0.84M | 1.5% |
| 2.x | 2.2M | 4.0% ★ |
Notable: 3 customers on v2.8.1 are 4% of your total API traffic (2.2M requests/30d). One of them is presumably one of your big enterprise accounts that never upgraded. Deprecating 2.x without warning would be a Tier-1 incident.
Recommended:
- Safe to deprecate 3.1.x and older (~63 customers, mostly low-volume). Send a 90-day notice.
- Find who the v2.8.1 customers are — they need an account-manager-led upgrade conversation, not an email blast.
- Publish the table so the API team can pull it up at every release planning.
agentry_publish_query {
recipe_id: "raw_hogql",
description: "SDK version distribution (30d)",
params: { query: "<same query above>" }
}
{ "publication_id": "pub_sdk_v", "public_url": "https://agentry.sh/q/pub_sdk_v?key=agp_…" }
agentry_analytics_query {
project_id: "default",
query: "
select
properties.customer_id as customer,
sum(case when properties.sdk_version = '2.8.1' then 1 else 0 end) as v2_calls,
sum(case when properties.sdk_version like '3.%' then 1 else 0 end) as v3_calls
from events
where event = 'api_request' and timestamp > now() - interval 30 day
group by customer
having v2_calls > 0
order by v2_calls desc
"
}
{
"rows": [
{ "customer": "wayne_ent", "v2_calls": 1840000, "v3_calls": 0 },
{ "customer": "umbrella_co", "v2_calls": 240000, "v3_calls": 4810000 },
{ "customer": "stark_legacy", "v2_calls": 120000, "v3_calls": 0 }
]
}
Interesting: umbrella_co is mostly on v3 (4.8M v3 calls) but still has 240k v2 calls — probably one stale microservice they forgot about. Easy ask for them to find and update.
wayne_ent and stark_legacy are 100% on v2. These are the conversations that need an AM, not a blast email.
The output
SDK version distribution (30d)
Version Customers % Requests % Notes
─────────────────────────────────────────────────────────────────
3.4.0 142 11.7% 4,200,000 7.6% latest
3.3.2 610 50.4% 38,400,000 69.9% N-1 (stable)
3.3.1 240 19.8% 6,800,000 12.4% N-1
3.3.0 120 9.9% 2,400,000 4.4% N-1
3.2.4 42 3.5% 180,000 0.3% N-2 (deprecate)
3.1.9 18 1.5% 840,000 1.5% deprecate
2.8.1 3 0.2% 2,200,000 4.0% ★ enterprise — AM-led
Deprecation plan:
Tier 1: 3.1.x and older (≤63 customers, low volume)
→ 90-day email notice
→ Hard sunset at +90 days
Tier 2: 2.8.1 customers (3 customers, HIGH volume)
→ AM-led upgrade
→ wayne_ent and stark_legacy need migration help
→ umbrella_co has a stray service (240k calls) to track down
Public dashboard:
https://agentry.sh/q/pub_sdk_v?key=agp_xxx
Setting it up
Tag every api_request event with the SDK version the client sent (or the absence of a version, which usually means “raw HTTP / curl”):
// API middleware
const sdkVersion =
c.req.header("x-sdk-version") ?? // SDK convention
c.req.header("user-agent")?.match(/myapi-sdk-js\/([\d.]+)/)?.[1] ??
"unknown";
fetch(`https://api.agentry.sh/v1/analytics/${PROJECT_ID}/`, {
method: "POST",
headers: {
"Authorization": `Bearer ${env.AGENTRY_DSN}`,
"Content-Type": "application/json",
"User-Agent": "myapi-edge/1.0", // REQUIRED — Cloudflare 403s default UAs
},
body: JSON.stringify({
event: "api_request",
distinct_id: customer.id,
properties: {
customer_id: customer.id,
sdk_version: sdkVersion,
sdk_language: c.req.header("x-sdk-language") ?? "unknown",
endpoint: c.req.routePath,
},
}),
}).catch(() => {});
If your SDK doesn’t send a version header today, ship a version that does in the next release. Old clients will continue to show as “unknown” — that group itself is informative (“how many requests are coming from people who don’t even use our SDK?”).
Variations
- “Same query split by sdk_language — what % of traffic is from the Python SDK vs JS vs Go?”
- “For each old SDK version, which API endpoints do those clients hit? Tells me what to keep backward-compatible on the API surface.”
- “Error rate per SDK version — old versions sometimes drive higher error rates because they don’t handle new error codes.”
- “Day-over-day trend on v3.4.0 adoption — is the latest release picking up users at expected rate?”