Overslaan naar hoofdinhoud
OpenAI

11 september 2026

Engineering

Onlineopslag snel opschalen voor ruim 1 miljard ChatGPT‑gebruikers

Hoe we ons Python-platform voor applicatieopslag, Habitat, aanpasten aan ongekende groei.

Door Jon Lee, Chaomin Yu en Ben Ries, technisch medewerkers

Bezig met laden...

Elk product van OpenAI is afhankelijk van snelle, betrouwbare toegang tot gegevens, of iemand nu inlogt, de Codex-instellingen controleert of een nieuw gesprek in ChatGPT begint. Voor elk van die handelingen kunnen veel afzonderlijke gegevensopzoekingen nodig zijn voordat het product kan reageren. Als die verzoeken traag zijn, voelt het product traag aan. Als die verzoeken mislukken, werkt het product helemaal niet meer.

Habitat is het onlineopslagplatform dat we hebben gebouwd zodat OpenAI-producten snel en betrouwbaar toegang hebben tot de benodigde informatie. Habitat verwerkt nu ruim 70 miljoen verzoeken per seconde en ondersteunt in bijna 40 geografische regio's producten die wekelijks door meer dan 1 miljard mensen worden gebruikt. Habitat werd voor het eerst gelanceerd ter ondersteuning van GPT's op DevDay 2023, aanvankelijk als een eenvoudige Python-bibliotheek aan de clientzijde die met één database was verbonden. Tegenwoordig is het een complex gedistribueerd systeem dat meer dan 500 petabyte aan gegevens verwerkt.

Figuur 01 · Wat is Habitat?

Onlineopslagplatform

Habitat is het onlineopslagplatform dat we hebben gebouwd zodat OpenAI-producten snel en betrouwbaar toegang hebben tot de benodigde informatie.

  • Verzoek
  • Antwoord
  • Wijzigingen (CDC)

Clients

Onlineopslagplatform

Opslagbronnen

  • ChatGPT
  • API
  • Codex
  • Interne services
  • En meer

Habitat

  • CachingCaches
  • ACL-beleidAutorisatie
  • Plaatsing en gegevensresidentieGegevensresidentie
  • VersleutelingGegevensbeveiliging
  • IsolatieMultitenancy
  • SnelheidsbegrenzingRequest shaping
  • RouteringSchema opzoeken · Gegevensresidentie
  • Azure Cosmos DBOnlineopslag
  • NanobaseOnlineopslag
  • ValkeyCaches
  • BlobopslagOpslagbronnen
CDC-servicesChange Data Capture
  • Databricks
  • Rockset
  • Kafka
  • En meer

Infrastructuur op deze schaal bouwen en beheren is geen sinecure, maar ook niet uitzonderlijk moeilijk. Onze situatie was uniek door het ongekende tempo waarin we moesten opschalen om de duizelingwekkende groei van gebruikers en productvraag bij te benen, terwijl we tegelijk een volwassen platform opbouwden. Systeemengineers bouwen vaak voor een tien keer zo grote schaal en hopen dat die enkele jaren volstaat terwijl ze zich voorbereiden op de volgende vertienvoudiging. In ons geval zijn we de afgelopen drie jaar elk jaar meer dan tien keer zo groot geworden. Het bouwen en beheren van Habitat werd daardoor een reeks tactische keuzes en zorgvuldig geordende stappen: elk onderdeel tot op het laagste niveau doorgronden om alles uit onze bestaande stack te halen, terwijl we tekorten aan opslag- en rekencapaciteit afwendden om tijd te winnen voor fundamentele investeringen.

  • 70 mln.+

    verzoeken per seconde

  • 1 mld.+

    mensen per week

  • 500 PB+

    gegevens

Naarmate OpenAI groeide, moest Habitat meegroeien: eerst door betrouwbaar genoeg te worden voor bedrijfskritisch productverkeer, daarna snel genoeg voor gebruikers wereldwijd en ten slotte door behendig op enorme schaal te functioneren. Dit bericht is het eerste deel van een tweedelige serie over hoe we onlineopslag hebben opgeschaald. In dit bericht vertellen we hoe Habitat zich ontwikkelde, waarom we van een bibliotheek een service maakten en hoe we een service in een ongebruikelijke taal voor serverworkloads, Python, uitbouwden tot een betrouwbare platformlaag voor opslag.

