<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Moksh Gupta</title>
    <description>The latest articles on DEV Community by Moksh Gupta (@moksh).</description>
    <link>https://dev.to/moksh</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2457679%2F32485ee6-614e-4050-bd8e-e22536e1f2b5.png</url>
      <title>DEV Community: Moksh Gupta</title>
      <link>https://dev.to/moksh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/moksh"/>
    <language>en</language>
    <item>
      <title>API Docs Platforms in 2026: What Removing the Vendor Logo Actually Costs</title>
      <dc:creator>Moksh Gupta</dc:creator>
      <pubDate>Sun, 27 Sep 2026 19:19:03 +0000</pubDate>
      <link>https://dev.to/moksh/api-docs-platforms-in-2026-what-removing-the-vendor-logo-actually-costs-1hgj</link>
      <guid>https://dev.to/moksh/api-docs-platforms-in-2026-what-removing-the-vendor-logo-actually-costs-1hgj</guid>
      <description>&lt;p&gt;Most API teams stopped hand-writing their reference docs years ago. Point a tool at an OpenAPI file and it renders the endpoint list, the schemas and a try-it console for you, which is exactly why it's strange that Postman's 2025 State of the API Report (5,700+ respondents, published August 2025) still found 55% of API teams fighting inconsistent, outdated or missing documentation. The spec is accurate. The docs still aren't. I went through pricing pages for six platforms to see why, and wrote a longer version of the breakdown on &lt;a href="https://devtoollab.com/blog/best-api-documentation-platforms" rel="noopener noreferrer"&gt;DevToolLab&lt;/a&gt; if you want every screenshot and the full per-tool rundown.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkbwt47ozff5aswbcwui6.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkbwt47ozff5aswbcwui6.webp" alt="Mintlify homepage headed " width="800" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The workflow every tool here assumes
&lt;/h2&gt;

&lt;p&gt;Same report: 60% of teams version their APIs, 57% keep specs in Git, and 41% now use AI somewhere in the docs pipeline (enough that Postman folded a generator called Fern into its own product). None of that changes what has to happen next - a spec still needs a tool to turn it into a browsable site with search, versioning, and usually a domain that doesn't say the vendor's name on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The gate that's easy to miss
&lt;/h2&gt;

&lt;p&gt;Every platform below gives you a custom domain cheaply or free. What's gated separately, and priced very differently, is removing the vendor's own branding entirely.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Custom domain from&lt;/th&gt;
&lt;th&gt;Branding removal&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mintlify&lt;/td&gt;
&lt;td&gt;$0/month&lt;/td&gt;
&lt;td&gt;Enterprise only, custom price&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ReadMe&lt;/td&gt;
&lt;td&gt;$0/month&lt;/td&gt;
&lt;td&gt;Enterprise only, custom price&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stoplight&lt;/td&gt;
&lt;td&gt;$113/month (annual)&lt;/td&gt;
&lt;td&gt;$362/month (annual) tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Redocly&lt;/td&gt;
&lt;td&gt;$10/seat/month&lt;/td&gt;
&lt;td&gt;not gated separately&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scalar&lt;/td&gt;
&lt;td&gt;$0/month&lt;/td&gt;
&lt;td&gt;not gated separately&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Swagger UI&lt;/td&gt;
&lt;td&gt;self-hosted&lt;/td&gt;
&lt;td&gt;no vendor mark to begin with&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Stoplight is the most upfront about it: Basic and Startup get domains and theming, but "Remove Stoplight branding" doesn't show up until Pro Team at $362/month billed annually. If "our logo, not theirs" is a hard requirement, that's the number to plan around, not the entry-tier price everyone quotes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhjw7c1go44il7tppoy37.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhjw7c1go44il7tppoy37.webp" alt="Stoplight homepage headed " width="800" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Six platforms, six pricing models
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://mintlify.com/" rel="noopener noreferrer"&gt;Mintlify&lt;/a&gt;&lt;/strong&gt; is the fastest to stand up: point it at a GitHub repo and an &lt;code&gt;openapi.yaml&lt;/code&gt;, and you get API reference, search and an in-browser playground in minutes, no build step. It also runs an AI layer that flags pages drifting out of sync with the spec. Free Starter caps at 5 editor seats; Pro is $450/month with unlimited seats and 10,000 AI credits (then $0.01/credit).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://readme.com/" rel="noopener noreferrer"&gt;ReadMe&lt;/a&gt;&lt;/strong&gt; is a full docs CMS wrapped around the API reference, and its editor can push changes back into your source repo, not just read from it. The catch is one project per plan below Enterprise, so two APIs need two subscriptions. Pro is $250/month annual.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://stoplight.io/" rel="noopener noreferrer"&gt;Stoplight&lt;/a&gt;&lt;/strong&gt;, a SmartBear product since 2022, leans into the design side: a visual OpenAPI editor plus shared style guides across up to 20 teams on Pro Team. Free is one user, one project; extra editors cost $11-27/month on top of whichever tier you're on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://redocly.com/" rel="noopener noreferrer"&gt;Redocly&lt;/a&gt;&lt;/strong&gt; sells hosting and a catalog layer on top of Redoc, the open-source renderer that clears 1M npm downloads/week (MIT, v2.5.3, 25,927 GitHub stars). Pro is metered: $10/seat/month, capped at 100 pages before you need the next tier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://scalar.com/" rel="noopener noreferrer"&gt;Scalar&lt;/a&gt;&lt;/strong&gt; is the one that's genuinely self-hostable start to finish - MIT core, 16,197 stars, shipped a release as recently as September 25, 2026. Run the reference UI and API client free forever; pay only for hosting, SDK generation or their MCP server output. Free stops at 3 APIs; Business tops out at 25.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpyn5ew5w22ju3eh7p8a8.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpyn5ew5w22ju3eh7p8a8.webp" alt="Scalar homepage headed " width="799" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://swagger.io/tools/swagger-ui/" rel="noopener noreferrer"&gt;Swagger UI&lt;/a&gt;&lt;/strong&gt; is still the baseline everyone else gets compared to: Apache 2.0, 29,026 stars, no account or seat count because there's no hosted product at all. It renders one spec into one page and leaves hosting to you. If you just want to paste a spec and look at it without deploying anything, DevToolLab's &lt;a href="https://devtoollab.com/tools/swagger-viewer" rel="noopener noreferrer"&gt;Swagger Viewer&lt;/a&gt; does that same job in the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Picking without migrating twice
&lt;/h2&gt;

&lt;p&gt;A few things worth checking before you commit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Count specs, not headcount.&lt;/strong&gt; Redocly and Scalar price on distinct APIs and page counts, not seats, so match your real spec count against their tier tables.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decide on branding removal up front.&lt;/strong&gt; If zero third-party logo is non-negotiable, price Mintlify/ReadMe Enterprise or Stoplight's $362 tier now, not after launch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Try the free renderer first.&lt;/strong&gt; Paste your spec into Swagger UI or Scalar's open core - if it looks fine, the paid tier is selling hosting and search, not the rendering itself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Match sync direction to who edits docs.&lt;/strong&gt; ReadMe's bi-directional editing solves "writer fixes a typo without a PR." Mintlify's drift detection solves "spec and page disagree." Different problems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href="https://devtoollab.com/blog/best-api-documentation-platforms" rel="noopener noreferrer"&gt;original post&lt;/a&gt; has the full side-by-side table (model, cheapest paid tier, self-host status, license) and a use-case breakdown for five different team shapes, plus the sourcing for every GitHub star count and release date above.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bottom line
&lt;/h2&gt;

&lt;p&gt;Turning an OpenAPI file into a readable page has been free for years, through Swagger UI and now Scalar's open core. What the current crop of paid platforms sells is what happens around that page - AI drift detection, bi-directional editing, multi-team governance, and a domain with nobody else's logo on it. Check which of those your subscription actually includes before renewing.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devtoollab.com/blog/best-api-documentation-platforms" rel="noopener noreferrer"&gt;Best API Documentation Platforms in 2026 - full comparison on DevToolLab&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.postman.com/state-of-api/" rel="noopener noreferrer"&gt;Postman 2025 State of the API Report&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mintlify.com/pricing" rel="noopener noreferrer"&gt;Mintlify pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://readme.com/pricing" rel="noopener noreferrer"&gt;ReadMe pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stoplight.io/pricing" rel="noopener noreferrer"&gt;Stoplight pricing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>api</category>
      <category>devops</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Tracing Backends in 2026: Same Spans, Five Different Bills</title>
      <dc:creator>Moksh Gupta</dc:creator>
      <pubDate>Fri, 25 Sep 2026 18:17:55 +0000</pubDate>
      <link>https://dev.to/moksh/tracing-backends-in-2026-same-spans-five-different-bills-2kdd</link>
      <guid>https://dev.to/moksh/tracing-backends-in-2026-same-spans-five-different-bills-2kdd</guid>
      <description>&lt;p&gt;A checkout request that hits a load balancer, three services, Postgres, a queue and Stripe leaves four seconds of latency and no obvious culprit until you stitch the hops into one timeline. That's what distributed tracing is for, and I went looking for what it actually costs to store that timeline once you're past the free tier. I wrote up the full breakdown on &lt;a href="https://devtoollab.com/blog/best-distributed-tracing-tools" rel="noopener noreferrer"&gt;DevToolLab&lt;/a&gt;, and the short version is that nobody prices tracing the same way, so a side-by-side comparison means nothing unless you know your span size first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nobody bills the same unit
&lt;/h2&gt;

&lt;p&gt;Grafana Cloud and SigNoz charge per gigabyte of spans. Honeycomb and Dash0 charge per span. Datadog charges per host plus per million indexed spans. AWS splits between per-trace (classic X-Ray) and per-gigabyte (the newer CloudWatch Transaction Search). None of that is comparable until you know how big your spans are, so instead of trusting a vendor's example numbers I generated 50,000 of them.&lt;/p&gt;

&lt;p&gt;Using the official OpenTelemetry JS SDK and its OTLP protobuf serializer, I built a checkout trace: an HTTP server span, three SQL queries, an inventory service call, a Stripe call, a queue publish, four internal spans, &lt;code&gt;us-east-1&lt;/code&gt; Kubernetes resource attributes attached. Batched in groups of 512 (the SDK default), the average span came out to 266 bytes as protobuf and 656 bytes as JSON. That's a lean number, before auto-instrumentation adds its usual pile of attributes, and it matters because none of the per-GB pricing pages say whether their gigabyte is measured before or after compression.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a month actually costs
&lt;/h2&gt;

&lt;p&gt;Feeding 266-byte spans into each vendor's public rate card at two volumes (50 million spans across 6 hosts, and 500 million spans across 24 hosts) produced this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;50M spans/mo, 6 hosts = 13.3 GB
  Grafana Cloud Traces            $19.00
  SigNoz Cloud                    $49.00
  Datadog APM                     $350.80
  Honeycomb Pro                   $150.00
  Dash0                           $30.00
  AWS X-Ray (classic)             $24.50
  CloudWatch Transaction Search   $4.66
  Self-hosted Tempo (S3 only)     $0.31

500M spans/mo, 24 hosts = 133.0 GB
  Grafana Cloud Traces            $56.35
  SigNoz Cloud                    $49.00
  Datadog APM                     $1913.20
  Honeycomb Pro                   not published
  Dash0                           $300.00
  AWS X-Ray (classic)             $249.50
  CloudWatch Transaction Search   $46.55
  Self-hosted Tempo (S3 only)     $3.06
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a roughly 40x spread on the same 500 million spans: $1,913.20 on Datadog versus $46.55 on CloudWatch Transaction Search. Bump the span size to 1 KB and only the per-GB backends move - Grafana Cloud goes to $221.50, SigNoz to $150.00 - while Datadog, Dash0 and X-Ray hold steady, because they never cared about bytes in the first place. Small spans favor per-GB pricing; fat, attribute-heavy spans make per-span pricing look better by comparison. None of this counts self-hosting compute, extended retention or volume discounts, so treat it as a starting estimate, not a quote.&lt;/p&gt;

&lt;h2&gt;
  
  
  The backends, briefly
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.jaegertracing.io/" rel="noopener noreferrer"&gt;Jaeger&lt;/a&gt;&lt;/strong&gt; is the CNCF project, and v2 rebuilt it on top of the OpenTelemetry Collector framework. You pick the storage backend (Elasticsearch, Cassandra, ClickHouse, Badger), which means you also own operating it. v1 reached end of life December 31, 2025.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2qbzq10pth5otdwrhuyx.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2qbzq10pth5otdwrhuyx.webp" alt="Jaeger open source distributed tracing platform homepage" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://grafana.com/oss/tempo/" rel="noopener noreferrer"&gt;Grafana Tempo&lt;/a&gt;&lt;/strong&gt; needs only object storage, and that's why it's cheap: our 133 GB month costs $3.06 in S3 before compute. Version 3.0 replaced the ingester architecture and made TraceQL metrics generally available, but the new write path pulls Kafka into a self-hosted deployment. Grafana Cloud Traces gives you 50 GB free, then $19/month gets you 50 GB more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu84bmvbdd6n5irqmr2ij.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu84bmvbdd6n5irqmr2ij.webp" alt="Grafana Tempo open source distributed tracing backend page" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://signoz.io/" rel="noopener noreferrer"&gt;SigNoz&lt;/a&gt;&lt;/strong&gt; stores traces, logs and metrics together in ClickHouse and prices at a flat $0.30/GB with a $49 minimum, no host or seat fees. The &lt;code&gt;ee/&lt;/code&gt; directory sits under a separate license, so it's not purely MIT, and ClickHouse at scale is its own operational job.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.honeycomb.io/" rel="noopener noreferrer"&gt;Honeycomb&lt;/a&gt;&lt;/strong&gt; counts every span, span event and span link as a billable event but doesn't charge extra for attributes, which the docs call "unlimited custom fields." That makes high-cardinality debugging genuinely cheap, but only the 50M-event, $150/month tier is public. Go past 500 million and you're negotiating.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.datadoghq.com/product/apm/" rel="noopener noreferrer"&gt;Datadog APM&lt;/a&gt;&lt;/strong&gt; bills per host ($31/month, annual) plus per indexed span past the bundled allotment. In our 24-host run, indexed spans alone were $809 of the $1,913 total. It's the best option if Datadog already owns your infra dashboards; it's the worst option if you're optimizing for a tracing line item in isolation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2pjkgp8rfrlifod8phpq.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2pjkgp8rfrlifod8phpq.webp" alt="Datadog APM performance monitoring page with a trace waterfall" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.dash0.com/" rel="noopener noreferrer"&gt;Dash0&lt;/a&gt;&lt;/strong&gt; charges $0.06/M spans ingested plus $0.54/M stored, 30-day retention, no free tier. Sampling inside its own SignalControl filtering only charges the ingest rate, so dropping spans there is cheap - but a lean 266-byte span gets you nothing, since the price is per-span, not per-byte.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://aws.amazon.com/xray/" rel="noopener noreferrer"&gt;AWS X-Ray / CloudWatch Transaction Search&lt;/a&gt;&lt;/strong&gt; is mid-migration: the classic X-Ray SDKs went into maintenance mode February 25, 2026, and the product URL now redirects to CloudWatch. Transaction Search bills $0.35/GB ingested plus $0.75/M spans indexed beyond a small free allotment, and it came out cheapest of every hosted option in both of our workloads.&lt;/p&gt;

