Skip to main content

When $1.38 cheaper is worse: scoring features into price comparisons

Pure price ranking has a dirty secret: at the top of the board, it's often noise. In our own object storage comparison, two plans land within $1.38 of each other on a five-terabyte monthly bill of roughly $556 — a 0.25% difference that no invoice forecast on earth will predict accurately. Yet a strict "sort by cost" ranking must declare one the winner, and buyers reasonably read that as "this one is better." The intuitive fix — let features decide inside a tight price band — feels fair until it costs real money: in vector-db we watched Qdrant at $18.62 outrank Hetzner pgvector at $17.89 because both fell in the same $2 band and the richer feature set won. This article is about how we fixed both problems, why naive tolerance comparisons break transitivity, and what "near-tie" now means in our engine: price decides, the band only badges.

The case that forced the question

At our 5 TB storage + 5 TB EU egress scenario (the storage tool's default for a media-heavy side project), AWS S3 Standard computes to $556.59/month and IBM Cloud Object Storage computes to $555.21/month once free tiers and per-GB rates from storage-catalog.json (verifiedAt 2026-08-21) are applied. IBM is cheaper — by $1.38, or 0.25%. But the two services are not equivalent products: our catalog captures UI-visible capability dimensions (S3 API compatibility, object lock / WORM, versioning, durability published, SLA published, retention policies, lifecycle automation, storage classes, region spread, ecosystem features like CDN or transcoding), and AWS S3 Standard scores 10 of 10 while IBM Cloud scores 9 in that count (each optional field absent scores zero, never guessed). So which should rank first? A site that sorts by price alone shows you IBM as #1 and you'd never learn what you were giving up for $1.38. A site that let features decide inside the band showed AWS as #1 — but then kept that logic everywhere, and hid a $0.73 real gap elsewhere.

Band the prices, then let features argue — and why we reversed it

From 2026-08-21 until 2026-08-23, our fix treated totals within roughly two dollars as a near-tie: we rounded every plan's computed total into $2 bands (NEAR_TIE_FEATURE_USD = 2 from `src/lib/near-tie.ts`), and inside a band the plan with the richer feature score ranked first; exact cents only decided when features tied, and the vendor slug broke any remaining deadlock. On the S3-versus-IBM case, both totals fell in the same ~$2 band, the richer feature set won, and S3 Standard ranked first despite being nominally more expensive. Outside the band, price ruled exactly as before — nobody got to hide a $50 difference behind a nice dashboard. The logic was deterministic: a composite key [band, -featureScore, exact cents, slug] gave every plan one position regardless of input order. We shipped it, it pinned with tests in both directions (richer-wins-inside-band, cheaper-wins-outside), and it felt principled — until a sibling tool exposed the cost.

What counts as a feature?

Only what we actually captured and show in the tool's UI — and only fields that are visible to the buyer before they pay. For storage, storageFeatureScore() counts: S3 API compatibility (1), object lock / WORM (1), versioning (1), published durability string non-empty (1), published SLA non-empty (1), ecosystem feature non-empty (1), plus region count capped at 8 — total up to 14, but the AWS-vs-IBM gap in this scenario is 10 vs 9 on the ten UI-visible dimensions we narrate to buyers. Each dimension counts one point where the vendor offers the capability; absent optional fields score zero rather than being guessed. The scoring is deliberately dumb: it doesn't weight dimensions or editorialize about which features matter, because weighting would be an opinion pretending to be a measurement. Its only job is to say, honestly and mechanically, "within this price band, this product does more of the things we can verify versus this product that does fewer." The full rule lives in code (`src/lib/near-tie.ts` and `src/lib/storage-compute.ts:storageFeatureScore`) with tests pinning the detection: two vendors $1.38 apart badge as near-ties, two $5 apart do not, and the richer features show up alongside the badge rather than as a reorder.

The general lesson

  • "Cheapest" is only well-defined when products are identical; the closer the prices, the more the decision is actually about features — exactly where naive sort-by-cents hides the most information and band-reordering hides price.
  • Any comparison ranking needs an explicit tie-break policy that is a valid total order. If a site doesn't publish one, its top-of-board ordering is partly arbitrary and may wobble with input order or locale.
  • Determinism matters as much as correctness: the same catalog plus the same workload must always produce the same board, regardless of row order — our band keys plus the equality-first cmpNum (Infinity-safe, NaN-free) guarantee it.
  • Feature scores must come from captured, displayable facts — not affiliate weighting or editorial preference. Ours are countable from the catalog and capped so region count cannot dominate.
  • Surface price first, features second: a badge that says "$1.38 apart — compare 10 vs 9 capabilities" respects both the buyer's wallet and their autonomy, while a silent reorder respects neither.

Methodology you can replay

If you disagree with a two-dollar band, the numbers to argue with are published right there — which is the whole point. Change the band to $1 or $5 in the open code and the same data produces a predictably different set of badges, still deterministically, still price-first. That arguability is stronger than any single "correct" band width, because it turns a subjective design choice into a visible parameter rather than a hidden opinion. Try it in the object storage tool and compare with the vector DB comparison where the same banding idea was first tried.

Sources & provenance