In een volgend bericht gaan we dieper in op hoe we multitenancy op schaal betrouwbaar maakten, onze gelaagde strategie om leesprestaties te optimaliseren en hoe we onze samenwerking met Azure Cosmos DB opschaalden om ongekende vraag betrouwbaar te verwerken.

Wat is Habitat?

Habitat ontstond vanuit een eenvoudig idee: productengineers zouden zich niet met databasebeheer hoeven bezig te houden. Habitat werd op DevDay 2023 voor het eerst gelanceerd ter ondersteuning van GPT's, als een kleine Python-bibliotheek die communiceerde met de hoofdserver van ChatGPT. De bibliotheek ondersteunde een beperkt aantal bewerkingen die achter de schermen werden vertaald naar de databasetoepassing Azure Cosmos DB.

De bibliotheek moest productteams een eenvoudige manier bieden om gegevens op te slaan en op te halen zonder dat ze alle onderliggende details hoefden te beheersen. Habitat nam het noodzakelijke werk voor zijn rekening: bepalen om welke gegevens het ging, waar ze vandaan moesten komen of naartoe moesten, of het verzoek was toegestaan, enzovoort.

Productengineers hoefden zich niet bezig te houden met het opzoeken van schema's, routering, autorisatie, versleuteling, serialisatie, request shaping en connection pooling. Ze hoefden niet eens na te denken over de herkomst van de gegevens: Azure Cosmos DB, caches of andere soorten opslag.

Figuur 02 · Habitat-service

Vereenvoudigde verzoekstroom van Habitat

Door de opslaglogica onder te brengen in een zelfstandige service, creëerden we één centraal punt voor implementaties, observeerbaarheid en platformverbeteringen.

  • Verzoek
  • Antwoord

Client

OpenAI

Azure Cosmos DB

Habitat-client-SDK
envoy
  • habitat-serviceproces 1
  • habitat-serviceproces 2
  • habitat-serviceproces 3
habitat-envoy
  • habitat-cosmos-db-us0
  • habitat-cosmos-db-us1
  • habitat-cosmos-db-eu0

Deze Python-bibliotheek werkte goed en werd snel omarmd door productengineers bij OpenAI, ondanks dat er geen centrale, gecoördineerde stimulans was om af te stappen van zelfbediende Postgres en Azure Cosmos DB.

Toen de productbehoeften veranderden, konden productontwikkelaars de gedeelde bibliotheek bovendien gemakkelijk uitbreiden met functies als caching aan de clientzijde, compressie en versleuteling.

Een service bouwen voor betere ondersteuning van meerdere complexe producten

Halverwege 2025 had Habitat de grenzen van een implementatie aan de clientzijde bereikt. Naarmate de Habitat-laag complexer werd en het aantal services van OpenAI toenam, werden achterwaarts compatibele protocolwijzigingen onhaalbaar.

Zo wilden we de impact van een storing in één regio op onze belangrijkste gegevenssets beperken door deze te migreren naar een reeks regionaal verspreide Azure Cosmos DB-accounts. Voor deze wijziging moesten we extra routeringslogica aan de client toevoegen, uitgeschakeld achter een featureflag, die naar alle clients uitrollen en vervolgens de featureflag inschakelen.

Het coördineren van implementaties voor tientallen services en het samenwerken met elk team aan de uitrol kostte dagen. Voordat we dit inschakelden, beseften we dat we shadowing wilden toevoegen om te controleren of de shardinglogica correct werkte. De uitrol daarvan kostte weer een paar dagen. Een bugfix voor iets wat toch niet bleek te kloppen? Nog een paar dagen. Uiteindelijk waren we klaar om de flag in te schakelen. Toen draaide een van de teams om andere redenen de service terug naar een eerdere client met een bug, waardoor juist de storing ontstond die we zo hard hadden geprobeerd te voorkomen.

Wijzigingen aan de clientbibliotheek vereisten complexe coördinatie tussen tientallen services. Dit proces werd steeds kwetsbaarder, inefficiënter en gevoeliger voor operationele fouten. Om deze operationele fan-out bij toekomstige implementaties te beperken, besloten we van Habitat een zelfstandige service te maken.