&lt;h2&gt;
  
  
  The math side by side
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Backend&lt;/th&gt;
&lt;th&gt;Billing unit&lt;/th&gt;
&lt;th&gt;Entry price&lt;/th&gt;
&lt;th&gt;Retention&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;a href="https://www.jaegertracing.io/" rel="noopener noreferrer"&gt;Jaeger&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Your storage&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;You decide&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;a href="https://grafana.com/oss/tempo/" rel="noopener noreferrer"&gt;Grafana Tempo&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per GB (Cloud)&lt;/td&gt;
&lt;td&gt;Free 50 GB, then $19/mo&lt;/td&gt;
&lt;td&gt;30 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;a href="https://signoz.io/" rel="noopener noreferrer"&gt;SigNoz&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per GB&lt;/td&gt;
&lt;td&gt;$49/mo minimum&lt;/td&gt;
&lt;td&gt;15 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;a href="https://www.honeycomb.io/" rel="noopener noreferrer"&gt;Honeycomb&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per event&lt;/td&gt;
&lt;td&gt;Free 20M, then $150/mo&lt;/td&gt;
&lt;td&gt;60 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;a href="https://www.datadoghq.com/product/apm/" rel="noopener noreferrer"&gt;Datadog APM&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per host + indexed span&lt;/td&gt;
&lt;td&gt;$31/host/mo&lt;/td&gt;
&lt;td&gt;15 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;a href="https://www.dash0.com/" rel="noopener noreferrer"&gt;Dash0&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per span&lt;/td&gt;
&lt;td&gt;$0.60 per 1M kept&lt;/td&gt;
&lt;td&gt;30 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AWS X-Ray / CloudWatch&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per trace or per GB&lt;/td&gt;
&lt;td&gt;100k traces free&lt;/td&gt;
&lt;td&gt;30 days (classic)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Picking one without migrating twice
&lt;/h2&gt;

&lt;p&gt;Instrument with OpenTelemetry regardless of backend - Jaeger v2 is built on the OTel Collector and even AWS is steering people off its own SDKs, so vendor lock-in now happens at the pricing layer, not the instrumentation layer. Before you sign anything, point a Collector at a file exporter for an hour of real production traffic and divide total bytes by span count; that single number tells you whether per-GB or per-span pricing wins. Do your tail sampling in the Collector, not in the vendor's ingestion pipeline, since Grafana Cloud and Dash0 both bill ingestion even for spans you're about to sample out. And keep a Collector between your apps and whichever backend you pick, so switching later is a config change, not a redeploy.&lt;/p&gt;

&lt;p&gt;If you're a small team, Grafana Cloud's $19/month Pro tier covered our entire 50-million-span workload inside its included 50 GB. If you want to own your data outright, Tempo or Jaeger-on-ClickHouse both work, but budget engineering time, not just storage dollars. If you're already deep in Datadog, stay, but index selectively - that's where the real cost sits. If you're all-in on AWS, CloudWatch Transaction Search undercut everything else we tested at both volumes. I go into more of the decision framework, plus the actual &lt;a href="https://devtoollab.com/blog/best-distributed-tracing-tools" rel="noopener noreferrer"&gt;pricing script&lt;/a&gt; you can run against your own numbers, in the full post.&lt;/p&gt;

&lt;p&gt;If you're setting up the collector side of this, DevToolLab's &lt;a href="https://devtoollab.com/tools/otel-config-generator" rel="noopener noreferrer"&gt;OTel Config Generator&lt;/a&gt; builds the tail-sampling and dual-write YAML mentioned above, and the &lt;a href="https://devtoollab.com/tools/protobuf-decoder" rel="noopener noreferrer"&gt;Protobuf Decoder&lt;/a&gt; is handy for reading a captured OTLP span payload without hunting down the &lt;code&gt;.proto&lt;/code&gt; file.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://devtoollab.com/blog/best-distributed-tracing-tools" rel="noopener noreferrer"&gt;Best Distributed Tracing Tools in 2026 - DevToolLab&lt;/a&gt; - the original post, including the full cost-modeling script&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.jaegertracing.io/" rel="noopener noreferrer"&gt;Jaeger&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://grafana.com/oss/tempo/" rel="noopener noreferrer"&gt;Grafana Tempo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://signoz.io/" rel="noopener noreferrer"&gt;SigNoz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.honeycomb.io/" rel="noopener noreferrer"&gt;Honeycomb&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.datadoghq.com/product/apm/" rel="noopener noreferrer"&gt;Datadog APM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.dash0.com/" rel="noopener noreferrer"&gt;Dash0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/xray/" rel="noopener noreferrer"&gt;AWS X-Ray&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>opensource</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>I Planted 10 Fake API Keys in a Repo and Ran 4 Secret Scanners on It</title>
      <dc:creator>Moksh Gupta</dc:creator>
      <pubDate>Thu, 24 Sep 2026 18:14:48 +0000</pubDate>
      <link>https://dev.to/moksh/i-planted-10-fake-api-keys-in-a-repo-and-ran-4-secret-scanners-on-it-1h0j</link>
      <guid>https://dev.to/moksh/i-planted-10-fake-api-keys-in-a-repo-and-ran-4-secret-scanners-on-it-1h0j</guid>
      <description>&lt;p&gt;Once a credential lands in a pushed commit, removing the line fixes nothing. The key is in every clone and every CI cache, so the only real remedy is revoking it at the provider, and you can only revoke the keys a scanner actually reports.&lt;/p&gt;

&lt;p&gt;That makes detection quality the whole game. So instead of comparing feature pages, I built a small test: a throwaway repository with ten fake credentials in real token formats, one of them committed and then deleted, and four open-source scanners pointed at its full history. The longer version, with per-tool screenshots and pricing detail, is &lt;a href="https://devtoollab.com/blog/best-secret-scanning-tools" rel="noopener noreferrer"&gt;on DevToolLab&lt;/a&gt;. This is the condensed pass.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh9zc7zfxgm52r24c0h3f.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh9zc7zfxgm52r24c0h3f.webp" alt="Banner for the secret scanning tools comparison" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this got worse in 2025
&lt;/h2&gt;

&lt;p&gt;GitGuardian's State of Secrets Sprawl 2026 report, released March 17, 2026, counted 28.65 million new hardcoded secrets in public GitHub commits during 2025, up 34% on the year before. Two other numbers from that report stuck with me. Commits co-written with Claude Code leaked secrets at 3.2%, about double the 1.5% baseline for all public commits. And 64% of credentials that were valid in 2022 still worked when retested in January 2026. People find leaks and never rotate.&lt;/p&gt;

&lt;p&gt;The tooling landscape moved too. Praetorian archived Nosey Parker (last release v0.24.0, May 2025), Yelp's detect-secrets has not shipped since May 2024, and the original Gitleaks author started a successor called Betterleaks in February 2026 after saying he no longer fully controls the Gitleaks repo and name.&lt;/p&gt;

&lt;h2&gt;
  
  
  The test setup
&lt;/h2&gt;

&lt;p&gt;The repo has four commits. The first holds an AWS key pair, a Postgres URL with a password, a Slack webhook and a SendGrid key in source files. The second adds a &lt;code&gt;.env&lt;/code&gt; with a Stripe live key and a GitHub token, plus an RSA private key. The third deletes the &lt;code&gt;.env&lt;/code&gt; and the key file, which is the classic "I noticed and cleaned it up" commit. The fourth adds an &lt;code&gt;.mcp.json&lt;/code&gt; with inline OpenAI and Anthropic keys, alongside decoys: lockfile hashes, a UUID, AWS's documented &lt;code&gt;AKIAIOSFODNN7EXAMPLE&lt;/code&gt; and a &lt;code&gt;your-api-key-here&lt;/code&gt; placeholder.&lt;/p&gt;

&lt;p&gt;Validation was off everywhere, so no tool could lean on calling a provider API. These are the exact commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gitleaks git ./repo &lt;span class="nt"&gt;-f&lt;/span&gt; json &lt;span class="nt"&gt;-r&lt;/span&gt; out/gitleaks.json &lt;span class="nt"&gt;--no-banner&lt;/span&gt;
betterleaks git ./repo &lt;span class="nt"&gt;-f&lt;/span&gt; json &lt;span class="nt"&gt;-r&lt;/span&gt; out/betterleaks.json
trufflehog git file://./repo &lt;span class="nt"&gt;--json&lt;/span&gt; &lt;span class="nt"&gt;--no-update&lt;/span&gt; &lt;span class="nt"&gt;--no-verification&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; out/trufflehog.json
kingfisher scan ./repo &lt;span class="nt"&gt;--no-validate&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; json &lt;span class="nt"&gt;-o&lt;/span&gt; out/kingfisher.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I regenerated the repo with fresh random values five times and got the same result every run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gitleaks     findings= 9  seeds found=9/10  noise=0  missed=[postgres]
betterleaks  findings= 9  seeds found=9/10  noise=0  missed=[awsSecret]
trufflehog   findings= 9  seeds found=10/10  noise=0  missed=[]
kingfisher   findings= 9  seeds found=9/10  noise=0  missed=[awsSecret]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every scanner caught the secrets hiding in the deleted commit, and none flagged a decoy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real code is where the ranking changes
&lt;/h2&gt;

&lt;p&gt;A seeded repo is the easy case. To see noise, I timed each tool over the full history of Express (6,425 commits) on an Apple M3 Pro. Every single finding there was a false positive:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scanner&lt;/th&gt;
&lt;th&gt;Median time&lt;/th&gt;
&lt;th&gt;Findings on Express&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Betterleaks 1.8.1&lt;/td&gt;
&lt;td&gt;0.77 s&lt;/td&gt;
&lt;td&gt;5 (test fixtures, an example login, a package version)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kingfisher 2.7.0&lt;/td&gt;
&lt;td&gt;0.91 s&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gitleaks 8.30.1&lt;/td&gt;
&lt;td&gt;1.08 s&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TruffleHog 3.97.9&lt;/td&gt;
&lt;td&gt;2.70 s&lt;/td&gt;
&lt;td&gt;1 (a URL with credentials in a code comment)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So the fastest tool was also the noisiest on real fixtures, and the slowest was the only one with a perfect seed score. Run two scanners on your own noisiest repo before you pick one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four open-source scanners, briefly
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Gitleaks&lt;/strong&gt; (MIT, v8.30.1, March 21, 2026) is the default everyone reaches for: one Go binary, 222 rules, zero noise here. It missed the Postgres connection string entirely and does not validate anything. The last release is six months old.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Betterleaks&lt;/strong&gt; (MIT, v1.8.1, August 18, 2026) is a drop-in replacement for Gitleaks with 463 rules, backed by Aikido Security. It filters candidates with BPE token efficiency instead of plain entropy; the project claims 98.6% recall on CredData versus 70.4% for entropy, which is the author's number, not an independent one. Its &lt;code&gt;generic-password&lt;/code&gt; rule is the noise source.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TruffleHog&lt;/strong&gt; (AGPL-3.0, v3.97.9, September 24, 2026) found all ten. Its real selling point is verification: it classifies 800+ secret types and logs in to check whether each one is live, so &lt;code&gt;--results=verified&lt;/code&gt; turns a pile of findings into a revocation list. Watch the AGPL if you plan to embed it in something you ship.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftqqau1s98rikfn4lzgl4.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftqqau1s98rikfn4lzgl4.webp" alt="TruffleHog repository page with the tagline " width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kingfisher&lt;/strong&gt; (Apache 2.0, v2.7.0, September 24, 2026) is MongoDB's Rust scanner. Version 2 uses the Betterleaks rule catalog plus Google's Veles detectors, which is why its seed results matched Betterleaks exactly. What sets it apart is what happens after detection: it validates, maps the blast radius of a leaked key across 43 providers and can revoke 34 credential types, all in the free release.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnnmbyogse4d7nbt4hytt.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnnmbyogse4d7nbt4hytt.webp" alt="Kingfisher homepage showing 485 detection rules and 43 blast radius providers" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The paid options
&lt;/h2&gt;

&lt;p&gt;GitHub Secret Protection has been sold on its own since April 1, 2025 at $19 per active committer per month. Its best feature is push protection: the push is rejected before the secret ever enters history. Public repos get it free, but the generic patterns that catch connection strings are paid only.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdzn1rjemlnajykjpi23b.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdzn1rjemlnajykjpi23b.webp" alt="GitHub push protection rejecting a push with error GH009: Secrets detected" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitGuardian's free Starter plan covers up to 25 developers, which for that headcount beats the $5,700 a year GitHub would charge. Its CLI, &lt;code&gt;ggshield&lt;/code&gt;, sends content to GitGuardian's API for detection, so it does not scan locally. The full side-by-side table, with license and price columns, is in the &lt;a href="https://devtoollab.com/blog/best-secret-scanning-tools" rel="noopener noreferrer"&gt;original comparison&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would actually do
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Run TruffleHog with &lt;code&gt;--results=verified&lt;/code&gt; over every repo you own, once. The count of live keys tells you whether this is cleanup or an incident.&lt;/li&gt;
&lt;li&gt;Block at push time. On GitHub that is push protection; elsewhere, a Gitleaks or Betterleaks pre-commit hook plus a CI job nobody can skip.&lt;/li&gt;
&lt;li&gt;Allowlist your test fixtures on day one, or the noise trains your team to ignore the alerts.&lt;/li&gt;
&lt;li&gt;If you need to know what a leaked key could reach, Kingfisher's blast-radius mapping is the free way to find out.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For a quick check before pasting a config into an issue or a Slack thread, I built a browser-based &lt;a href="https://devtoollab.com/tools/secret-scanner" rel="noopener noreferrer"&gt;secret scanner&lt;/a&gt; that runs locally and redacts what it finds, and a &lt;a href="https://devtoollab.com/tools/shannon-entropy-calculator" rel="noopener noreferrer"&gt;Shannon entropy calculator&lt;/a&gt; that shows why a random token trips these tools while a long config value does not.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://devtoollab.com/blog/best-secret-scanning-tools" rel="noopener noreferrer"&gt;Best Secret Scanning Tools in 2026, Tested&lt;/a&gt; - the original, with the full comparison table and persona verdicts&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.gitguardian.com/the-state-of-secrets-sprawl-2026/" rel="noopener noreferrer"&gt;GitGuardian: The State of Secrets Sprawl 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.aikido.dev/blog/betterleaks-gitleaks-successor" rel="noopener noreferrer"&gt;Aikido: Betterleaks, the Gitleaks successor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.blog/changelog/2025-03-04-introducing-github-secret-protection-and-github-code-security/" rel="noopener noreferrer"&gt;GitHub Changelog: Introducing GitHub Secret Protection and GitHub Code Security&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/gitleaks/gitleaks" rel="noopener noreferrer"&gt;Gitleaks&lt;/a&gt;, &lt;a href="https://github.com/betterleaks/betterleaks" rel="noopener noreferrer"&gt;Betterleaks&lt;/a&gt;, &lt;a href="https://github.com/trufflesecurity/trufflehog" rel="noopener noreferrer"&gt;TruffleHog&lt;/a&gt;, &lt;a href="https://github.com/mongodb/kingfisher" rel="noopener noreferrer"&gt;Kingfisher&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>security</category>
      <category>opensource</category>
      <category>devops</category>
      <category>git</category>
    </item>
    <item>
      <title>Log Management Pricing in 2026: Four Rate Cards, One 500 GB Workload</title>
      <dc:creator>Moksh Gupta</dc:creator>
      <pubDate>Wed, 23 Sep 2026 19:33:24 +0000</pubDate>
      <link>https://dev.to/moksh/log-management-pricing-in-2026-four-rate-cards-one-500-gb-workload-1hae</link>
      <guid>https://dev.to/moksh/log-management-pricing-in-2026-four-rate-cards-one-500-gb-workload-1hae</guid>
      <description>&lt;p&gt;Metrics roll up. Traces sample. Logs do neither, which is why they are the telemetry bill that keeps climbing in a quarter where nothing shipped. Add a service, add a retry storm, hire two more engineers who each want their own debug lines, and the invoice moves without traffic moving.&lt;/p&gt;

