Zurück zu Arbeiten

COMPARE INFERENCE

2026

Ein Preisindex für die drei Dinge, die KI wirklich kostet: GPUs, Token und Strom.

ProduktData EngineeringFullstack-EntwicklungDesign EngineeringDevOps
COMPARE INFERENCE

Compare Inference ist ein täglicher Medianpreis-Index für KI-Infrastruktur, über GPU-Miete, LLM-Token und Strom im Großhandel. Die Seite liest ein, was Anbieter veröffentlichen, bildet den Median darüber und zeigt die Streuung dahinter. Kostenlos, ohne Konto, mit öffentlicher JSON-API und CSV-Export.

Jeder Anbieter, der eine H100 vermietet, veröffentlicht einen Preis. Keine zwei davon veröffentlichen denselben. Am Tag des Starts kostete eine H100-Stunde bei einem Anbieter 1,95 $ und beim nächsten 4,15 $, eine Spanne von 112 Prozent, und es gab keine neutrale Stelle, an der man das sehen konnte.

Compare Inference liest ein, was Anbieter veröffentlichen, bildet den Median darüber und zeigt die Streuung hinter diesem Median. Drei Märkte, eine Methode.

MarktEinheitAbdeckung heute
RechenleistungUSD je physischer GPU-Stunde15 Beschleunigertypen, je bis zu 26 Anbieter
TokenUSD je 1 Mio. Token, gemischt 3:1 Ein- zu Ausgabe37 Labore, 2.532 Modelle
StromUSD je MWh, Spitzenlast7 US-Handelspunkte

Kostenlos, ohne Konto, ohne Anmeldeschranke. Es gibt eine öffentliche JSON-API und einen CSV-Export, denn ein Preisindex, den man nicht in eine Tabelle ziehen kann, ist ein Screenshot.

Das sind Listenpreise verschiedener Anbieter, keine abgeschlossenen Geschäfte, und die Seite sagt das an jeder Stelle, an der eine Zahl steht. Strom ist die Ausnahme: dort sind es gemeldete Abschlüsse, wöchentlich veröffentlicht, rund acht Tage im Rückstand. Fehlende Tage bleiben fehlend. Nichts wird interpoliert.

Der Preissturz um 25 Prozent, den es nie gab

159 Tage Historie aus einer fremden Sammlung nachzuladen klingt nach einer Datenaufgabe. Es ist keine. Diese Sammlung deckte vier Anbieter mit H100-Preisen ab. Diese hier deckt zweiundzwanzig ab.

Auf demselben Stichtag gemessen liegt der Median über Neoclouds bei 3,29 $, gemischt bei 4,04 $ und über Hyperscaler bei 15,16 $. Ein naiver Nachlauf schreibt 158 Tage bei 4 bis 5 $ und fällt dann am ersten selbst gemessenen Tag auf 3,20 $. Das ist ein Preissturz von 25 Prozent bei Rechenleistung, den es nie gab, und jeder Typechecker und jeder Test im Repository hätte ihn kommentarlos durchgewinkt.

Deshalb ist die Anbieterklasse eine Konstante und keine Spalte. Damit sind beide Sammlungen von vornherein gleich zusammengesetzt. Ein automatisches Gate vergleicht danach für jeden Beschleuniger den letzten geerbten Tag mit dem ersten selbst gemessenen. Über 10 Prozent Abweichung beschreiben die beiden nicht denselben Markt, und die Historie dieses Beschleunigers wird zurückgezogen. In den echten Daten rissen drei von neun die Grenze, mit +25,8, -13,7 und -11,2 Prozent. Sechs behielten je 158 Tage.

Geerbte Historie wird als getrennte gestrichelte Linie in derselben Farbe gezeichnet, mit einer Notiz unter dem Diagramm, die sagt, was die Strichelung bedeutet und wie weit beide Sammlungen dort übereinstimmen, wo sie sich überlappen.

Der Rest der Datenstrecke