Door de opslaglogica onder te brengen in een zelfstandige service, creëerden we één centraal punt voor implementaties, observeerbaarheid en platformverbeteringen. In plaats van versnipperde updates te beheren, konden we verbeteringen centraal doorvoeren, zodat elk OpenAI-product er direct van profiteerde.

Een centrale service biedt ons ook één controlepunt voor de krachtigste basisvoorzieningen voor gegevensbeveiliging en privacy. In de Habitat-service kunnen we centraal beleid voor toegangsbeheer afdwingen, auditlogboeken bijhouden en de toegang tot onderliggende opslagbronnen zoals Azure Cosmos DB beperken. Habitat speelt een cruciale rol bij het beschermen van gebruikersgegevens en het voorkomen van ongeautoriseerde toegang door externe, interne en agentactoren.

Een Python-service op schaal lanceren

We wisten dat we een service nodig hadden, maar wilden nog niet van Python afstappen, ondanks de extra overhead van Python als service. Het gebruik van Python voor een service met hoge doorvoer verhoogde de netwerklatentie en bracht aanzienlijk hogere schaalkosten voor CPU en geheugen met zich mee dan lokale uitvoering als bibliotheek. Bovendien beseften we dat de inefficiënties van Python bij een schaal die honderd keer zo groot was onaanvaardbaar zouden zijn, waardoor een uiteindelijke herschrijving vrijwel zeker was.

Toch zagen we dit als een strategische keuze voor technische schuld. Ons belangrijkste doel was toen niet het optimaliseren van kosten of middelen, maar productontwikkelaars vooruithelpen en het platform stabiel maken. Door op korte termijn de prestatiecompromissen van een Python-service te accepteren, konden we urgentere uitdagingen voorrang geven, onze kern-API's vastleggen en een robuuste infrastructuur opbouwen.

Ook gokten we er weloverwogen op dat de snelle vooruitgang van onze eigen programmeermodellen het technische traject later zou vereenvoudigen. We gokten erop dat Codex en GPT een volledige migratie van Python haalbaar zouden maken zodra die nodig werd. Die gok bleek uiteindelijk juist.

Habitat als Python-service uitvoeren was qua prestaties niet optimaal, maar wel noodzakelijk. Met Python kunnen we snel werken, maar dat betekende niet dat we alle voorzichtigheid konden laten varen en duidelijk slechtere latentietijden konden accepteren. Wanneer een gemiddeld gebruikersverzoek tot honderden databaseaanroepen leidt, merkt de gebruiker vooral de traagste aanroep. Volgens ons is het beheren van deze staartlatenties de grootste uitdaging bij het uitvoeren van een Python-service op deze schaal.

De asyncio-vertraging volgen

Asyncio helpt Python om I/O-gebonden workloads gelijktijdig uit te voeren, maar omzeilt de Python-GIL niet en biedt geen CPU-parallellisme. Naast het proxyen van I/O-intensieve verzoeken voert Habitat veel CPU-intensieve taken en achtergrondtaken uit: routering, compressie, versleuteling, checksums, statuscontroles van downstreamsystemen, request shadowing en hedging.

Met zoveel CPU-intensieve workloads en achtergrondtaken in onze service kan de planningsvertraging van asyncio de staartlatentie van verzoeken gemakkelijk gaan domineren. Voordat we onze eerste servicelancering optimaliseerden, zagen we in traces van verzoeken met een p99-latentie of hoger dat downstreamopslag snel reageerde, maar verzoeken vaak vastliepen terwijl ze wachtten tot de verantwoordelijke coroutine opnieuw werd ingepland om het antwoord te verwerken.

Figuur 03 · De asyncio-vertraging volgen

Gelijktijdigheid is geen CPU-parallellisme

Met asyncio in Python kunnen verzoeken gelijktijdig worden verwerkt, maar op de CPU-thread wordt steeds slechts één verzoek uitgevoerd. Dit heeft grote gevolgen voor de latentietijd van verzoeken wanneer er veel CPU-werk nodig is.

CPU-verwerking van verzoeken en antwoordenLezen/schrijven via het Python-netwerkWachten op Cosmos

Weinig CPU-werk

Korte Python-stappen; I/O-wachttijden overlappen

Veel CPU-werk