&lt;p&gt;I priced 500 GB of monthly log ingest against four vendor rate cards as published on September 23, 2026. Cheapest was $43.50. Most expensive was $1,360.72. Same bytes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fysr0nghwjkt92v569is2.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fysr0nghwjkt92v569is2.webp" alt="Log management tools compared" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the condensed version. The &lt;a href="https://devtoollab.com/blog/best-log-management-tools" rel="noopener noreferrer"&gt;full breakdown on DevToolLab&lt;/a&gt; carries the per-vendor detail, including the three open source engines I only summarize here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Teams Say They Actually Are
&lt;/h2&gt;

&lt;p&gt;Grafana Labs ran its 4th Annual Observability Survey on March 18, 2026, with 1,363 responses from engineers, SREs and technology leaders in 76 countries.&lt;/p&gt;

&lt;p&gt;The top concern for 2026 was not cost. Complexity and overhead took it at 38%, with signal-to-noise at 34% and cost third at 31%. SaaS is now at half of all respondents in some capacity, up from 43% the year before.&lt;/p&gt;

&lt;p&gt;The number worth planning around is OpenTelemetry adoption for logs specifically: 48%, against 57% for metrics and 50% for traces. Broader context: 77% say open source or open standards matter to their strategy. An OTel collector sitting in front of your backend is what turns a backend swap into a config edit instead of a quarter of work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Arithmetic
&lt;/h2&gt;

&lt;p&gt;You cannot compare these vendors on a per-GB number, because they do not meter the same object. Datadog bills ingestion by GB and indexing by million events, tiered on retention. Grafana Cloud splits one pipeline into three GB meters: Write, Process, Retain. Elastic and Better Stack separate ingestion from retained GB-months. A dollar figure per GB with no unit attached is marketing, not a price.&lt;/p&gt;

&lt;p&gt;So here is one workload against four rate cards:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;KB_PER_LINE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MEVENTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;GB&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;KB_PER_LINE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;e6&lt;/span&gt;   &lt;span class="c1"&gt;// 524.288M lines at 1 KB each&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;plans&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Datadog, standard 30d index&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ingest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GB&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MEVENTS&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;2.50&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Datadog, Flex Logs Starter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ingest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GB&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MEVENTS&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.60&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Grafana Cloud Logs Pro&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;GB&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;process&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;GB&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.050&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Elastic Serverless, Logs Essentials&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ingest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GB&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.07&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;retain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GB&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.017&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;usd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;minimumFractionDigits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;maximumFractionDigits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plans&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;meters&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;meters&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;breakdown&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;meters&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;usd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; + &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;usd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;padStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;breakdown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;totals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`\nspread: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;totals&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;totals&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;x on &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;MEVENTS&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;M log lines`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    $43.50   Elastic Serverless, Logs Essentials  ingest $35.00 + retain $8.50
   $221.50   Grafana Cloud Logs Pro               platform $19.00 + write $180.00 + process $22.50
   $364.57   Datadog, Flex Logs Starter           ingest $50.00 + flex $314.57
 $1,360.72   Datadog, standard 30d index          ingest $50.00 + index $1,310.72

spread: 31.3x on 524.288M log lines
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read the Datadog row again. Ingesting 500 GB costs $50. Indexing it costs $1,310.72, which is 96% of the bill. Every conversation about a Datadog invoice is secretly a conversation about what you agreed not to index.&lt;/p&gt;

&lt;p&gt;The assumption doing the most work here is 1 KB per line. If your logs are structured JSON averaging 2 KB, you have half as many events and roughly half that indexing charge. Measure yours before you trust anyone's model, including mine.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Managed Three
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Datadog&lt;/strong&gt; is the reference price everyone else quotes against. Logging without Limits decouples ingestion from indexing on purpose, so sending everything and indexing a slice is the intended design rather than a workaround. Correlation is the actual product: logs next to APM traces and metrics in one pane, with Watchdog flagging error outliers unprompted. Flex Logs at $0.60 per million events against $2.50 for 30-day standard indexing is a real answer to archive-versus-search, and CloudPrem now covers keeping logs on your own infrastructure. The catch is predictability. Two meters in different units, index pricing that varies by retention tier, and regional ingest variation ($0.10 in the US, $0.12 in the EU) mean the bill moves when traffic shape changes, not just when volume does.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe49ycuueux6wdkq927n4.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe49ycuueux6wdkq927n4.webp" alt="Datadog log management and Log Explorer with Watchdog Insights" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Better Stack&lt;/strong&gt; sells the inverse: bundled plans with one predictable number, aimed directly at Datadog invoices. The "30x cheaper than Datadog" line is plausible against standard indexing, though not verifiable like for like. Packaging is the real strength, since logs, traces, metrics, uptime monitoring and incident response come together, and the free tier is a tier rather than a trial. It does not scale down in a log-only shape: plans bundle three signals at equal volume, so 300 GB of logs and almost no metrics still pays for metrics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Elastic Cloud Serverless&lt;/strong&gt; took the cheapest slot because Logs Essentials prices ingestion and retention separately and low. Search is the reason to be here. This is the lineage that made full-text log search ordinary, and if debugging means arbitrary substring queries over unstructured output, nothing below beats it. Serverless also deletes the cluster-sizing exercise. Simplicity ends above Essentials, where Complete moves ingest to $0.09 and retention to $0.019 and adds separate metrics meters. One note: the $95/month entry price that circulates in third-party comparison posts does not appear on Elastic's own pricing page.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Self-Hosted Four
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Grafana Loki&lt;/strong&gt; is the architectural odd one out, and its docs say why without hedging: it does not index log contents, only a label set per stream. That is the entire cost story. Labels in the index, bulk in object storage at S3 prices. If Prometheus and Grafana are already running, LogQL reads like PromQL's sibling. What you give up is fast arbitrary full-text search, since a query that cannot be narrowed by label turns into a scan, and a badly chosen label set gives you either unusable cardinality or streams too coarse to be useful. AGPL-3.0, v3.7.8 on September 17, 2026, 25,217 stars.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpxc7w7bt3x40hoh3uslq.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpxc7w7bt3x40hoh3uslq.webp" alt="Grafana Loki project page, 25,217 GitHub stars" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OpenSearch&lt;/strong&gt; is the Apache-2.0 route to an Elasticsearch-shaped stack, and if your objection to Elastic is the license rather than the technology, this is the destination. Being unsurprising is the feature: the query DSL, index lifecycle management and dashboards all behave the way an ELK veteran expects. 3.8.0 landed August 5, 2026. It does not escape the operational weight of an inverted index, and its own install docs are honest about that, wanting &lt;code&gt;vm.max_map_count&lt;/code&gt; at 262144 or higher, half of system RAM for the Java heap, and swap disabled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Graylog&lt;/strong&gt; sits in between: pipelines, streams, role-based access control and multi-tenancy shipped as a platform on top of OpenSearch and MongoDB, rather than parts you assemble. It supplies the operations layer raw engines omit, which is why it shows up wherever who-can-see-which-logs is the binding requirement. One correction worth repeating, because it is widely misreported: Graylog is not open source under the OSI definition. It ships under Server Side Public License v1, which is not OSI-approved, and GitHub's license detection returns &lt;code&gt;NOASSERTION&lt;/code&gt; rather than an SPDX identifier. If your policy allows only OSI-approved licenses, this does not clear it. 7.1.9 was tagged September 2, 2026.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4ilug2mpx94fuuu8hquc.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4ilug2mpx94fuuu8hquc.webp" alt="Graylog SIEM and log management homepage" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VictoriaLogs&lt;/strong&gt; is the newest credible option and competes on resource efficiency rather than feature count. It claims up to 30x less RAM and up to 15x less disk than Elasticsearch and Loki. Treat that as a vendor claim, because it appears in VictoriaLogs' own docs with named comparison targets but no workload definition and no methodology I could find. What is checkable is the shape: one zero-config Apache-2.0 binary the docs say runs on a Raspberry Pi with no flag tuning. What it lacks is ecosystem, meaning a thin plugin catalog, little community troubleshooting material, and a query language nobody on your team has used. v1.52.0 shipped July 16, 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side by Side
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Metering model&lt;/th&gt;
&lt;th&gt;Entry price&lt;/th&gt;
&lt;th&gt;Self-host&lt;/th&gt;
&lt;th&gt;License&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Datadog Logs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ingest GB + index per M events&lt;/td&gt;
&lt;td&gt;$0.10/GB + $2.50/M events&lt;/td&gt;
&lt;td&gt;CloudPrem&lt;/td&gt;
&lt;td&gt;Proprietary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Better Stack&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Bundled plan by volume&lt;/td&gt;
&lt;td&gt;Free 3 GB, then $350/mo&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Proprietary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Elastic Serverless&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ingest GB + retained GB-month&lt;/td&gt;
&lt;td&gt;$0.07/GB&lt;/td&gt;
&lt;td&gt;Yes, self-managed&lt;/td&gt;
&lt;td&gt;Elastic License&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Grafana Loki&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Write + Process + Retain GB&lt;/td&gt;
&lt;td&gt;$0 self-host, Cloud free 50 GB&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;AGPL-3.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OpenSearch&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Infrastructure only&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Apache-2.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Graylog&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Infrastructure only&lt;/td&gt;
&lt;td&gt;$0 Open edition&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;SSPL v1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;VictoriaLogs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Infrastructure only&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Apache-2.0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Full per-vendor pricing lines, including Better Stack's plan ladder and Grafana Cloud's three meters, are in the &lt;a href="https://devtoollab.com/blog/best-log-management-tools" rel="noopener noreferrer"&gt;original article&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Five Checks Before You Commit
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Measure your average log line.&lt;/strong&gt; Pipe a day of production output through &lt;code&gt;wc -c&lt;/code&gt;, divide by line count. Every per-event price above moves inversely with that one number, and most people guess it wrong by 2x.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Split what you search from what you keep.&lt;/strong&gt; What share of your logs gets queried during an actual incident? Under a fifth, and an ingest-cheap, index-selective model wins. That ratio decides more of your bill than the vendor choice does.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test the query you run at 2am&lt;/strong&gt;, not a benchmark. If your reflex is grepping unstructured stack traces for a substring, Loki's label model fights you no matter how good the price looks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check the license before the trial, not after.&lt;/strong&gt; SSPL and the Elastic License are not OSI-approved, and AGPL-3.0 stops some legal teams cold. Finding this out in week three of a migration is expensive.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ship through OpenTelemetry whoever wins.&lt;/strong&gt; A collector in front of the backend makes the next migration a config change.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Two things make step 1 and step 5 concrete: the &lt;a href="https://devtoollab.com/tools/grok-pattern-tester" rel="noopener noreferrer"&gt;Grok Pattern Tester&lt;/a&gt; builds the patterns that turn unstructured lines into the fields every backend here bills you to index, and the &lt;a href="https://devtoollab.com/tools/otel-config-generator" rel="noopener noreferrer"&gt;OTel Config Generator&lt;/a&gt; writes the Collector YAML.&lt;/p&gt;

&lt;h2&gt;
  
  
  Picking One
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Already deep in Datadog for APM.&lt;/strong&gt; Stay, and move everything you do not query into Flex Logs. On this workload that is $1,360.72 down to $364.57 a month, no migration required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kubernetes with Prometheus and Grafana already running.&lt;/strong&gt; Loki. Self-hosted if you have platform capacity, Grafana Cloud if not, where the free 50 GB tier covers a small cluster outright.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full-text search over unstructured logs is the requirement.&lt;/strong&gt; OpenSearch self-hosted if you have the operations budget for it, Elastic Cloud Serverless if you would rather pay $0.07 per GB than tune a cluster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Small team, one bill, no platform work.&lt;/strong&gt; Better Stack. One number to defend beats four meters to model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Access control is the hard requirement.&lt;/strong&gt; Graylog, assuming SSPL survives legal review. If it does not and the hardware is modest, VictoriaLogs is the Apache-2.0 fallback.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Log tools did not get cheaper in 2026. The cost of full-text indexing got explicit enough to shop around, which is a different thing. Datadog's Flex tier, Elastic's serverless retention pricing and Loki's label-only index are three implementations of one argument: stop indexing what you will never search.&lt;/p&gt;

&lt;p&gt;Before the next renewal, get one number. What percentage of the logs you paid to index last quarter did anyone actually query? If nobody in the room can answer, that silence is your negotiating position.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://devtoollab.com/blog/best-log-management-tools" rel="noopener noreferrer"&gt;Best Log Management Tools in 2026: Costs&lt;/a&gt; - the original, longer article on DevToolLab&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.datadoghq.com/product/log-management/" rel="noopener noreferrer"&gt;Datadog Log Management&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://betterstack.com/logs" rel="noopener noreferrer"&gt;Better Stack Logs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.elastic.co/observability/log-monitoring" rel="noopener noreferrer"&gt;Elastic log monitoring&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://grafana.com/oss/loki/" rel="noopener noreferrer"&gt;Grafana Loki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://opensearch.org/" rel="noopener noreferrer"&gt;OpenSearch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://graylog.org/" rel="noopener noreferrer"&gt;Graylog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.victoriametrics.com/victorialogs/" rel="noopener noreferrer"&gt;VictoriaLogs documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>opensource</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Stripe and Adyen Just Bought the Usage-Based Billing Market</title>
      <dc:creator>Moksh Gupta</dc:creator>
      <pubDate>Tue, 22 Sep 2026 17:53:38 +0000</pubDate>
      <link>https://dev.to/moksh/stripe-and-adyen-just-bought-the-usage-based-billing-market-4a5d</link>
      <guid>https://dev.to/moksh/stripe-and-adyen-just-bought-the-usage-based-billing-market-4a5d</guid>
      <description>&lt;p&gt;If your product charges for a stream of events instead of a flat seat price, tokens in and out, agent runs, GPU seconds, you need a meter that survives a customer disputing the invoice: dedupe the events, aggregate them into a period, price them against the contract. I went looking for who still builds that independently and found the market had consolidated hard in the last year. &lt;a href="https://devtoollab.com/blog/best-usage-based-billing-platforms" rel="noopener noreferrer"&gt;I wrote a longer version of this comparison on DevToolLab&lt;/a&gt;, with the full pricing script and a screenshot of every dashboard; this is the short version.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Independent Shortlist Isn't Independent Anymore
&lt;/h2&gt;

&lt;p&gt;In ten months, all three vendors most comparison posts point to got bought. Kong announced it was acquiring OpenMeter on September 3, 2025. Stripe closed its purchase of Metronome on January 14, 2026, for an undisclosed price that reporting puts near $1 billion. Adyen agreed to pay $335 million for Orb on June 11, 2026, closing July 1 and folding it in as an "indirect wholly owned subsidiary" under an incubator model. Orb's own homepage now reads "an adyen company."&lt;/p&gt;

&lt;p&gt;A Metronome-run survey from January 2025 found 85% of 100 surveyed SaaS companies had already adopted usage-based pricing, so the timing tracks. Worth noting the survey came from a vendor selling the thing it measured, but the acquisitions back up the trend either way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Math: Percentage of Revenue vs a Fixed Bill
&lt;/h2&gt;

&lt;p&gt;Only two platforms in this space publish a price without a sales call: Stripe Billing at 0.7% of billing volume, and Flexprice, whose top self-serve tier is $1,000 a month. Everything else routes to Contact Sales.&lt;/p&gt;