Acht Adapter über drei Märkte, jeder normalisiert auf dieselbe Form. Das Abholen ist die leichte Hälfte. Jede Quelle lügt auf ihre eigene Art.

  • Preise kommen je Instanz, je Knoten, in Cent oder je GPU. Alles wird auf eine physische GPU-Stunde normalisiert, und keinem Feld einer Quelle, das schon je GPU rechnet, wird geglaubt.
  • Ein historischer Datensatz hatte 38.620 von 46.589 Zeilen als reine CPU-Angebote markiert. Ohne diesen Filter ist der Median null.
  • Dieselbe Konfiguration taucht einmal pro Region auf. Die H100 PCIe eines Anbieters erschien zwölfmal zum identischen Preis. Ohne Entdopplung ist der Median regionsgewichtet, und ein einzelner Hyperscaler liefert die Hälfte der Zeilen.
  • Unplausible Beobachtungen werden in Quarantäne gestellt, nicht verworfen, samt Begründung. Ein Katalogfehler schob ein Teil über Nacht von 0,2253 $ auf 3,5642 $.
  • Unbekannte Hardwarenamen werden übersprungen, nie geraten. Ein Mapper, der rät, verdirbt eine Zeitreihe. Einer, der überspringt, hinterlässt eine Lücke, die sichtbar eine Lücke ist.

Architektur

Vier Deployables, ein Repository, keine Server zum Patchen.

apps/web       Vite-SPA auf Cloudflare Workers Static Assets
apps/api       Hono auf Cloudflare Workers, sechs JSON-Endpunkte
apps/crawler   Cloudflare Worker mit Cron-Trigger, zweimal täglich
packages/db    Drizzle-Schema und die Domänenkonstanten für beide Seiten