Lange Python-stappen laten gereedstaande antwoorden wachten

0.0 / 40 illustratieve eenheden

Voor Python-services bij OpenAI is het naast standaardstatistieken voor gebruik en verzadiging van geheugen, CPU, netwerk en schijf essentieel om ook de asyncio-loop en de belasting ervan te bewaken en de service daarop af te stemmen.

Door periodiek achtergrondtaken in te plannen en het verschil tussen de verwachte en werkelijke uitvoeringstijd vast te leggen, kunnen we de planningsvertraging van de eventloop in realtime empirisch meten. Bij hoge benutting en veel kostbare taken zijn zelfs bescheiden aantallen gelijktijdige verzoeken per proces voldoende voor aanzienlijke planningsjitter, tot honderden milliseconden en in sommige uitzonderlijke gevallen meerdere seconden.

Daarom laten we elk proces slechts een klein aantal gelijktijdige verzoeken verwerken en schalen we in plaats daarvan het aantal Python-workerprocessen enorm op.

Staartlatentie in onze featureflagconfiguraties verlagen

Bij onze eerste servicelancering ontdekten we via live CPU-profilering een hoofdoorzaak van hoge asyncio-vertraging en de daaruit voortvloeiende hoge staartlatenties: het periodiek verwerken van de JSON voor onze featureflagconfiguraties via Statsig, een tool voor het beheren van featureflags, A/B-tests en meer.

Statsig was standaard ingesteld om elke minuut zonder jitter bijgewerkte configuraties op te halen, waarbij de configuratie alle productieregels van alle services bevatte. Elders was de architectuurkeuze gemaakt om per pod maximaal acht Python-processen uit te voeren, voor een hoger CPU-gebruik en lagere latentietijden. Samen betekende dit dat er in elke pod iedere minuut een moment was waarop alle workers stopten met het verwerken van lopende verzoeken en hun CPU-cycli in plaats daarvan besteedden aan het verwerken van een enorm configuratiebestand.

Toen CPU-profilering ons naar de hoofdoorzaak had geleid, was de oplossing eenvoudig: een kleinere, gerichte configuratie implementeren, het vernieuwingsinterval verlengen en wat jitter aan dit soort achtergrondtaken toevoegen.

Belastingen verdelen en connection pools beheren

Om de asyncio-vertraging laag te houden, moeten verzoeken ook goed over serverprocessen worden verdeeld. Zonder de juiste afstemming kan connection pooling dit juist tegenwerken.

Bij connection pooling aan de clientzijde kan één clientproces dat veel gelijktijdige verzoeken doet slechts een handvol serververbindingen opzetten en daardoor alle belasting naar slechts enkele processen sturen. Voordat we onze load balancing aanpasten, varieerde de benutting van onze service sterk. Sommige uitschieters onder de processen verwerkten vijf tot tien keer zoveel gelijktijdige verzoeken als gemiddeld.

We ontdekten dit toevallig tijdens een incident waarbij een deel van de processen nog lang na de verkeerspiek slechter bleef presteren, hoewel we de client die een deel van onze service overbelastte al hadden gestopt. We zagen zelfs dat de prestaties van die processen steeds verder verslechterden en dat ze steeds meer verzoeken ontvingen, totdat we ze opnieuw opstartten. Zodra een pod overbelast raakte, zorgde bepaald gedrag ervoor dat steeds meer verkeer aan die pod werd toegewezen. Dit was een soort storing die sommige teamgenoten goed kenden uit eerder werk: metastabiele uitval(opent in een nieuw venster).

We vermoedden dat de connection pool de oorzaak was. We testten dit door de maximale duur voor verbindingshergebruik te beperken. Dat beperkte inderdaad de verslechtering en bevestigde dat ons onderzoek de juiste richting op ging. Nader onderzoek wees uit dat de TCPConnector van aiohttp in Python standaard LIFO gebruikt voor verbindingshergebruik: de laatst teruggekeerde verbinding wordt voor het volgende verzoek geselecteerd. Normaal is dat een redelijke standaard: door recente verbindingen te hergebruiken, kunnen de extra verbindingen die voor een verkeerspiek zijn gemaakt wegens inactiviteit verlopen, zodat het onderhoud ervan minder overhead oplevert. In ons geval veroorzaakte dit metastabiele uitval. Tijdens een verzoekpiek kwamen verbindingen van tragere, overbelaste servers later terug in de pool. Daardoor werden ze vaker voor volgende verzoeken geselecteerd en concentreerde steeds meer verkeer zich op pods die het al moeilijk hadden. Door de connection pool aan te passen voor hergebruik met FIFO, doorbraken we deze feedbacklus en verminderden we ook de variatie in verzoeken tijdens de stabiele toestand.