&lt;p&gt;Run that 0.7% against a self-hosted budget and the crossover point is concrete. At $50,000 a month in billing volume, 0.7% is $350, cheaper than any engineer's time. But if running something like Lago or Kill Bill yourself costs $3,000 a month in infrastructure and attention, the percentage fee overtakes that around $429,000 a month in billing volume, roughly a $5.1M annual run rate. Below that line, pay the fee. Above it, the math flips toward self-hosting. &lt;a href="https://devtoollab.com/blog/best-usage-based-billing-platforms" rel="noopener noreferrer"&gt;The original post&lt;/a&gt; has the runnable script behind this table if you want to plug in your own volume and infra budget instead of these three examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Six Platforms, Verified This Month
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk4zo1qv5sj3x6rqhqdo8.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk4zo1qv5sj3x6rqhqdo8.webp" alt="Stripe Billing pricing page showing 0.7% of billing volume, pay as you go" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stripe Billing&lt;/strong&gt; charges 0.7% of billing volume, pay as you go, with up to 100 million metering events a month included. Anything past basic metering, multidimensional rates, negotiated contracts, routes to a Contact Metronome button, since that is exactly where Metronome landed after the acquisition.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbtcdoqoobvhz31vwz3w1.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbtcdoqoobvhz31vwz3w1.webp" alt="Orb homepage reading " width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Orb&lt;/strong&gt;, now under Adyen, is the pick for genuinely complicated pricing: hybrid plans, matrix rates, mid-period recomputation when a contract changes. Customers include Vercel, Replit, Supabase and LaunchDarkly, and ingestion is stress-tested to 250,000 events a second. There's no published price; it's billings plus events plus a platform fee, quote only.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh3ztuorw6ho7edcb46c0.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh3ztuorw6ho7edcb46c0.webp" alt="Lago dashboard showing AI token usage split into input, output and cached bars" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lago&lt;/strong&gt; is the open-source option with the most AI-billing polish: AGPL-3.0, 10,593 GitHub stars, v1.53.0 shipped September 8, 2026. Free to self-host; Premium (prepaid credits, entitlements, customer portal) is quote-only, and AGPL is a hard no for some legal teams.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Flexprice&lt;/strong&gt; is the rare open-source vendor with a real public price ladder: free up to 100,000 events a month, $500/month for 1 million events, $1,000/month for 5 million events and up to $1.2M in cumulative billing. AGPL-3.0, 6,201 stars, v2.1.31. Those ceilings are low for a real token-metered workload, and plans gate on cumulative rather than monthly billing, so once an account crosses a threshold it stays across it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OpenMeter&lt;/strong&gt;, an Apache-2.0 project now owned by Kong, is a metering layer rather than a full billing suite: 2,331 stars, still pre-1.0 at v1.0.0-beta.233. The managed path is now Kong Konnect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kill Bill&lt;/strong&gt; is the oldest option here and argues hardest against paying a percentage forever: fixed cost, self-run, Apache-2.0, 5,753 stars, 15+ years in production and 100,000+ subscriptions claimed. It is also a Java platform with a plugin architecture, and the heaviest operational lift of the six.&lt;/p&gt;

&lt;h2&gt;
  
  
  Picking One Without Migrating Twice
&lt;/h2&gt;

&lt;p&gt;Run the math on your own volume before reading another pricing page. Under roughly $200,000 a month in billing volume, Stripe's 0.7% usually beats the engineering cost of running your own meter. Above it, count events rather than revenue, since event volume is what actually breaks self-serve tiers. A product generating 40 million events a month is outside every self-serve plan here regardless of vendor.&lt;/p&gt;

&lt;p&gt;If you already know you need open source, the license split matters more than the feature list: Lago and Flexprice are AGPL-3.0, OpenMeter and Kill Bill are Apache-2.0. And if you are leaning toward Orb, get the multi-PSP commitment from Adyen in writing before migrating. The incubator model is explicitly described as a first phase, not a permanent structure.&lt;/p&gt;

&lt;p&gt;One practical note whichever you pick: idempotency keys are what stop a replayed usage event from being billed twice, and a &lt;a href="https://devtoollab.com/tools/uuid-generator" rel="noopener noreferrer"&gt;UUID generator&lt;/a&gt; is a fast way to mint test ones while you build the ingestion path. And if you are trying to work out what a 0.7% revenue share actually leaves you per customer against a flat monthly fee, running the numbers through a &lt;a href="https://devtoollab.com/tools/margin-calculator" rel="noopener noreferrer"&gt;margin calculator&lt;/a&gt; makes the comparison concrete before you commit to either model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;2026 changed ownership, not capability. Two payments companies and an API gateway company bought their way into metering inside ten months, and what is left independent is mostly open source: Lago, Flexprice, OpenMeter and Kill Bill, all usable, all with real tradeoffs. The question worth asking at renewal time is whether your billing cost is a percentage that keeps growing with your revenue, or a number you control.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://devtoollab.com/blog/best-usage-based-billing-platforms" rel="noopener noreferrer"&gt;Best Usage-Based Billing Platforms 2026, DevToolLab&lt;/a&gt; - the full price simulation script, six dashboard screenshots and the side-by-side license and pricing table&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stripe.com/billing" rel="noopener noreferrer"&gt;Stripe Billing pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.withorb.com/" rel="noopener noreferrer"&gt;Orb&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.getlago.com/" rel="noopener noreferrer"&gt;Lago&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://flexprice.io/" rel="noopener noreferrer"&gt;Flexprice&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://openmeter.io/" rel="noopener noreferrer"&gt;OpenMeter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://killbill.io/" rel="noopener noreferrer"&gt;Kill Bill&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>opensource</category>
      <category>devops</category>
      <category>ai</category>
    </item>
    <item>
      <title>What DAST Tools Actually Cost in 2026: ZAP, Nuclei, Burp, StackHawk, Detectify</title>
      <dc:creator>Moksh Gupta</dc:creator>
      <pubDate>Mon, 21 Sep 2026 18:10:07 +0000</pubDate>
      <link>https://dev.to/moksh/what-dast-tools-actually-cost-in-2026-zap-nuclei-burp-stackhawk-detectify-31kc</link>
      <guid>https://dev.to/moksh/what-dast-tools-actually-cost-in-2026-zap-nuclei-burp-stackhawk-detectify-31kc</guid>
      <description>&lt;p&gt;Static analysis can tell you a SQL query is built with string concatenation. It cannot tell you that staging is terminating TLS and forwarding plain HTTP to the app server, or that an admin route survived a refactor and is still reachable with no auth check in front of it. Catching that class of bug means throwing real requests at a running deployment, which is the whole point of dynamic application security testing (DAST).&lt;/p&gt;

&lt;p&gt;I went through six DAST tools and priced them off their own current pages rather than trusting last year's numbers anyone else might be quoting. &lt;a href="https://devtoollab.com/blog/best-dast-tools" rel="noopener noreferrer"&gt;I wrote the full breakdown on DevToolLab&lt;/a&gt; with screenshots of every pricing page; this is the condensed version with the numbers that matter most.&lt;/p&gt;

&lt;h2&gt;
  
  
  The price spread is enormous
&lt;/h2&gt;

&lt;p&gt;Burp Suite Professional: $499 per user for a one-year subscription. StackHawk's Wingman tier: $10 per user per month. ZAP, Nuclei and Wapiti: $0, licensed Apache-2.0, MIT and GPL-2.0 respectively. Detectify publishes a full ladder, but in euros, from a €0 starter tier up to €15,000/year for Enterprise. All of that was pulled straight from vendor pages on September 21, 2026.&lt;/p&gt;

&lt;p&gt;One correction that keeps getting missed in roundups: &lt;strong&gt;ZAP is not an OWASP project anymore.&lt;/strong&gt; ZAP's own blog carries a banner stating it's "now supported by Checkmarx and is not part of any foundation." If a post you're reading still calls it "OWASP ZAP," it's working from stale information.&lt;/p&gt;

&lt;p&gt;On adoption, there's no clean industry survey for this category the way CNCF runs one for Kubernetes, so GitHub stars are the least-bad public signal available: Nuclei sits at 31,395, ZAP at 15,797, Nikto at 10,735, Wapiti at 1,864 (checked the same day). Nuclei is also the most actively committed-to of the four.&lt;/p&gt;

&lt;h2&gt;
  
  
  Doing the per-seat math
&lt;/h2&gt;

&lt;p&gt;Per-seat pricing and flat platform fees cross over at a team size most comparisons skip entirely. Running the numbers with each vendor's published rate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tool                           1 dev     5 dev    20 dev    50 dev
------------------------------------------------------------------
Burp Suite Professional         $499    $2,495    $9,980   $24,950
StackHawk Wingman               $120      $600    $2,400    $6,000
ZAP / Nuclei / Wapiti             $0        $0        $0        $0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Burp runs about 4.2x StackHawk per seat, and a 20-developer team pays roughly $7,580/year more choosing Burp over StackHawk at list price. But the license total isn't the number that should drive the decision. A scanner that hands you 400 findings on a mid-sized Rails app, 380 of which are the same reflected parameter reported repeatedly, costs an engineer a full day of triage. That's the real reason free tools aren't automatically the cheap option; see the &lt;a href="https://devtoollab.com/blog/best-dast-tools" rel="noopener noreferrer"&gt;DevToolLab post&lt;/a&gt; for the full walkthrough of that tradeoff.&lt;/p&gt;

&lt;h2&gt;
  
  
  The tools, briefly
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.zaproxy.org/" rel="noopener noreferrer"&gt;ZAP&lt;/a&gt;&lt;/strong&gt; (Zed Attack Proxy) is the default free pick, Apache 2.0, version 2.17.0 (Dec 2025), still getting commits days before this was written. It runs as a proxy, a headless scanner, or a CI-driven daemon via its Automation Framework, and the add-on marketplace covers a lot of ground commercial tools charge for, including auth handling and OpenAPI import. The catch: default active scans are noisy against modern SPAs, and tuning it to a trustworthy signal is a real project, not an afternoon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/projectdiscovery/nuclei" rel="noopener noreferrer"&gt;Nuclei&lt;/a&gt;&lt;/strong&gt; isn't a crawler and shouldn't be compared to ZAP head-to-head. It's a template engine, MIT licensed, 31,395 stars, version 3.11.1 (Aug 2026): point it at a target with a YAML template describing a request and a matcher, and it tells you if the condition holds. That makes it the fastest way to sweep many hosts for one specific CVE the morning it drops, but it won't discover your app's forms or parameters on its own.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://wapiti-scanner.github.io/" rel="noopener noreferrer"&gt;Wapiti&lt;/a&gt;&lt;/strong&gt; is the readable black-box option, GPL-2.0, 1,864 stars, version 3.3.2 tagged Aug 2026 (its own site still lists 3.3.1 as current, so trust the release tag). It crawls a live app, collects inputs, and fuzzes them for SQL/XPath/LDAP injection, XSS, file disclosure, command execution, XXE and CRLF injection. No commercial support and a much smaller contributor base than ZAP is the tradeoff.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://portswigger.net/burp/pro" rel="noopener noreferrer"&gt;Burp Suite Professional&lt;/a&gt;&lt;/strong&gt; is priced for a human tester, $499/user/year. Repeater, Intruder and the manual proxy workflow are the actual product; the automated scanner is good but not the reason people buy it. It's a desktop app for one person, not CI infrastructure - PortSwigger sells a separate, sales-quoted product for pipeline scanning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.stackhawk.com/pricing/" rel="noopener noreferrer"&gt;StackHawk&lt;/a&gt;&lt;/strong&gt; has pivoted hard into the AI-coding-agent workflow. Wingman is $10/user/month, unlimited apps, 50 agentic scans per user per month, after a 14-day trial. The pitch is the scanner runs beside Claude Code, Cursor or Copilot so findings surface while the developer still remembers the feature. The 50-scan cap is the thing to watch if your CI config is chatty.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://detectify.com/pricing" rel="noopener noreferrer"&gt;Detectify&lt;/a&gt;&lt;/strong&gt; is the rare vendor that publishes a real ladder: €0 (Starter, up to 5 users), €2,500 (Standard), €5,000 (Professional), €15,000 (Enterprise) - all annual platform fees, all in euros. It leans on a Crowdsource network of external researchers for detection modules rather than an in-house rule set alone. The platform fee is a floor: API and Apex scanning cost extra per target, and PCI ASV scanning is a separate €500/year.&lt;/p&gt;

&lt;h2&gt;
  
  
  Picking one without buying twice
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Confirm you actually need DAST this quarter - if there's no SAST, no dependency scanning and no secrets detection yet, those find more per hour of setup on an unscanned codebase.&lt;/li&gt;
&lt;li&gt;Run ZAP against staging before spending anything. It costs an afternoon and tells you your real finding volume - 12 findings and 900 findings are different buying decisions.&lt;/li&gt;
&lt;li&gt;Price the triage time, not just the license. Estimate minutes per finding from step 2 and weigh that against $499/seat; for most teams, engineer time is the bigger line item.&lt;/li&gt;
&lt;li&gt;Decide whether you need authenticated scanning - anonymous-only coverage misses most real business logic, and this is where free tools cost the most setup time.&lt;/li&gt;
&lt;li&gt;Match the pricing unit to your shape: per-seat punishes large teams with few apps, per-application/platform fees punish small teams running many services.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you're already carrying a DAST finding into remediation, a couple of DevToolLab's utilities save the rescan round-trip: the &lt;a href="https://devtoollab.com/tools/security-headers-checker" rel="noopener noreferrer"&gt;Security Headers Checker&lt;/a&gt; confirms a missing CSP or HSTS header without waiting on a full scan, and the &lt;a href="https://devtoollab.com/tools/ssl-certificate-checker" rel="noopener noreferrer"&gt;SSL Certificate Checker&lt;/a&gt; rules out a TLS chain problem before you chase a false positive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bottom line
&lt;/h2&gt;

&lt;p&gt;The real story this year is that the cheap commercial tier got genuinely cheap - StackHawk at $120/developer/year is close enough to free that self-hosting ZAP purely to dodge a bill is worth reconsidering against your actual triage hours. Before renewing anything, ask how many findings from last quarter's scans an engineer actually acted on. Under ten, and you're paying for scan volume nobody's using - the fix is better tuning, not a bigger plan.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devtoollab.com/blog/best-dast-tools" rel="noopener noreferrer"&gt;Best DAST Tools in 2026: Prices Compared - the original article on DevToolLab&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.zaproxy.org/" rel="noopener noreferrer"&gt;ZAP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://portswigger.net/burp/pro" rel="noopener noreferrer"&gt;Burp Suite Professional pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.stackhawk.com/pricing/" rel="noopener noreferrer"&gt;StackHawk pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://detectify.com/pricing" rel="noopener noreferrer"&gt;Detectify pricing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>security</category>
      <category>devops</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>Six API Gateways, Priced on the Same Month of Traffic</title>
      <dc:creator>Moksh Gupta</dc:creator>
      <pubDate>Mon, 21 Sep 2026 03:22:25 +0000</pubDate>
      <link>https://dev.to/moksh/six-api-gateways-priced-on-the-same-month-of-traffic-4i3l</link>
      <guid>https://dev.to/moksh/six-api-gateways-priced-on-the-same-month-of-traffic-4i3l</guid>
      <description>&lt;p&gt;Nobody sets out to adopt an API gateway. You add TLS termination, then a token check, then per-customer rate limits, and at some point the thing in front of your services has become a product decision you never made deliberately.&lt;/p&gt;

&lt;p&gt;So I stopped reading feature matrices and priced one fixed workload against every vendor's published rates instead. The short version: 50 million requests a month lands anywhere between $63.50 and $430 depending purely on which billing model you picked, and half the products here will not tell you a price at all. I published the full comparison, including the per-gateway detail, as &lt;a href="https://devtoollab.com/blog/best-api-gateways" rel="noopener noreferrer"&gt;Best API Gateways in 2026 on DevToolLab&lt;/a&gt;. This is the condensed pass.&lt;/p&gt;

&lt;p&gt;Everything below was read off each vendor's own pricing page or release feed on September 20, 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who Actually Runs One
&lt;/h2&gt;

&lt;p&gt;Gateways are not a niche. CNCF and SlashData's State of Cloud Native Development report, published November 11, 2025, found API gateways to be the single most adopted cloud native technology among backend developers at 50 percent, with microservices behind them at 46 percent. The same report counted 15.6 million cloud native developers.&lt;/p&gt;