SPA und API teilen sich eine Origin. Cloudflare greift die spezifischste Route zuerst, also landet cmpinf.com/api/* beim API-Worker und alles Übrige fällt auf die statischen Dateien durch. Kein CORS-Preflight für die eigenen Anfragen der Seite, und das Session-Cookie für API-Token darf SameSite=Lax bleiben.

Postgres läuft auf eigener Infrastruktur und ist aus dem Internet nicht erreichbar. Die Worker kommen über einen Cloudflare Tunnel mit vorgelagerter Zero-Trust-Access-Regel heran, und Hyperdrive hält den Pool. Beide Worker nutzen dieselbe Bindung, und das nicht aus Symmetrie: ein roher Postgres-Socket kann kein Access-Service-Token vorzeigen, Hyperdrive schon.

Stack

Frontend. React 19, TypeScript im Strict-Modus, Vite 7. TanStack Router für dateibasiertes Routing mit automatischem Code-Splitting, TanStack Query für die Datenschicht, TanStack Table für die Analysetabellen. Tailwind v4, CSS-first, ohne JavaScript-Konfiguration. shadcn/ui über Radix-Primitiven. Dazu je eine Bibliothek pro Aufgabe: cmdk für die Befehlspalette, @number-flow/react für rollende Preisziffern, d3-scale und d3-shape unter einem kleinen eigenen Diagrammbaukasten, zod für jede Grenze, die die App nicht selbst kontrolliert.

Backend. Hono auf Workers, Drizzle ORM, postgres.js, Postgres 17. Werkzeuge. pnpm-Workspaces und Turborepo, Biome, oxlint mit eigenem Plugin, Vitest und Playwright.

Zwei Entscheidungen, die eine Erklärung verdienen.

Alles steht in der URL. Markt, Zeitraum, Beschleuniger, Modell, Vergleichsüberlagerungen, Tabellensortierung, Filterchips. Eine gefilterte, sortierte Ansicht auf 2.532 Modelle ist genau das, was jemand in einen Chat einfügen will, und sie übersteht einen Reload. Ein Klick auf die Sortierung legt einen Verlaufseintrag an, Tippen im Filter ersetzt einen. So kosten sechs Tastenanschläge nicht sechs Klicks auf Zurück.

Die Animationsbibliothek wird geholt, nicht importiert. Sie kommt bei der ersten Zeigerbewegung oder dem ersten Tastendruck. Sie wiegt 41,7 kB gzip, und jede Fläche, die sie braucht, ist eine Hover-Karte oder ein Dropdown, also nichts, was auf dem Schirm sein kann, bevor jemand etwas anfasst. Die beiden Exporte zu benennen statt das Namespace-Objekt zu halten, drückte den Chunk von 188,4 kB auf 126,8 kB roh, weil Rollup keinen Export entfernen kann, den später jemand über den Namespace lesen könnte.

Performance

Gemessen auf der ausgelieferten Seite statt auf einem Build-Server, drei Läufe, angegeben ist der Median.

LighthouseWert
Performance100
Barrierefreiheit100
Best Practices100
SEO92
Largest Contentful Paint589 ms
Total Blocking Time0 ms
Cumulative Layout Shift0,002

Die acht fehlenden SEO-Punkte gehen nicht auf die Seite zurück. Cloudflare schreibt eine Content-Signal-Zeile in die robots.txt, und Lighthouse wertet die Direktive, die es nicht kennt, als Fehler. Diese Signale sind ein Rechtevorbehalt nach Artikel 4 der EU-Urheberrechtsrichtlinie, und der ist mehr wert als acht Punkte. Also bleiben sie.

Zwei Änderungen haben die Zeiten bis zum ersten Bild getragen, und die zweite wurde erst sichtbar, als die erste behoben war. Der Loader übersprang die Preisreihe vollständig, wenn die URL keinen Beschleuniger nannte, also bei jedem kalten Besuch der Startseite: erst musste der Katalog eintreffen, dann die Komponente rendern, dann ein Effekt den Standardwert in die URL schreiben, und erst danach fragte das Diagramm überhaupt etwas an. Jetzt rät der Loader diesen Standardwert aus derselben Vorzugsliste, gegen die auch die Komponente auflöst. Falsch zu liegen kostet eine ungenutzte Anfrage. Zu spät zu fragen kostete bei jedem Besuch einen seriellen Umlauf.

Danach lädt das Dokument selbst die vier Aufrufe der Startseite vor, damit sie mit dem HTML rausgehen und nicht erst, wenn das Bundle geparst ist. Diese Hinweise trugen crossorigin nur dann, wenn die API auf einer anderen Origin lag, mit der Begründung, ein gleichursprünglicher Fetch schicke Anmeldedaten, zu denen ein anonymer Preload-Eintrag nicht passt. Das ist falsch: as="fetch" beschreibt eine Anfrage, die fetch() stellen wird, und fetch() läuft standardmäßig im CORS-Modus. Zeigen konnte das nur die Produktion, denn in der Entwicklung liegt die API auf einem anderen Port und die Bedingung nahm den anderen Zweig. Der Test lief grün, während auf der Live-Seite alle vier Hinweise „preloaded but not used" meldeten und die ganze Optimierung wirkungslos war.

Das Vorrendern aller zwölf Routen wurde vor beiden gebaut, gemessen und verworfen. FCP verbesserte sich um 390 ms, TBT um 23 ms, die Wertung stieg um einen Punkt, und LCP bewegte sich überhaupt nicht, weil vorgerendertes HTML keinen LCP-Kandidaten liefert, solange kein Inhalt darin steht. Die Messung steht aufgeschrieben, damit sie nicht später neu entdeckt wird.

Die Barrierefreiheit auf 100 hat am meisten Arbeit gekostet. Der Fokusring, den shadcn mitliefert, kommt gegen Weiß auf 1,54:1, wo WCAG 2.2 3:1 verlangt. Der Token wurde auf 7,4:1 im hellen und 5,6:1 im dunklen Modus neu gerechnet. Die Links im Kursband tragen einen sr-only-Zusatz statt eines aria-label, denn jede Beschriftung, die erklärt, was die Zahlen bedeuten, schiebt Wörter dazwischen. Dann ist der sichtbare Text kein zusammenhängender Teil des zugänglichen Namens mehr, und Sprachsteuerung bricht. Jede Animation liefert zwei Varianten, und bei reduzierter Bewegung wird das Laufband zu einer waagerecht scrollbaren Preisleiste statt zu einem Streifen, dessen Inhalt hinter overflow: hidden feststeckt.

Prüfgatter

Vier Stufen, jede beantwortet eine andere Frage.

  1. typecheck, lint, test, build. Kompiliert und bündelt es.
  2. anti-slop. Ein lokales oxlint-Plugin mit fünfzehn Regeln gegen die Muster, in die ungeprüfte Modellausgabe fällt: verkettete Type Assertions, Verbreitern auf unknown und Zurückbehaupten, typeof-Prüfungen zur Laufzeit für Dinge, die der Typ schon kennt, bedingte Spreads leerer Objekte. Jede Assertion, die überlebt, braucht einen // SAFETY:-Kommentar, der sagt, warum sie hält.
  3. Review. Unabhängige Leser auf dem Diff.
  4. Browser-Probe. Jede Route in einem echten Browser durchfahren, mit der Zusicherung: keine Fehlerseiten, keine Konsolenfehler, keine 4xx und 5xx.

Nur die letzte Stufe fragt nach dem Produkt. Diese Regel hat das Projekt aus einer Nachbetrachtung geerbt, in der ein Starterkit vierzehn Releases mit lauter grünen Gattern auslieferte, während ein frischer Klon nicht startete, jede Seite hinter dem Login abstürzte und ein Anmeldeformular das Passwort in die URL schrieb.

Drei kaputte Gatter kamen beim Bauen ans Licht:

  • Biome prüfte test-results/.last-run.json mit. Nach jedem Playwright-Lauf wurde das Linting rot, wegen einer Datei, die kein Mensch geschrieben hat.
  • Playwrights voreingestellte Worker-Zahl brachte den Dev-Proxy von wrangler um. Die voreingestellten 8 Worker auf einer 16-Kern-Maschine töteten ihn in 3 von 3 Läufen, die Antwortzeiten stiegen von 60 ms auf 890 ms, danach lief jede weitere Anfrage in ECONNREFUSED. Auf 4 gedeckelt überlebte er 3 von 3. Die Suite hatte eine Maschinengrenze als Produktfehler gemeldet.
  • Die Browser-Suite erklärte keine Abhängigkeit auf die App, die sie prüft, also enthielt ihr Cache-Schlüssel das Frontend nie. Eine Komponente ändern und die Tests laufen lassen ergab "FULL TURBO, 43 passed", ohne dass irgendetwas ausgeführt wurde. Sie wurde grün auf einem kaputten Diagramm und auf dessen Reparatur gleichermaßen.

Wegen des dritten Falls steht in der SOP hinter diesem Projekt: ein Gatter, das man nie hat scheitern sehen, ist ungetestet. Die Reparatur wurde geprüft, indem dieselbe Änderung zweimal gemacht und der Task-Hash beobachtet wurde.

Wie es gebaut wurde

Allein, und das umfasst Produktentscheidungen, Datenmodell, Crawler, API, Oberfläche und Betrieb. Mit Agenten gebaut, aber mit der Struktur, die das tragfähig macht, nicht mit der, die es schnell macht.

Plan vor Code. Siebzehn nummerierte Plandokumente, vom MVP über die Rechenleistungsquellen bis zu Anreicherung und API-Token, jedes vor der Umsetzung geschrieben und gelesen.

Untersuchung delegiert, Umsetzung an einer Stelle. Die Recherche kam von spezialisierten Agenten: ein TanStack-Review gegen die Best Practices des Frameworks, ein Performance-Bericht, ein Animationsdurchgang, ein End-to-End-Audit, ein Design-Engineering-Audit, ein Review für Such- und Antwortmaschinen, drei Datenqualitätsberichte zum Crawler, zwei Produktionsreife-Audits und ein Deploy-Bericht. Fünfzehn solcher Berichte und Audits liegen im Repository. Die Umsetzung blieb an einer Stelle, denn parallele Agenten auf denselben Dateien erzeugen einen Merge, den niemand mehr prüfen kann.

Skills als Prüfmaßstab. Die Animations- und Interaktionsarbeit lief gegen benannte Skill-Sets statt gegen Geschmack. Das Design-Engineering-Audit ist ein reiner Lesedurchgang gegen dieselben Regeln, und genau das macht es nachprüfbar statt zu einer Meinung.

Review über Modellfamilien hinweg. Untersuchungen und Reviews liefen bei anderen Modellen als der Umsetzung, damit kein Modell die eigene Änderung abnimmt.

Was als Nächstes kommt

  • Spotpreise auf der Startseite. Die Daten liegen schon vor und sie sind 10 bis 30 Prozent günstiger, aber fünf der erfassten Typen haben genau einen Spot-Anbieter, und ein Median über Anbieter bei einem Anbieter ist der Preis dieser Firma mit dem Wort Median davor. Das gehört dorthin, wo neben jeder Zahl eine Anbieterzahl stehen kann.
  • Mehr Stromhandelspunkte. Die aktuelle Quelle hat keinen ERCOT-Punkt und nur den Western Hub von PJM. Das sind die beiden Regionen, in denen gerade wirklich Rechenzentren gebaut werden, also sagt die Seite das mit klaren Worten, statt es still wegzulassen.
  • Speicher. Tägliche DRAM-Spotpreise liegen hinter Lizenzen, die eine Weitergabe untersagen. Ein monatlicher Index ist möglich, und er ist eine andere, kleinere Aussage.

Highlights

8 Adapter über drei Märkte, 5 Quellen mit hinterlegter Lizenz

110 Unit-Tests und 43 End-to-End-Tests in 8 Suiten

Lighthouse 100 für Performance, Barrierefreiheit und Best Practices

3 Cloudflare Worker, kein Server zum Patchen

Tech Stack

React 19TypeScriptViteTanStack RouterTanStack QueryTanStack TableTailwind v4HonoCloudflare WorkersCloudflare HyperdriveCloudflare TunnelPostgreSQLDrizzle ORMTurborepoBiomeoxlintVitestPlaywright
Live-Projekt ansehen

Cookie-Einstellungen

Wir nutzen Cookies für Analyse und Verbesserung unserer Website. Datenschutzerklärung