Figuur 04A · Connection pooling aan de clientzijde

LIFO stuurt nieuw werk terug naar het trage proces

Na een piek in verzoeken sturen tragere servers hun verbindingen als laatste terug naar de pool. Door LIFO concentreert meer werk zich op diezelfde tragere servers.

Een eerste piek bereikt A, B en het tragere proces C.

Figuur 04B · Connection pooling aan de clientzijde

FIFO doorbreekt de feedbacklus van verbindingshergebruik

FIFO houdt na een piek meer verbindingen actief, maar verdeelt workloads eerlijk over alle servers.

Een eerste piek bereikt A, B en het tragere proces C.

Tegenwoordig vertrouwen we binnen de OpenAI-infrastructuur vooral op Istio en Envoy voor connection pooling en betere load-balancingstrategieën die rekening houden met de serverbelasting, zodat we dit probleem volledig vermijden.

Voorkomen dat downstreambronnen worden overspoeld

Een neveneffect van optimalisatie voor een lage asyncio-vertraging en het grote aantal Python-processen is dat downstreamafhankelijkheden heel gemakkelijk worden overspoeld door het enorme aantal verbindingen, ook wel een "thundering herd" genoemd.

Een normale dagelijkse implementatie kan aanzienlijke CPU-onrust door het steeds vernieuwen van verbindingen veroorzaken als die niet bewust langzaam wordt uitgevoerd. Ook kan een verbindingslek het netwerk platleggen door de NAT-gateway te verzadigen. Dit zijn ook bij andere services geen ongebruikelijke problemen. Door een orde van grootte meer processen ligt de drempel echter veel lager. Daardoor raken netwerkbronnen vaak verzadigd terwijl clients op basis van alleen de doorvoer niet verwachten dat ze dit bij een constante belasting moeten kunnen verwerken.

We vertrouwen ook op Envoy om onze verbindingsconsolidatie te maximaliseren. We gebruiken Envoy om de HTTP/1-verbindingen van Python te upgraden naar HTTP/2 en zo multiplexing te benutten. Vervolgens poolt Envoy die verbindingen en verlengt het hun levensduur. Envoy biedt ons ook één centrale plek voor snelheidslimieten en circuitbreakers, die in elk afzonderlijk Python-proces minder effectief zouden zijn.

Figuur 05 · Verbindingsconsolidatie

Dezelfde verzoeken, minder verbindingen

Connection pooling en multiplexing van HTTP/2-verbindingen helpen de verbindingsbelasting op downstreamsystemen te verlagen.

VerzoekAntwoordInactieve keep-alive

Waarom Habitat minder doet

Een reden waarom we Python zo ver konden opschalen, was de beperkte API van Habitat, die de kosten per verzoek voorspelbaar houdt. In plaats van clients willekeurige SQL-query's te laten samenstellen die grote tabelscans of joins over veel tabellen kunnen veroorzaken, biedt Habitat een eenvoudige NoSQL-API. Het ontbreken van een krachtige API is een bewuste afweging in het ontwerp van Habitat.

We optimaliseren voor eenvoudige, voorspelbare verzoeken die steeds evenveel werk vergen. Onze ervaring is dat zulke systemen aanzienlijk eenvoudiger op te schalen zijn en dat er moeilijk fouten mee te maken zijn of misbruik van kan worden gemaakt. Verzoeken met een onvoorspelbare fan-out zijn operationeel gevaarlijk: ze bemoeilijken isolatie en load balancing en veroorzaken plotselinge latentiepieken waarop zowel de service als de clients moeilijk kunnen worden geschaald.