&lt;p&gt;Repository attention lines up roughly with that. On September 20, 2026 Traefik sat at 64,904 GitHub stars, Kong at 44,157, Apache APISIX at 17,147, Tyk at 10,823, and KrakenD Community Edition at 2,684. Stars are not production traffic, but all five shipped a release in the preceding quarter, which is more than you can say for a lot of infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pricing One Month, Four Ways
&lt;/h2&gt;

&lt;p&gt;Tier tables compare tiers. They do not compare bills. So here is a script that prices a single workload against published rates: 50 million requests, 3 KB responses, eight services, one control plane, us-east-1. It prices the vendor invoice only, which is why the self-hosted options read $0 and still cost you compute and an on-call rotation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// price-gateways.mjs - rates from each vendor's pricing page, September 20, 2026&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reqs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="nx"&gt;_000_000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;M&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;reqs&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;_000_000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;egressGB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reqs&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;_000_000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;services&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;controlPlanes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// AWS: HTTP $1.00/M to 300M then $0.90/M; REST $3.50/M to 333M then $2.80/M; egress $0.09/GB&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;awsHttp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;M&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;M&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.9&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;egressGB&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.09&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;awsRest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;M&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;333&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;3.5&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;M&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;333&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;2.8&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;egressGB&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.09&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// API7 Cloud: $2 per 1M calls + $250 per gateway group + $10 per service&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;api7&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;M&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;controlPlanes&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;250&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;services&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Kong Konnect Plus serverless: $25 per control plane; 2 APIs included,&lt;/span&gt;
&lt;span class="c1"&gt;// then $20/mo for the first 10 total APIs and $10/mo for each extra.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;billable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;services&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;kong&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;controlPlanes&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;billable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;billable&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;M&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;M requests/month, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;egressGB&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; GB egress`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AWS HTTP API&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;awsHttp&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AWS REST API&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;awsRest&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                      &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;API7 Cloud&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;api7&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Kong Konnect Plus&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;kong&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;padStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it at the baseline, then at ten times the traffic, and the ordering flips:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ node price-gateways.mjs 50000000
AWS HTTP API         $   63.50
AWS REST API         $  188.50
API7 Cloud           $  430.00
Kong Konnect Plus    $  145.00

$ node price-gateways.mjs 500000000
AWS HTTP API         $  615.00
AWS REST API         $ 1768.10
API7 Cloud           $ 1330.00
Kong Konnect Plus    $  145.00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kong Konnect starts out 2.3 times pricier than an AWS HTTP API and ends up under a quarter of it, because Konnect charges per control plane and per published API while AWS charges per request. Whether your invoice tracks your traffic or your org chart matters far more than the headline rate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kong Gateway
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnkfx9nd849fb1570snvh.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnkfx9nd849fb1570snvh.webp" alt="Kong Gateway product page headlined " width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Built on NGINX and OpenResty, and the plugin catalog is the reason it keeps winning evaluations. It runs either against PostgreSQL or in DB-less mode, which Kong documents as running "without a database using only in-memory storage for entities" from a declarative YAML or JSON file. That second mode is what makes it workable in a GitOps pipeline.&lt;/p&gt;

&lt;p&gt;The catch is that Konnect's bill follows environments and teams rather than load, so staging and preview control planes are line items. Apache 2.0, v3.9.3 as of June 17, 2026. Konnect starts at $25 a month per serverless control plane, $200 hybrid, $500 dedicated plus $0.15 per GB.&lt;/p&gt;

&lt;h2&gt;
  
  
  Traefik
&lt;/h2&gt;

&lt;p&gt;Traefik Proxy is Go, and its pitch is that it writes its own config: label a container or apply an Ingress and the route appears, with Let's Encrypt handled for you. HTTP/2, HTTP/3, TCP, UDP and gRPC are all in the open source build, as are OpenTelemetry traces, metrics and logs.&lt;/p&gt;

&lt;p&gt;What you cannot get is a number. Both Traefik Hub tiers swap the price for a "Get Pricing" button, and the WAF, distributed rate limiting and OIDC live behind the first of them. MIT, v3.7.13 as of September 4, 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  Apache APISIX
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flb90t6tjtksh1d9gt4zz.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flb90t6tjtksh1d9gt4zz.webp" alt="Apache APISIX homepage headlined " width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An Apache Software Foundation top-level project that its README describes as built "on top of NGINX and etcd." Using etcd rather than a relational database is the real differentiator: plugins and routes hot-reload across the fleet with nothing to restart and no database in the request path.&lt;/p&gt;

&lt;p&gt;The bill for that is operational. You are now running a consensus store, and etcd is usually the first thing to wake you up. Its homepage advertises 100+ plugins, about 18,000 QPS per core and 0.2 ms added latency, all vendor-measured. Apache 2.0, 3.18.0 as of August 20, 2026, with commercial support via API7 at $2 per million calls plus $250 per gateway group and $10 per service monthly.&lt;/p&gt;

&lt;h2&gt;
  
  
  KrakenD
&lt;/h2&gt;

&lt;p&gt;KrakenD describes itself as "a stateless, distributed, high-performance API Gateway," and it means the stateless part literally: one Go binary, one config file read at boot, no database, no config store. Nodes are immutable and rollbacks are just the previous artifact. API composition is the standout feature, fanning one client request across several backends and merging the response, which deletes an entire backend-for-frontend tier.&lt;/p&gt;

&lt;p&gt;The tradeoff is that nothing changes at runtime, so every config edit ships as a deploy. Its own feature matrix marks 71 rows "Not included in Community," service-level rate limiting among them, though endpoint-level rate limiting ships in the free edition. Apache 2.0, Community Edition v2.13.11 as of September 8, 2026, Enterprise priced on request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tyk
&lt;/h2&gt;

&lt;p&gt;Tyk has spent two years turning into a control plane for things that are not REST. Native GraphQL was the original hook, and it now ships distinct proxies for Kafka and async streams, MCP tools and registries, and LLM traffic with prompt and cost controls. If a gateway has to sit in front of an agent runtime as well as an API, nothing else here covers as much surface.&lt;/p&gt;

&lt;p&gt;Read the license before you commit. The core is MPL 2.0 but the &lt;code&gt;ee&lt;/code&gt; directory carries a separate commercial license, so the open source Tyk and the Tyk you trialled may differ. Prices are quoted on request and the free Cloud trial runs 48 hours. 10,823 stars, v5.14.0 as of July 7, 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  Amazon API Gateway
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq1nvsupi7jvqw7nxlr53.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq1nvsupi7jvqw7nxlr53.webp" alt="Amazon API Gateway product page headlined " width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If your compute is already Lambda, this is the default and the integration work you skip is worth real money. HTTP APIs are the cheaper of its two REST-shaped products, and the newer Portals feature gives you an AWS-native developer portal without adding a vendor.&lt;/p&gt;

&lt;p&gt;It never gets cheaper though. There is no flat tier to graduate onto, so the invoice is a straight line through your traffic graph, and REST APIs cost three and a half times HTTP APIs for largely overlapping features. HTTP APIs run $1.00 per million to 300 million then $0.90, REST APIs $3.50 per million to 333 million then $2.80, with $0.09 per GB egress and a 12-month free tier of a million calls a month.&lt;/p&gt;

&lt;h2&gt;
  
  
  Picking One Without Migrating Twice
&lt;/h2&gt;

&lt;p&gt;Price your actual last month rather than a tier, because the crossover between metered and flat-rate billing depends entirely on your numbers. Decide whether config changes are allowed to be deploys, since KrakenD insists they are and Kong, APISIX and Tyk hand you an admin API instead. Count the stateful components you are signing up for: PostgreSQL for Kong in traditional mode, etcd for APISIX, nothing for KrakenD or open source Traefik.&lt;/p&gt;

&lt;p&gt;Then check the paywall before you prototype, not after. Build the proof of concept on the free edition and confirm rate limiting, OIDC and the developer portal are in the tier you actually plan to buy. And get anything "quoted on request" in writing, renewal uplift included, while you still have leverage.&lt;/p&gt;

&lt;p&gt;If you want the per-persona verdicts and the full side-by-side table, they are in &lt;a href="https://devtoollab.com/blog/best-api-gateways" rel="noopener noreferrer"&gt;the original article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Two things worth having open while you test: the &lt;a href="https://devtoollab.com/tools/rate-limit-header-analyzer" rel="noopener noreferrer"&gt;Rate Limit Header Analyzer&lt;/a&gt; for checking that the policy you configured is the one clients actually receive, and the &lt;a href="https://devtoollab.com/tools/cors-header-generator" rel="noopener noreferrer"&gt;CORS Header Generator&lt;/a&gt; for building the &lt;code&gt;Access-Control-Allow-*&lt;/code&gt; set once at the edge instead of in every service behind it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Changed This Year
&lt;/h2&gt;

&lt;p&gt;Gateways stopped being only about REST. Four of these six now market AI, MCP or LLM proxying, and both Traefik and APISIX sell an AI gateway as its own product. That is where the roadmaps are heading, and it is also where the license boundaries are being redrawn.&lt;/p&gt;

&lt;p&gt;The question to ask at renewal is not which has more plugins. It is whether the bill scales with your traffic or with your team. Metered pricing punishes growth; per-control-plane pricing punishes having lots of environments. Model both against next year.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devtoollab.com/blog/best-api-gateways" rel="noopener noreferrer"&gt;Original article on DevToolLab&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://konghq.com/products/kong-gateway" rel="noopener noreferrer"&gt;Kong Gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://traefik.io/traefik/" rel="noopener noreferrer"&gt;Traefik Proxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://apisix.apache.org/" rel="noopener noreferrer"&gt;Apache APISIX&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.krakend.io/" rel="noopener noreferrer"&gt;KrakenD&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tyk.io/" rel="noopener noreferrer"&gt;Tyk&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/api-gateway/" rel="noopener noreferrer"&gt;Amazon API Gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cncf.io/announcements/2025/11/11/cncf-and-slashdata-survey-finds-cloud-native-ecosystem-surges-to-15-6m-developers/" rel="noopener noreferrer"&gt;CNCF and SlashData, State of Cloud Native Development&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>opensource</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Your One Dependency Is Actually 67 Packages</title>
      <dc:creator>Moksh Gupta</dc:creator>
      <pubDate>Sat, 19 Sep 2026 17:56:22 +0000</pubDate>
      <link>https://dev.to/moksh/your-one-dependency-is-actually-67-packages-38jf</link>
      <guid>https://dev.to/moksh/your-one-dependency-is-actually-67-packages-38jf</guid>
      <description>&lt;p&gt;Nobody audits a lockfile. You pick a handful of libraries deliberately, and everything underneath them shows up because a resolver said so, gets refreshed by a bot, and is never looked at again. The question supply chain security answers is what is actually down there, and whether it arrived the way you think it did.&lt;/p&gt;

&lt;p&gt;I put a number on the first half of that on September 19, 2026. A fresh project with exactly one dependency, &lt;code&gt;express@5.1.0&lt;/code&gt;, produced a CycloneDX bill of materials containing &lt;strong&gt;67 components&lt;/strong&gt;. The same process against a production Next.js 15 app with 112 direct production dependencies returned &lt;strong&gt;762 library components&lt;/strong&gt;, so the tree is nearly seven times larger than the part anyone chose. The longer version of this writeup, with every version and price, is &lt;a href="https://devtoollab.com/blog/supply-chain-security-tools" rel="noopener noreferrer"&gt;on DevToolLab&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmr8ilia7o9zps1wme2au.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmr8ilia7o9zps1wme2au.webp" alt="Supply chain security tools banner" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reproduce the 67 in Under a Minute
&lt;/h2&gt;

&lt;p&gt;With Trivy 0.74.0 on your path, this is the whole thing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;sbom-demo &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;sbom-demo
npm init &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
npm &lt;span class="nb"&gt;install &lt;/span&gt;express@5.1.0 &lt;span class="nt"&gt;--package-lock-only&lt;/span&gt; &lt;span class="nt"&gt;--no-audit&lt;/span&gt; &lt;span class="nt"&gt;--no-fund&lt;/span&gt;
trivy fs &lt;span class="nt"&gt;--scanners&lt;/span&gt; vuln &lt;span class="nt"&gt;--format&lt;/span&gt; cyclonedx &lt;span class="nt"&gt;--output&lt;/span&gt; sbom.json package-lock.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Count what it wrote:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;bom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sbom.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CycloneDX spec : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;bom&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;specVersion&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;components     : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bom&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;components&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;vulnerabilities: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;vulnerabilities&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What came back on the day I ran it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CycloneDX spec : 1.7
components     : 67
vulnerabilities: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Zero vulnerabilities is the part worth reading carefully. It describes today, not next month, because disclosure almost always lands long after installation. The reason to keep the inventory is so that "are we affected" takes minutes rather than a week of grepping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three Jobs, Not One
&lt;/h2&gt;

&lt;p&gt;The phrase "supply chain security" bundles together three problems that need separate tools, and treating them as one is why these projects stall.&lt;/p&gt;

&lt;p&gt;Inventory means producing an SBOM listing every component in a build. Provenance means signing artifacts and attesting how they were produced, so a consumer can check the binary really came from the source it names. Detection means finding known vulnerabilities in the inventory, and separately catching packages that are malicious rather than just stale.&lt;/p&gt;

&lt;p&gt;A scanner says nothing about whether your pipeline was tampered with. A signature says nothing about whether the thing you signed is full of compromised code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Free Stack Covers All Three
&lt;/h2&gt;

&lt;p&gt;For inventory, Syft and Trivy both emit SPDX and CycloneDX and both carry an Apache 2.0 license. Syft, from Anchore, hit v1.52.0 on September 17, 2026 with 9,581 GitHub stars and does only cataloging, which makes it the cleaner pipeline component. Trivy, from Aqua Security, hit v0.74.0 on August 14, 2026 with 37,980 stars and folds scanning, misconfiguration checks and secret detection into the same binary. One tool in CI or one tool per job, that is the whole decision.&lt;/p&gt;

&lt;p&gt;For detection, Grype reached v0.119.0 on September 17, 2026 and reads a Syft SBOM directly. Google's OSV-Scanner reached v2.6.0 on September 14, 2026 and pulls from the OSV database, where records are keyed to exact affected version ranges per ecosystem instead of vendor CPE strings. That difference shows up as noticeably fewer false positives. Both are Apache 2.0, and running both is not unreasonable.&lt;/p&gt;

&lt;p&gt;For provenance, Sigstore's Cosign reached v3.1.3 on August 6, 2026. Its useful trick is keyless signing: short-lived certificates bound to an OIDC identity such as a GitHub Actions workflow, with the signature written to a public transparency log, so there is no long-lived private key for anyone to lose.&lt;/p&gt;

&lt;p&gt;One thing to check if you are reading older comparisons: &lt;strong&gt;SLSA v1.2 is the current approved specification&lt;/strong&gt; as of September 2026, and v1.1 is marked Retired. It adds a Source Track alongside the Build Track, which most published roundups predate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy77ojeu4oljpfhumpspn.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy77ojeu4oljpfhumpspn.webp" alt="The SLSA specification site showing Version 1.2 with status Approved and the Build Track, Source Track and Cross Track sections" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, storage. OWASP's Dependency-Track reached 5.1.0 on August 27, 2026 and ingests a CycloneDX SBOM from every build, then re-evaluates what it already holds as new advisories land. A CI scan answers "is this build clean right now". Dependency-Track answers "which of the forty services we shipped last quarter ship this package", which is the question an incident actually starts with, and one a folder of SBOM files cannot answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Paid Tools Are Selling
&lt;/h2&gt;

&lt;p&gt;Reachability analysis, malicious-package detection, hardened base images and a support contract. The &lt;a href="https://devtoollab.com/blog/supply-chain-security-tools" rel="noopener noreferrer"&gt;original article&lt;/a&gt; breaks the pricing down properly, but the shape is this.&lt;/p&gt;

&lt;p&gt;Snyk publishes per-seat pricing: Free at $0 per month, Team from $25 per month, and Ignite from $1,260 per year, all per contributing developer, with Enterprise quoted. Chainguard sells the opposite approach, shipping hardened images so you have fewer CVEs to triage rather than better triage. Up to five images are free, and its Catalog tier with 2,000-plus images starts at $19,000 for a team of 10, built in SLSA L3 infrastructure under a contractual CVE remediation SLA. Both checked on their own pricing pages on September 19, 2026.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvafycgtfy0gxczo94bmx.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvafycgtfy0gxczo94bmx.webp" alt="The Snyk plans page showing Free at $0 per month, Team at $25 per month and Ignite at $1,260 per year, each per contributing developer" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Socket is the third approach, judging a package by what its code actually does rather than matching it to a CVE list, which is the only one of the three that flags a malicious release on day zero. I could not verify its current pricing: socket.dev returned HTTP 403 to every non-browser client I tried, so I have left the number out rather than guess at it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side by Side
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Job&lt;/th&gt;
&lt;th&gt;License&lt;/th&gt;
&lt;th&gt;Version (Sep 19, 2026)&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Syft&lt;/td&gt;
&lt;td&gt;SBOM generation&lt;/td&gt;
&lt;td&gt;Apache 2.0&lt;/td&gt;
&lt;td&gt;v1.52.0&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trivy&lt;/td&gt;
&lt;td&gt;SBOM plus scanning&lt;/td&gt;
&lt;td&gt;Apache 2.0&lt;/td&gt;
&lt;td&gt;v0.74.0&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grype&lt;/td&gt;
&lt;td&gt;Vulnerability scanning&lt;/td&gt;
&lt;td&gt;Apache 2.0&lt;/td&gt;
&lt;td&gt;v0.119.0&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OSV-Scanner&lt;/td&gt;
&lt;td&gt;Vulnerability scanning&lt;/td&gt;
&lt;td&gt;Apache 2.0&lt;/td&gt;
&lt;td&gt;v2.6.0&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cosign&lt;/td&gt;
&lt;td&gt;Signing and attestation&lt;/td&gt;
&lt;td&gt;Apache 2.0&lt;/td&gt;
&lt;td&gt;v3.1.3&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dependency-Track&lt;/td&gt;
&lt;td&gt;SBOM management&lt;/td&gt;
&lt;td&gt;Apache 2.0&lt;/td&gt;
&lt;td&gt;5.1.0&lt;/td&gt;
&lt;td&gt;Free, self-hosted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Snyk&lt;/td&gt;
&lt;td&gt;Scanning plus reachability&lt;/td&gt;
&lt;td&gt;Commercial&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;$0 to $1,260/yr per developer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chainguard&lt;/td&gt;
&lt;td&gt;Hardened base images&lt;/td&gt;
&lt;td&gt;Commercial&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;5 images free; Catalog from $19,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Socket&lt;/td&gt;
&lt;td&gt;Malicious package detection&lt;/td&gt;
&lt;td&gt;Commercial&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;Not publicly verifiable&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Where to Start
&lt;/h2&gt;

&lt;p&gt;Run Trivy in CI. One binary, an SBOM and a vulnerability report, no purchase order. That is the honest answer for most teams, and if a customer is only asking for an SBOM then Syft alone finishes the job.&lt;/p&gt;

&lt;p&gt;Add Dependency-Track once you are running more than a handful of services, because per-build scanning stops answering the question you will actually be asked. Add Cosign and publish provenance if other people consume what you ship. Look at behavioral analysis if malicious packages rather than outdated ones are what worry you, since CVE matching structurally cannot catch those. Price Chainguard against the hours your team currently spends patching base images, not against zero.&lt;/p&gt;

&lt;p&gt;Two things worth having open while you do any of this: a &lt;a href="https://devtoollab.com/tools/sha256-file-checksum" rel="noopener noreferrer"&gt;SHA256 file checksum&lt;/a&gt; for confirming a release artifact matches the digest its project published, and &lt;a href="https://devtoollab.com/tools/npm-package-info" rel="noopener noreferrer"&gt;npm package info&lt;/a&gt; for looking at maintainers and release history before a package becomes one more node in the tree.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Everything load-bearing here is free and actively maintained. Syft, Trivy, Grype, OSV-Scanner, Cosign and Dependency-Track are all Apache 2.0 and all shipped a release within about five weeks of September 19, 2026. Between them you get an inventory, a scan, a signature and a history.&lt;/p&gt;

&lt;p&gt;Paid tools buy less noise, day-zero malicious detection, hardened images and someone to call. None of that is the first step. Generate one SBOM, look at how many packages you did not know you were shipping, and decide from that number.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://devtoollab.com/blog/supply-chain-security-tools" rel="noopener noreferrer"&gt;9 Supply Chain Security Tools in 2026&lt;/a&gt; - the original article, with the full pricing breakdown and methodology&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://slsa.dev/spec/v1.2/" rel="noopener noreferrer"&gt;SLSA specification v1.2&lt;/a&gt; - current approved version, Build and Source tracks&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/anchore/syft" rel="noopener noreferrer"&gt;Syft&lt;/a&gt; and &lt;a href="https://github.com/anchore/grype" rel="noopener noreferrer"&gt;Grype&lt;/a&gt; - Anchore&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/aquasecurity/trivy" rel="noopener noreferrer"&gt;Trivy&lt;/a&gt; - Aqua Security&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/sigstore/cosign" rel="noopener noreferrer"&gt;Cosign&lt;/a&gt; - Sigstore&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/google/osv-scanner" rel="noopener noreferrer"&gt;OSV-Scanner&lt;/a&gt; - Google&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/DependencyTrack/dependency-track" rel="noopener noreferrer"&gt;Dependency-Track&lt;/a&gt; - OWASP&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>security</category>
      <category>devops</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>Your RAG Chunker Cuts a Sentence in Half 98% of the Time</title>
      <dc:creator>Moksh Gupta</dc:creator>
      <pubDate>Sat, 19 Sep 2026 12:39:59 +0000</pubDate>
      <link>https://dev.to/moksh/your-rag-chunker-cuts-a-sentence-in-half-98-of-the-time-2cbm</link>
      <guid>https://dev.to/moksh/your-rag-chunker-cuts-a-sentence-in-half-98-of-the-time-2cbm</guid>
      <description>&lt;p&gt;When retrieval in a RAG pipeline comes back with the wrong passage, the first suspect is almost always the embedding model. Swap &lt;code&gt;text-embedding-3-small&lt;/code&gt; for something with a bigger benchmark number, re-index, measure again. That is usually the wrong knob. If the chunk you pulled back stops halfway through the sentence that contained the answer, the answer is not in your index at all, and no embedding model is going to reconstruct it.&lt;/p&gt;

&lt;p&gt;Chunking gets decided once, in a constructor argument, and then nobody looks at it again. So I looked at it: four strategies, one document (RFC 9562, the UUID specification, 114,629 characters), a 1,000-character target, and one metric that chunking libraries do not report. Plain fixed-size splitting landed a boundary mid-sentence &lt;strong&gt;98 percent&lt;/strong&gt; of the time. Paragraph-aware splitting managed &lt;strong&gt;zero&lt;/strong&gt;. The full write-up with the complete script is &lt;a href="https://devtoollab.com/blog/rag-chunking-strategies" rel="noopener noreferrer"&gt;on DevToolLab&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fobbti0dm0otj84e02eky.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fobbti0dm0otj84e02eky.webp" alt="RAG chunking strategies banner" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Four Ways to Cut a Document
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Fixed size&lt;/strong&gt; slices every N characters. Trivial to write, perfectly uniform output, and it has no idea what the text says.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fixed size with overlap&lt;/strong&gt; does the same thing, then copies the tail of each chunk onto the head of the next one, betting that whatever got severed will survive intact in at least one of the pair.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recursive&lt;/strong&gt; works down a ladder of separators, paragraph break first, then newline, then sentence, then space, and only drops to the next rung when a piece is still too big. Most frameworks ship this as the default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paragraph aware&lt;/strong&gt; treats a paragraph as atomic. It fills a chunk with whole paragraphs and opens a new one when the budget runs out.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Metric Nobody Reports
&lt;/h2&gt;

&lt;p&gt;Chunk size is not the interesting number. Boundary placement is. A cut that lands on a sentence terminator or a blank line costs you nothing, because both halves are still coherent units. A cut anywhere else takes one idea and turns it into two useless fragments.&lt;/p&gt;

&lt;p&gt;So the measurement is: collect every legal boundary in the document up front, then ask each strategy how many of its cuts missed. The test corpus is an RFC because RFCs have real paragraph structure and a plain-text canonical form, which makes them easy to fetch and hard to argue with.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F88ugvxz9y43gfqh8qn0b.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F88ugvxz9y43gfqh8qn0b.webp" alt="The RFC Editor page for RFC 9562, the Universally Unique IDentifiers specification, used here as the test corpus" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The scoring half is about ten lines of Node with no dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Every position where a sentence or a paragraph legitimately ends.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sentenceEnds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;matchAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;.!?&lt;/span&gt;&lt;span class="se"&gt;][&lt;/span&gt;&lt;span class="sr"&gt;"')&lt;/span&gt;&lt;span class="se"&gt;\]]?\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(?=[&lt;/span&gt;&lt;span class="sr"&gt;A-Z0-9&lt;/span&gt;&lt;span class="se"&gt;])&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;)].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;paragraphEnds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;matchAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\n\s&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;)].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SAFE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;sentenceEnds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;paragraphEnds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;// A chunker returns [start, end] pairs. Every start after the first is a cut it chose.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;midSentence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;SAFE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the strategy that scores zero is not complicated either, which is the uncomfortable part:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Never split a paragraph. Pack whole paragraphs until the budget is gone.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;byParagraph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cur&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;paragraphEnds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;SIZE&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;cur&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cur&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;cur&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cur&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;out&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://devtoollab.com/blog/rag-chunking-strategies" rel="noopener noreferrer"&gt;original article&lt;/a&gt; carries the whole runnable file, including the recursive splitter and the corpus cleanup that strips RFC page furniture.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Came Back
&lt;/h2&gt;

&lt;p&gt;Node 25.5.0, run September 14, 2026:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;document: RFC 9562, 114,629 chars, 616 sentences
target chunk size: 1000 chars (overlap 200 where used)

strategy           chunks  avg size   mid-sentence   mid-para  total chars
------------------------------------------------------------------------------
fixed size            115       997      112 (98%)        112      114,629
fixed + overlap       144       995      142 (99%)        142      143,229
recursive             147       780       15 (10%)         15      114,629
paragraph aware       132       868         0 (0%)          0      114,629
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;112 bad cuts out of 114 is not a tail case you can ignore, it is what the strategy does on every document that is not pre-chopped into 1,000-character pieces.&lt;/p&gt;

&lt;p&gt;The overlap row is the one worth staring at. It cuts mid-sentence at 99 percent, slightly worse than plain fixed size, because shifting the stride by 800 instead of 1,000 does nothing to align it with the prose. What overlap actually buys is a duplicate of the damaged region living inside the neighbor, and the bill for that shows up in the last column: &lt;strong&gt;143,229 characters embedded instead of 114,629&lt;/strong&gt;. That is 25 percent more vectors, 25 percent more storage, 25 percent more spend at every re-index, to paper over a boundary problem that recursive splitting removes for free.&lt;/p&gt;

&lt;p&gt;Recursive drops the bad-cut rate to 10 percent and costs nothing but uniformity: 147 chunks averaging 780 characters against fixed size's tidy 115 at 997.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where It Stops Being Free
&lt;/h2&gt;

&lt;p&gt;Structure-aware splitting produces uneven chunks, and that is a real tradeoff rather than a rounding error. A 200-character chunk and a 900-character chunk do not carry comparable specificity once embedded, so cosine similarity between them is not quite apples to apples, and short chunks can punch above their weight in a ranked list. Recursive sits in the middle of that tension, which is a decent explanation for why it is everyone's default.&lt;/p&gt;

&lt;p&gt;Paragraph-aware hitting exactly zero also depends on the corpus. RFC paragraphs happen to fit under a 1,000-character budget. Point it at a document with 3,000-character paragraphs and it either blows the budget or falls back to something else, so check your source before assuming the zero transfers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Five Things to Do With This
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Move off plain fixed size today.&lt;/strong&gt; Recursive is the same single config line and removes roughly 90 percent of the damage. For prose, there is no case where fixed size is the better pick.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Go paragraph-aware on structured text.&lt;/strong&gt; Specs, contracts, API docs, anything with genuine paragraph markup can reach zero mid-sentence cuts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treat overlap as a last resort, not a default.&lt;/strong&gt; Here it added 25 percent to the embedding bill and improved nothing. It earns its keep only when the text has no usable separators at all, like untimed transcripts or raw OCR.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Score boundaries, not sizes.&lt;/strong&gt; Every library will happily print its chunk length distribution. None of them tell you how many ideas got bisected, and that is the number correlated with retrieval quality.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Budget in tokens, not characters.&lt;/strong&gt; Roughly 250 English tokens fit in 1,000 characters, and far fewer in most other languages, so a character budget quietly shrinks your chunks the moment your corpus is not English.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Clean the Input First
&lt;/h2&gt;

&lt;p&gt;Half the boundary damage in real pipelines comes from garbage the chunker was never designed to see. Markdown link syntax and heading markers eat budget without carrying meaning, so run documents through &lt;a href="https://devtoollab.com/tools/markdown-to-text" rel="noopener noreferrer"&gt;Markdown to Text&lt;/a&gt; before embedding. Zero-width and non-breaking characters from PDF and web scrapes are worse, because they survive every normalization step and sit invisibly inside what should be a clean sentence boundary; &lt;a href="https://devtoollab.com/tools/invisible-character-remover" rel="noopener noreferrer"&gt;Invisible Character Remover&lt;/a&gt; strips them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The chunking default in most RAG stacks severs a sentence at nearly every boundary it creates, and the standard remedy for that, overlap, charges a 25 percent embedding tax while leaving the cut rate untouched. Switching to recursive splitting is a one-line change that eliminates most of the problem, and on structured documents paragraph-aware eliminates all of it. Before you spend another sprint tuning the retriever or shopping for a better embedding model, run the boundary count on one of your own documents. The number is usually embarrassing.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://devtoollab.com/blog/rag-chunking-strategies" rel="noopener noreferrer"&gt;RAG Chunking Strategies, Measured&lt;/a&gt; - the original article, with the complete script and full methodology&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.rfc-editor.org/rfc/rfc9562.txt" rel="noopener noreferrer"&gt;RFC 9562: Universally Unique IDentifiers&lt;/a&gt; - the test corpus&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://devtoollab.com/blog/best-rag-platforms-and-tools" rel="noopener noreferrer"&gt;Best RAG Platforms and Tools&lt;/a&gt; - what runs the pipeline once chunking is settled&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://devtoollab.com/blog/best-pdf-parsers-for-rag" rel="noopener noreferrer"&gt;Best PDF Parsers for RAG&lt;/a&gt; - the ingestion step where structure is preserved or lost&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://devtoollab.com/blog/how-llm-tokenization-works" rel="noopener noreferrer"&gt;How LLM Tokenization Actually Works&lt;/a&gt; - why characters and tokens are not interchangeable budgets&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Your OpenRouter Model Slug Is a Pool, Not a Deployment</title>
      <dc:creator>Moksh Gupta</dc:creator>
      <pubDate>Fri, 18 Sep 2026 19:00:37 +0000</pubDate>
      <link>https://dev.to/moksh/your-openrouter-model-slug-is-a-pool-not-a-deployment-24d3</link>
      <guid>https://dev.to/moksh/your-openrouter-model-slug-is-a-pool-not-a-deployment-24d3</guid>
      <description>&lt;p&gt;Moving from a vendor SDK to OpenRouter reads like a trivial migration. The request shape stays OpenAI-compatible, you change a base URL, and suddenly one key reaches hundreds of models. What the diff does not tell you is that the string you put in &lt;code&gt;model&lt;/code&gt; does not identify a machine. It identifies a pool of them.&lt;/p&gt;