Voordat we overstapten op Habitat en Azure Cosmos DB, werden de meeste onlinegegevens van OpenAI in Postgres opgeslagen. Destijds konden we alle wijzigingen aan query's en schema's eenvoudig beoordelen, zodat ze zich correct gedroegen en geïndexeerde gegevens gebruikten voordat ze naar productie gingen. Naarmate het team en de producten groeiden, werd dit al snel onbeheersbaar. Het veroorzaakte geregeld storingen waarbij één nieuwe, kostbare query op een veelgebruikt pad de database platlegde.

Het probleem is de onevenwichtige kostenverdeling: het is goedkoop en eenvoudig om SQL-query's te schrijven die kostbaar en moeilijk uit te voeren zijn. In Habitat voorkomen we dit en maken we kostbare query's aan de clientzijde overduidelijk. Er zijn geen onbegrensde query's die Habitat kunnen overbelasten. Voor complexe joins en graftraversals moeten productteams bovendien een deel van het zware werk uitvoeren, wat efficiëntere ontwerpen bevordert.

Habitat biedt een NoSQL-API rond door clients gedefinieerde object- en randtypen, geïnspireerd op TAO(opent in een nieuw venster). Clients definiëren vooraf objecten en randen en hun onderlinge relaties, maar niet de inhoud van elk type. De resulterende relaties lijken op een graaf, maar Habitat zelf ondersteunt geen gebruikelijke graftraversalquery's, behalve query's op directe randen van een specifiek object.

We partitioneren deze graaf zodat elk object en de bijbehorende randen samen in een partitie op opslagniveau staan. Op databaseniveau proberen we echter niet doelbewust om objecten samen te plaatsen met de externe objecten waarnaar hun randen verwijzen. Daardoor kan het model gemakkelijk worden gepartitioneerd voor horizontale schaalbaarheid, maar zijn graftraversals inefficiënt: elke stap tussen objecten kan gegevens moeten ophalen uit twee totaal verschillende Azure Cosmos DB-accounts in verschillende regio's.

Voor clients met complexere querybehoeften bieden we via Rockset wel een offline secundaire weergave van Habitat. We gebruiken Change Data Capture (CDC) om wijzigingen vanuit de onlineopslag vrijwel realtime naar geïsoleerde Rockset-instanties te streamen. Elk clientteam is verantwoordelijk voor het schalen van de eigen Rockset-instantie voor complexe query's.

Het inrichten van Rockset zorgt voor extra frictie bij onze clients, maar is volgens ons op dit moment de juiste afweging: eenvoudige query's zijn de standaard, met een uitweg voor wie complexe query's nodig heeft. Dit ontwerp isoleert onze onlineopslag van leesintensieve analytische en zoekworkloads.

Migreren van Python naar Rust

Door de herschrijving van Python een jaar uit te stellen, konden we tijdens onze hypergroei focussen op urgentere uitdagingen met meer impact. Nu het platform volwassener werd, onze groei bleef versnellen en dit qua aantal cores de op een na grootste service van OpenAI was en qua Envoy-voetafdruk de vierde, was het eindelijk tijd om Python achter ons te laten. Op het hoogtepunt hielp Python ons meer dan 20 miljoen verzoeken per seconde te verwerken.

In het tweede kwartaal van 2026 konden we met slechts twee engineers, Codex en GPT‑5.5 de volledige service in Rust herschrijven. Deze nieuwe Rust-service verwerkt nu 95% van onze productieverzoeken. De komende weken faseren we Python volledig uit. Uit onze gegevens blijkt dat de Rust-service zes keer zo CPU-efficiënt en vijftien keer zo geheugenefficiënt is als de Python-versie, met aanzienlijk lagere gemiddelde en staartlatenties. In een toekomstig blogbericht delen we meer lessen.

Onze databaselaag optimaliseren: Azure Cosmos DB

De Python-service, en nu de Rust-service, is slechts één aspect van Habitat. In deel II van deze serie over hoe we onze onlineopslag snel hebben opgeschaald voor meer dan 1 miljard ChatGPT‑gebruikers, bespreken we de opslaglaag en hoe Habitat meer dan 500 petabyte en ruim 70 miljoen verzoeken per seconde verwerkt.

Wil je werken aan OLTP-systemen op grensverleggende schaal en spreekt dit soort engineering je aan? Bekijk dan deze vacature in ons team.

Auteurs

Jon Lee, Chaomin Yu, Ben Ries