&lt;p&gt;I pulled numbers off OpenRouter's public API on September 14, 2026 to see how wide that pool gets. For &lt;code&gt;deepseek/deepseek-v4-flash-0731&lt;/code&gt;, 28 separate providers answer to that one slug, and their input pricing runs from $0.04 to $0.44 per million tokens, a spread of &lt;strong&gt;11x&lt;/strong&gt;. For &lt;code&gt;qwen/qwen3.8-27b&lt;/code&gt;, 15 providers disagree about the context window by &lt;strong&gt;15.3x&lt;/strong&gt;: one advertises 66k, another claims 1,000k. The longer write-up with the full methodology is &lt;a href="https://devtoollab.com/blog/openrouter-provider-routing" rel="noopener noreferrer"&gt;on DevToolLab&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyfm5ehc144zb3tp3ixyf.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyfm5ehc144zb3tp3ixyf.webp" alt="OpenRouter provider routing banner" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Default Is Availability, Not Reproducibility
&lt;/h2&gt;

&lt;p&gt;OpenRouter does not hide this. Their provider routing docs state that requests are load balanced across the top providers by default, specifically to maximize uptime.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2f573bwskpx95lkeqsx4.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2f573bwskpx95lkeqsx4.webp" alt="The OpenRouter Provider Routing documentation page showing the provider object field table with order, allow_fallbacks, require_parameters, data_collection and zdr" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For uptime that is the right call. For anything you need to reproduce, it is a trap. Fire the same request twice sixty seconds apart and you can hit two different machines running two different quantizations with two different context ceilings at two different prices, with an identical payload and no code change between them. Open-weight models make this worse, because anyone with GPUs can join the pool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measuring It Yourself
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;/endpoints&lt;/code&gt; route is unauthenticated, so you can check any model without a key. Node 18 or later, nothing to install.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// or-variance.mjs - Node 18+, no deps, no API key needed&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MODELS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;z-ai/glm-5.2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;deepseek/deepseek-v4-flash-0731&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;z-ai/glm-5.3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;deepseek/deepseek-v4-pro-0813&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;moonshotai/kimi-k2.6&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;qwen/qwen3.8-27b&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;perM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;_000_000&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ratio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="kc"&gt;Infinity&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;MODELS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`https://openrouter.ai/api/v1/models/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/endpoints`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AbortSignal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;25000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`skip &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: HTTP &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;eps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endpoints&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;eps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inPrices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;eps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;perM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pricing&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;eps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;context_length&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;quants&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quantization&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;undeclared&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))]&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;eps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;supported_parameters&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="p"&gt;[]).&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tools&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;padStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt; providers  `&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="s2"&gt;`$&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;inPrices&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;inPrices&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;/M `&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="s2"&gt;`(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;ratio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;inPrices&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;inPrices&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;x)  `&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="s2"&gt;`ctx &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;k-&lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;k  `&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
      &lt;span class="s2"&gt;`tools &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;eps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;  quant: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;quants&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What came back that day:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;model                            prov         in $/M  spread           context  spread
--------------------------------------------------------------------------------------------
z-ai/glm-5.2                       33      0.49-2.31    4.7x        203k-1049k    5.2x
deepseek/deepseek-v4-flash-0731    28      0.04-0.44   11.0x        262k-1311k    5.0x
z-ai/glm-5.3                       27      0.92-2.10    2.3x        262k-1311k    5.0x
deepseek/deepseek-v4-pro-0813      21      0.66-1.65    2.5x       1000k-1049k    1.0x
moonshotai/kimi-k2.6               21      0.58-1.09    1.9x         256k-262k    1.0x
qwen/qwen3.8-27b                   15      0.15-0.45    3.0x         66k-1000k   15.3x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Which Spreads Actually Hurt
&lt;/h2&gt;

&lt;p&gt;Price is the one that looks scariest and matters least. OpenRouter sorts on price by default, so ordinary traffic settles near the floor of that 11x range. You feel it when you pin a provider for quality reasons and find out what quality costs.&lt;/p&gt;

&lt;p&gt;Context is where things break without telling you. If one host behind &lt;code&gt;qwen/qwen3.8-27b&lt;/code&gt; caps at 66k and another accepts 1,000k, then a 200k-token prompt is a coin flip. Worse, the failure surfaces as an intermittent API error, so you go hunting for a bug in your retry logic instead of your routing config.&lt;/p&gt;

&lt;p&gt;Quantization is declared rather than verified. Every model I checked had at least one provider reporting &lt;code&gt;unknown&lt;/code&gt;, and &lt;code&gt;moonshotai/kimi-k2.6&lt;/code&gt; alone spanned &lt;code&gt;int4&lt;/code&gt;, &lt;code&gt;fp4&lt;/code&gt;, &lt;code&gt;fp8&lt;/code&gt;, &lt;code&gt;bf16&lt;/code&gt; and &lt;code&gt;unknown&lt;/code&gt;. A 4-bit build and a bf16 build are not the same model in any sense that matters to output quality, but they share a slug.&lt;/p&gt;

&lt;p&gt;Capability varies too. On &lt;code&gt;qwen/qwen3.8-27b&lt;/code&gt;, 14 of 15 providers advertised tool support. The fifteenth did not. Route purely on price, land on that one, and your function calling breaks for reasons no amount of reading your own code will explain.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Part the Metadata Cannot Tell You
&lt;/h2&gt;

&lt;p&gt;Everything above is self-reported. Two providers can publish identical specs and still behave differently under real traffic, and no API call will surface that.&lt;/p&gt;

&lt;p&gt;Mohamed Moustafa's write-up, &lt;a href="https://mmoustafa.com/blog/so-you-want-to-use-openrouter/" rel="noopener noreferrer"&gt;So you want to use OpenRouter&lt;/a&gt;, is the best public account of this failure mode. Running a production assistant across OpenRouter, he found benchmark gaps between providers on one slug, hosts that accept image inputs then ignore them, reasoning-effort parameters silently dropped, tool calls returned as raw text instead of structured output, and 200 responses carrying empty bodies. Declared precision turns out to be a weak signal for actual quality. &lt;a href="https://devtoollab.com/blog/openrouter-provider-routing" rel="noopener noreferrer"&gt;The DevToolLab version of this post&lt;/a&gt; goes further into how his findings line up with the metadata.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pinning, in Six Fields
&lt;/h2&gt;

&lt;p&gt;The controls exist. They are just off by default. The &lt;code&gt;provider&lt;/code&gt; object accepts:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Default&lt;/th&gt;
&lt;th&gt;Effect&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;order&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;Provider slugs to try in sequence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;only&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;Restrict routing to these providers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ignore&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;Exclude these providers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;allow_fallbacks&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;true&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Permit fallback when the primary is down&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;require_parameters&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Route only to providers honoring every parameter sent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;quantizations&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;Limit to declared levels such as &lt;code&gt;fp8&lt;/code&gt; or &lt;code&gt;bf16&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;data_collection&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;"allow"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Exclude providers that may retain your data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;zdr&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;Restrict to zero data retention endpoints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;max_price&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;Cap price per million tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In practice:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Turn on &lt;code&gt;require_parameters: true&lt;/code&gt; before anything else. One boolean, and it eliminates every bug where a host quietly discards your tools or reasoning settings.&lt;/li&gt;
&lt;li&gt;Reach for &lt;code&gt;only&lt;/code&gt; when you mean only. &lt;code&gt;order&lt;/code&gt; still falls through to providers you did not list. A genuine hard pin is &lt;code&gt;order&lt;/code&gt; plus &lt;code&gt;allow_fallbacks: false&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Never pin to a single provider in production. Their incident becomes your incident. Use a tested shortlist instead.&lt;/li&gt;
&lt;li&gt;Filter &lt;code&gt;quantizations&lt;/code&gt; on anything quality-sensitive. Dropping &lt;code&gt;unknown&lt;/code&gt; alone eliminates the deployments you have the least information about.&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;data_collection: "deny"&lt;/code&gt; or &lt;code&gt;zdr: true&lt;/code&gt; now rather than during a compliance review. Both are one field today and a migration later.&lt;/li&gt;
&lt;li&gt;Log the serving provider on every response. OpenRouter hands it back, and without it a quality regression has no owner.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A couple of things make the debugging cheaper. &lt;a href="https://devtoollab.com/tools/json-diff" rel="noopener noreferrer"&gt;JSON Diff&lt;/a&gt; will show you exactly which fields differ between two providers answering the same prompt, and the &lt;a href="https://devtoollab.com/tools/llm-token-cost-calculator" rel="noopener noreferrer"&gt;LLM Token Cost Calculator&lt;/a&gt; converts an abstract 11x spread into the monthly bill that decides whether pinning is affordable.&lt;/p&gt;

&lt;h2&gt;
  
  
  When the Default Is Fine
&lt;/h2&gt;

&lt;p&gt;This is not a case against OpenRouter. If you are comparing six models in an afternoon, or building something for yourself, or deciding what to standardize on, one key across hundreds of models is genuinely excellent and price-first routing is what you want.&lt;/p&gt;

&lt;p&gt;The failure is a timing problem rather than a technical one. Something you spiked in a week turns into something customers depend on, and nobody goes back to the routing block. Treat it like any other dependency once real traffic arrives. Known providers, explicit capability requirements, enough logging to name the one that regressed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;A model slug on OpenRouter is a pool. For a widely hosted open-weight model, that pool reached 33 providers in my sample, with pricing varying 11x, context ceilings varying 15x, and five competing claims about quantization. That is exactly what you want for uptime and exactly what you do not want for reproducible output, and about six fields separate the two postures. Point the script at whatever you actually ship before you decide which one you are in.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devtoollab.com/blog/openrouter-provider-routing" rel="noopener noreferrer"&gt;Original article on DevToolLab&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://mmoustafa.com/blog/so-you-want-to-use-openrouter/" rel="noopener noreferrer"&gt;So you want to use OpenRouter&lt;/a&gt; by Mohamed Moustafa&lt;/li&gt;
&lt;li&gt;&lt;a href="https://openrouter.ai/docs/features/provider-routing" rel="noopener noreferrer"&gt;OpenRouter Provider Routing documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devtoollab.com/blog/best-llm-gateways" rel="noopener noreferrer"&gt;Best LLM Gateways and API Routers in 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devtoollab.com/blog/prompt-caching-guide" rel="noopener noreferrer"&gt;Prompt Caching in 2026&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Opsgenie Dies April 2027. Here Is What to Move To</title>
      <dc:creator>Moksh Gupta</dc:creator>
      <pubDate>Fri, 18 Sep 2026 19:00:31 +0000</pubDate>
      <link>https://dev.to/moksh/opsgenie-dies-april-2027-here-is-what-to-move-to-1ca4</link>
      <guid>https://dev.to/moksh/opsgenie-dies-april-2027-here-is-what-to-move-to-1ca4</guid>
      <description>&lt;p&gt;On-call tooling is the least glamorous thing in an observability stack and the only part that has to work while everything else is broken. It survives people quitting, phones on silent, and escalation chains nobody rehearses until 3am on a holiday weekend.&lt;/p&gt;

&lt;p&gt;Two of the defaults for that job died within a year of each other. Atlassian's migration page states that Opsgenie runs "without interruption until April 5th, 2027," and after that "the product will no longer be accessible; any customer data in Opsgenie that has not been moved will also be deleted." Grafana OnCall OSS, the answer everyone gave when the reply was "self-host it," went into maintenance mode in March 2025 and was archived in March 2026. I put the full comparison, with per-vendor screenshots, &lt;a href="https://devtoollab.com/blog/best-opsgenie-alternatives" rel="noopener noreferrer"&gt;on DevToolLab&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9tmtos75ss0c39q3hpk5.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9tmtos75ss0c39q3hpk5.webp" alt="Opsgenie alternatives" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  This Is a Deletion Date, Not a Deprecation
&lt;/h2&gt;

&lt;p&gt;Worth being precise about the difference, because it changes your timeline. Plenty of products get "deprecated" and then quietly run for another five years. This is not that. Atlassian published a calendar date and attached data destruction to it. Rotations, escalation policies, integrations and incident history all have to be somewhere else by April 5, 2027 or they stop existing.&lt;/p&gt;

&lt;p&gt;Atlassian's own destination is Jira Service Management, which absorbed the alerting and on-call features, and they ship automated migration tooling into it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Free Self-Host Option Closed Too
&lt;/h2&gt;

&lt;p&gt;Grafana OnCall OSS carried the self-hosted recommendation for years. Its docs now open with a caution notice: archived as of March 24, 2026, development continuing in Grafana Cloud IRM instead. The repository was relocated to &lt;code&gt;grafana-cold-storage/oncall&lt;/code&gt; and GitHub flipped it read-only on June 5, 2026.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9j7b87xlpzjvybyipxcd.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9j7b87xlpzjvybyipxcd.webp" alt="The grafana-cold-storage/oncall repository on GitHub showing an archived banner dated Jun 5, 2026, a Public archive badge, the AGPL-3.0 license, 3.9k stars and 429 forks" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The last release still runs. Nobody is shipping patches for it, which for something holding your paging path is a different risk calculation than for a CLI tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Six Replacements, Priced
&lt;/h2&gt;

&lt;p&gt;Every figure here came off the vendor's own pricing page, checked September 18, 2026. Annual rates are shown where the vendor publishes a discount.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Entry&lt;/th&gt;
&lt;th&gt;Mid&lt;/th&gt;
&lt;th&gt;Free tier&lt;/th&gt;
&lt;th&gt;Open source&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;PagerDuty&lt;/td&gt;
&lt;td&gt;$25 Professional&lt;/td&gt;
&lt;td&gt;$49 Business&lt;/td&gt;
&lt;td&gt;5 users&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;incident.io&lt;/td&gt;
&lt;td&gt;$19 Team&lt;/td&gt;
&lt;td&gt;$25 Pro&lt;/td&gt;
&lt;td&gt;Basic, forever&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rootly&lt;/td&gt;
&lt;td&gt;$20 Essentials&lt;/td&gt;
&lt;td&gt;Enterprise on request&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FireHydrant&lt;/td&gt;
&lt;td&gt;$25 Pro, annual&lt;/td&gt;
&lt;td&gt;Enterprise on request&lt;/td&gt;
&lt;td&gt;10 responders&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jira Service Management&lt;/td&gt;
&lt;td&gt;$20 per agent&lt;/td&gt;
&lt;td&gt;$51.42 Premium&lt;/td&gt;
&lt;td&gt;3 agents&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Keep&lt;/td&gt;
&lt;td&gt;Self-hosted, free&lt;/td&gt;
&lt;td&gt;Cloud on request&lt;/td&gt;
&lt;td&gt;All of it&lt;/td&gt;
&lt;td&gt;MIT outside &lt;code&gt;ee/&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;PagerDuty&lt;/strong&gt; is the incumbent and charges accordingly: $25 per user monthly, $21 annually, with Business at $49 or $41. Its real product is the integration catalog, so if your alert sources are a mess it is the shortest path. The bill stings as soon as you are paying full seats for engineers who take the pager twice a year.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;incident.io&lt;/strong&gt; treats the Slack or Teams channel as the incident surface instead of a separate console. The Basic tier is genuinely free forever and covers single-team on-call and a status page. Team is $19 monthly or $15 annually, Pro is $25.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rootly&lt;/strong&gt; opens at $20 per user and markets an AI layer: similar-incident lookup, a scribe for meeting notes, in-incident chat help. Judge the scheduling and escalation primitives first, since those are the parts you are actually replacing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FireHydrant&lt;/strong&gt; is the one with a genuinely different pricing shape, and I think it is the most under-discussed option here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F23oeit5elprc9kaktltr.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F23oeit5elprc9kaktltr.webp" alt="The FireHydrant pricing page showing a Free plan, Pro at $25 per responder per month billed annually, and Enterprise custom pricing, with a banner advertising a Signals migrator for PagerDuty and Opsgenie configs" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It charges per &lt;em&gt;responder&lt;/em&gt;, not per seat. If 25 people out of 200 engineers carry the pager, that gap against seat-based pricing is enormous. Its free tier covers 10 responders, which is the most generous starting point of any commercial option in the table.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jira Service Management&lt;/strong&gt; is the low-risk migration and the awkward one. Same vendor, first-party tooling, no export-reimport of history. It is also the vendor that just killed the product you are migrating off, and per-agent pricing is a different shape from what Opsgenie charged, so model the bill before committing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep&lt;/strong&gt; is the surviving open-source answer: MIT licensed outside its &lt;code&gt;ee/&lt;/code&gt; directory, 12,334 stars, v0.54.3 shipped September 9, 2026, commits landing continuously. It bills itself as AIOps and alert management rather than an on-call scheduler, so it is strong at correlating and deduplicating alerts across sources and thinner if what you want is a rotation calendar with reliable phone delivery. LinkedIn's &lt;code&gt;oncall&lt;/code&gt; also still exists, BSD-2-Clause and roughly 1,257 stars, but its last commit was August 2025.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Costs That Are Not on the Pricing Page
&lt;/h2&gt;

&lt;p&gt;Three things decide the real number, and the original post &lt;a href="https://devtoollab.com/blog/best-opsgenie-alternatives" rel="noopener noreferrer"&gt;works through each in more detail&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Seat versus responder pricing can differ by a multiple on identical headcount, so count who can actually be paged before you compare quotes. Voice and international SMS are metered almost everywhere and they are the feature that has to work; PagerDuty's free tier, for instance, includes 100 international phone and SMS notifications monthly, which a US-only rotation will never notice and a distributed one will hit fast.&lt;/p&gt;

&lt;p&gt;The one that eats the schedule is integration rebuild. Rotations and escalation policies port fine. The long tail of systems pointed at your current webhook endpoints does not, and that inventory is always longer than anyone guesses. A &lt;a href="https://devtoollab.com/tools/webhook-signature-verifier" rel="noopener noreferrer"&gt;webhook signature verifier&lt;/a&gt; is worth having open while you repoint them, and an &lt;a href="https://devtoollab.com/tools/uptime-sla-calculator" rel="noopener noreferrer"&gt;uptime SLA calculator&lt;/a&gt; helps settle which alerts deserve a phone call at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Picking One
&lt;/h2&gt;

&lt;p&gt;Already committed to Atlassian: Jira Service Management, with the bill modeled first. Running incidents in Slack: incident.io, cheapest commercial entry and the Slack model is the product. Small pager rotation inside a big org: FireHydrant, on responder pricing alone. Messy alert sources and no appetite for risk: PagerDuty. Set on self-hosting: Keep, with engineering time budgeted, because you are shaping an alert platform into an on-call tool rather than unboxing one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;A deletion date with data destruction attached is not a roadmap item to revisit next quarter. The commercial field sits between $19 and $25 at entry, FireHydrant has the free tier worth taking seriously, and Keep is the one maintained open-source option left standing.&lt;/p&gt;

&lt;p&gt;Plan against the calendar instead of the feature matrix: inventory what pages you today, count your real responders, and run a live rotation on a trial while you still have the option to change your mind.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devtoollab.com/blog/best-opsgenie-alternatives" rel="noopener noreferrer"&gt;Original article on DevToolLab&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.atlassian.com/software/opsgenie/migration" rel="noopener noreferrer"&gt;Atlassian Opsgenie migration page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/grafana-cold-storage/oncall" rel="noopener noreferrer"&gt;Grafana OnCall OSS, archived&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/keephq/keep" rel="noopener noreferrer"&gt;Keep on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devtoollab.com/blog/datadog-alternatives" rel="noopener noreferrer"&gt;7 Datadog Alternatives and What They Cost&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>programming</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Cheapest Sub-Minute Uptime Monitor in 2026 Is Free</title>
      <dc:creator>Moksh Gupta</dc:creator>
      <pubDate>Thu, 17 Sep 2026 18:46:10 +0000</pubDate>
      <link>https://dev.to/moksh/the-cheapest-sub-minute-uptime-monitor-in-2026-is-free-1l4l</link>
      <guid>https://dev.to/moksh/the-cheapest-sub-minute-uptime-monitor-in-2026-is-free-1l4l</guid>
      <description>&lt;p&gt;Uptime monitors all look interchangeable on a pricing page. They are not, and the thing that separates them is buried in the fine print: how often the service checks, how many endpoints it watches before billing starts, and whether it can page a human at 3 AM. Those three move independently, and the free tiers are where they diverge hardest.&lt;/p&gt;

&lt;p&gt;I priced seven of them off their own pages on September 17, 2026 and ran the arithmetic. One result was worth the exercise on its own: &lt;strong&gt;if you need a mean detection time under a minute for 10 endpoints, the cheapest option is a free plan, not a paid one.&lt;/strong&gt; Checkly's Hobby tier does it for $0. UptimeRobot hands you five times as many monitors free, but checks a fifth as often, so it cannot clear the same bar.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://devtoollab.com/blog/best-uptime-monitoring-tools" rel="noopener noreferrer"&gt;longer version of this lives on DevToolLab&lt;/a&gt; with the full per-vendor breakdown. This is the compressed argument.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Numbers Side by Side
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Free tier&lt;/th&gt;
&lt;th&gt;Free interval&lt;/th&gt;
&lt;th&gt;Entry paid plan&lt;/th&gt;
&lt;th&gt;Fastest interval&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://uptimerobot.com/" rel="noopener noreferrer"&gt;UptimeRobot&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;50 monitors&lt;/td&gt;
&lt;td&gt;5 minutes&lt;/td&gt;
&lt;td&gt;$9/mo, 10 monitors&lt;/td&gt;
&lt;td&gt;15 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://betterstack.com/" rel="noopener noreferrer"&gt;Better Stack&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;10 monitors, 10 heartbeats&lt;/td&gt;
&lt;td&gt;3 minutes&lt;/td&gt;
&lt;td&gt;$25/mo per extra 50&lt;/td&gt;
&lt;td&gt;30 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.checklyhq.com/" rel="noopener noreferrer"&gt;Checkly&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;10 monitors&lt;/td&gt;
&lt;td&gt;2 minutes&lt;/td&gt;
&lt;td&gt;$24/mo, 50 monitors&lt;/td&gt;
&lt;td&gt;30 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://cronitor.io/" rel="noopener noreferrer"&gt;Cronitor&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;5 monitors&lt;/td&gt;
&lt;td&gt;5 minutes&lt;/td&gt;
&lt;td&gt;$2/mo per monitor&lt;/td&gt;
&lt;td&gt;30 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://uptime.kuma.pet/" rel="noopener noreferrer"&gt;Uptime Kuma&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;unlimited, self-hosted&lt;/td&gt;
&lt;td&gt;configurable&lt;/td&gt;
&lt;td&gt;none, MIT&lt;/td&gt;
&lt;td&gt;configurable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://gatus.io/" rel="noopener noreferrer"&gt;Gatus&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;unlimited, self-hosted&lt;/td&gt;
&lt;td&gt;configurable&lt;/td&gt;
&lt;td&gt;hosted plan exists&lt;/td&gt;
&lt;td&gt;configurable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://upptime.js.org/" rel="noopener noreferrer"&gt;Upptime&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;unlimited, GitHub Actions&lt;/td&gt;
&lt;td&gt;5 minutes&lt;/td&gt;
&lt;td&gt;none, MIT&lt;/td&gt;
&lt;td&gt;5 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Detection Time Is Half the Check Interval
&lt;/h2&gt;

&lt;p&gt;Here is the piece most comparisons skip. A failure does not politely wait for your monitor. It lands at a random moment between two checks, so on average you wait half the interval before anything even looks. That is your floor, before alerting adds its own lag.&lt;/p&gt;

&lt;p&gt;Thirty lines of Node turns that into a ranking. No dependencies, runs on Node 18 or newer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Plan data read from each vendor's pricing page on September 17, 2026.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PLANS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UptimeRobot Free&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UptimeRobot Solo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UptimeRobot Team&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UptimeRobot Scale&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi"&gt;65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Better Stack Free&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Checkly Hobby&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Checkly Starter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Checkly Team&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi"&gt;75&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Cronitor Hacker&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;NEED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;            &lt;span class="c1"&gt;// endpoints you actually have&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TARGET_DETECT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;   &lt;span class="c1"&gt;// acceptable mean seconds to detection&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;PLANS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;usd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;monitors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;usd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;monitors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;meanDetect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;interval&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;perMonitor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;usd&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;usd&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;monitors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;fits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;monitors&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;NEED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rows&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fits&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meanDetect&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;TARGET_DETECT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;usd&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;usd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; at $&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;usd&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/mo`&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nothing qualifies&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// -&amp;gt; Checkly Hobby at $0/mo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The per-monitor column is what reorders the market. UptimeRobot Scale looks expensive at $65 a month until you divide by 200 monitors and get $0.33 each, the cheapest paid slot anywhere in the table. Checkly Team costs a dollar less in absolute terms and works out at $0.85, because it bundles 75 monitors instead of 200. Sorting by sticker price gets this exactly backwards, which is &lt;a href="https://devtoollab.com/blog/best-uptime-monitoring-tools" rel="noopener noreferrer"&gt;covered in more depth in the original post&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hosted Four
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3i71d9askiyxhc7if94w.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3i71d9askiyxhc7if94w.webp" alt="The UptimeRobot pricing page showing Solo at $9, Team at $35 and Scale at $65 per month with monitor counts and check intervals" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UptimeRobot&lt;/strong&gt; has the most generous free tier here: 50 monitors on a 5-minute interval, no card required, covering HTTP, port and ping. Paid tiers as of September 17, 2026 run $9 (Solo, 60-second checks), $35 (Team, 30-second, 100 monitors) and $65 (Scale, 15-second, 200 monitors) on annual billing. The free tier's catch is arithmetic: 5-minute checks mean roughly 150 seconds pass on average before a failure is noticed. Acceptable for a brochure site, not for checkout.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Better Stack&lt;/strong&gt; is the one to pick when uptime and on-call should be a single workflow rather than two subscriptions. Its own page advertises 10 monitors, 10 heartbeats and a status page at 3-minute checks for nothing. After that the pricing is modular: another 50 monitors costs $25 a month, or $21 billed yearly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Checkly&lt;/strong&gt; treats monitoring as code, so checks live in Git beside the Playwright tests they reuse. Annual pricing is $0 for Hobby (10 monitors at 2-minute frequency), $24 for Starter (50 monitors at 1 minute) and $64 for Team (75 monitors at 30 seconds across 22 locations). Watch the overages, which is where the bill surprises people: browser check runs past your allowance bill at $6.50 per 1,000 on Starter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cronitor&lt;/strong&gt; came from cron job monitoring and still handles that better than the generalists. Hacker is free forever with 5 monitors; Business charges $2 per monitor per month plus $5 per user with no base fee, reaching 30-second checks. Per-monitor billing is excellent at 10 monitors and brutal at 200. If your real question is whether last night's backup ran, this is the right shape.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Open-Source Three
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvx44xoz98h9529k85hra.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvx44xoz98h9529k85hra.webp" alt="The Uptime Kuma homepage showing the project logo, a self-hosted monitoring tagline and the docker run command" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Uptime Kuma&lt;/strong&gt; is the default self-hosted answer and dwarfs everything else in this category: MIT licensed, &lt;strong&gt;91,453 GitHub stars&lt;/strong&gt;, version 2.5.5 shipped September 16, 2026 with commits landing the next day. One &lt;code&gt;docker run&lt;/code&gt; gets you HTTP, TCP, ping, DNS and keyword checks plus status pages and around 90 notification integrations. The structural catch deserves saying plainly: one box in one region tells you the service is unreachable &lt;em&gt;from that box&lt;/em&gt;, which is not the same as down, and it tells you nothing at all while that box is the thing that broke.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gatus&lt;/strong&gt; is Apache-2.0, 12,090 stars, v5.36.0 from May 19, 2026. Everything is YAML, which makes it the natural fit when monitors belong in the same repo as the infrastructure they watch, and its conditions syntax asserts on status code, response time and body content together instead of bare reachability. Note that gatus.io now sells a hosted version too; the self-hosted core stays Apache-2.0.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Upptime&lt;/strong&gt; removes the server entirely. MIT, 17,157 stars, running on GitHub Actions, Issues and Pages, so checks run on Actions runners, incidents open as issues and the status page deploys to Pages. Two honest caveats: Actions scheduling puts a practical floor near 5 minutes, and the newest tagged release is &lt;strong&gt;v2.0.0 from October 13, 2020&lt;/strong&gt;, even though the repo took commits on September 17, 2026. It works; the tags just do not tell you that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Picking One
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Side project or marketing site:&lt;/strong&gt; UptimeRobot free. Nothing else gives you 50 endpoints for $0.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sub-minute detection, no budget:&lt;/strong&gt; Checkly Hobby, the only free plan in the table that clears a 60-second mean for 10 monitors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker already running, want unlimited monitors:&lt;/strong&gt; Uptime Kuma on a small VPS, in a different region from whatever it watches.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monitors belong in version control:&lt;/strong&gt; Gatus for YAML, Checkly if the checks should reuse Playwright tests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Uptime and on-call as one product:&lt;/strong&gt; Better Stack, whose free tier includes the status page and escalation policy instead of selling them separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cron jobs and backups rather than web pages:&lt;/strong&gt; Cronitor, where the heartbeat model matches the problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open-source project already on GitHub:&lt;/strong&gt; Upptime, if 5-minute checks are good enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The comparison that matters is cost per monitor against detection time, and those two rank these products differently from the pricing pages. On numbers verified September 17, 2026: UptimeRobot Scale is the cheapest paid slot at $0.33 per monitor, Checkly Hobby is the cheapest route to sub-minute detection at $0, and Uptime Kuma deletes the per-monitor question if you will run a box and live with a single vantage point. Count your endpoints, decide how fast you need to know, and run the script against your own list before paying anyone.&lt;/p&gt;

&lt;p&gt;Two DevToolLab tools that pair with this: the &lt;a href="https://devtoollab.com/tools/url-redirect-checker" rel="noopener noreferrer"&gt;URL Redirect Checker&lt;/a&gt; for finding out your health check is quietly following a 302, and the &lt;a href="https://devtoollab.com/tools/latency-percentile-calculator" rel="noopener noreferrer"&gt;Latency Percentile Calculator&lt;/a&gt; for turning raw response times into a p95 your alert threshold can actually use.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://devtoollab.com/blog/best-uptime-monitoring-tools" rel="noopener noreferrer"&gt;Best Uptime Monitoring Tools in 2026&lt;/a&gt; - the original article on DevToolLab, with the full fit table and per-vendor detail&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://devtoollab.com/blog/datadog-alternatives" rel="noopener noreferrer"&gt;7 Datadog Alternatives and What They Cost&lt;/a&gt; - the full observability platforms, priced on one identical workload&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://devtoollab.com/blog/best-sentry-alternatives" rel="noopener noreferrer"&gt;Best Sentry Alternatives in 2026&lt;/a&gt; - error tracking, which answers a different question than uptime&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/louislam/uptime-kuma" rel="noopener noreferrer"&gt;Uptime Kuma on GitHub&lt;/a&gt; - MIT licensed, source of the star count and release date quoted above&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/TwiN/gatus" rel="noopener noreferrer"&gt;Gatus on GitHub&lt;/a&gt; - Apache-2.0, version and license verified here&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>opensource</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
