Salta al contingut principal
OpenAI

11 de setembre del 2026

Enginyeria

Escalar ràpidament l'emmagatzematge en línia per atendre més de mil milions d'usuaris de ChatGPT

Com vam adaptar Habitat, la nostra plataforma d'emmagatzematge d'aplicacions en Python, per gestionar un creixement sense precedents.

Per Jon Lee, Chaomin Yu i Ben Ries, membres del personal tècnic

S'està carregant…

Tots els productes d'OpenAI depenen d'un accés ràpid i fiable a les dades, tant si algú inicia la sessió com si consulta la configuració de Codex o comença una conversa nova a ChatGPT. Cadascuna d'aquestes accions pot requerir moltes consultes de dades independents abans que el producte pugui respondre. Si aquestes sol·licituds són lentes, el producte sembla lent. Si fallen, el producte deixa de funcionar completament.

Habitat és la plataforma d'emmagatzematge en línia que vam crear perquè els productes d'OpenAI puguin accedir amb rapidesa i fiabilitat a la informació necessària. Habitat ja gestiona més de 70 milions de sol·licituds per segon i dona suport a productes utilitzats per més de mil milions de persones cada setmana en gairebé 40 regions geogràfiques. Habitat es va llançar inicialment per donar suport als GPT a DevDay 2023, com una biblioteca Python senzilla al client connectada a una única base de dades. Avui és un sistema distribuït complex que gestiona més de 500 petabytes de dades.

Figura 01 · Què és Habitat?

Plataforma d'emmagatzematge en línia

Habitat és la plataforma d'emmagatzematge en línia que vam crear perquè els productes d'OpenAI puguin accedir amb rapidesa i fiabilitat a la informació necessària.

  • Sol·licitud
  • Resposta
  • Canvis (CDC)

Clients

Plataforma d'emmagatzematge en línia

Recursos d'emmagatzematge

  • ChatGPT
  • API
  • Codex
  • Serveis interns
  • I més

Habitat

  • Emmagatzematge en memòria cauMemòries cau
  • Polítiques de llistes de control d'accésAutorització
  • Col·locació i ubicació de les dadesUbicació de les dades
  • XifratgeSeguretat de les dades
  • AïllamentMulticlient
  • Limitació de freqüènciaConformació de sol·licituds
  • EncaminamentConsulta de l'esquema · Ubicació de les dades
  • Azure Cosmos DBEmmagatzematge en línia
  • NanobaseEmmagatzematge en línia
  • ValkeyMemòries cau
  • Emmagatzematge de blobsRecursos d'emmagatzematge
Serveis CDCCaptura de dades de canvis
  • Databricks
  • Rockset
  • Kafka
  • I més

Crear i operar infraestructura a aquesta escala no és gens fàcil, però tampoc especialment difícil. El que feia única la nostra situació era la velocitat sense precedents amb què havíem d'escalar per respondre a l'enorme creixement d'usuaris i demanda de producte mentre construíem una plataforma madura. Sovint, els enginyers de sistemes dissenyen per a una escala deu vegades superior i esperen que aguanti uns anys mentre es preparen per al següent salt de deu vegades. En el nostre cas, hem crescut més de deu vegades interanualment durant els darrers tres anys. Per això, crear i operar Habitat ha estat una successió i seqüenciació de decisions tàctiques: entendre cada component al nivell més baix per aprofitar al màxim la pila existent, mentre evitem colls d'ampolla de capacitat d'emmagatzematge i còmput per guanyar temps per a inversions fonamentals.

  • Més de 70 M

    sol·licituds per segon

  • Més de mil milions

    persones cada setmana

  • Més de 500 PB

    dades

A mesura que OpenAI creixia, Habitat havia de créixer al mateix ritme: primer, assolint prou fiabilitat per al trànsit crític dels productes; després, prou velocitat per als usuaris d'arreu del món; i finalment, operant amb agilitat a escala massiva. Aquesta entrada és la primera d'una sèrie de dues parts sobre com vam escalar l'emmagatzematge en línia. En aquesta entrada expliquem com va evolucionar Habitat, per què el vam convertir d'una biblioteca en un servei i com vam portar un servei escrit en un llenguatge poc habitual per a servidors —Python— fins a convertir-lo en una capa fiable de la plataforma d'emmagatzematge.

En una entrada futura detallarem com vam garantir la fiabilitat multiclient a escala, l'estratègia per capes per optimitzar el rendiment de lectura i com vam ampliar la col·laboració amb Azure Cosmos DB per gestionar amb fiabilitat una demanda sense precedents.

Què és Habitat?

Habitat va néixer d'una idea senzilla: els enginyers de producte no haurien d'haver de pensar en la gestió de bases de dades. Habitat es va llançar inicialment per donar suport als GPT a DevDay 2023 com una petita biblioteca Python que interactuava amb el servidor principal de ChatGPT. Admetia un petit conjunt d'operacions que, internament, es corresponien amb l'aplicació de base de dades Azure Cosmos DB.

La funció de la biblioteca era oferir als equips de producte una manera senzilla d'emmagatzemar i recuperar dades sense haver de dominar els detalls subjacents. Habitat s'encarregava de la feina necessària: determinar el tipus de dades, d'on havien de venir o on havien d'anar, si la sol·licitud estava permesa, etc.

Els enginyers de producte no s'han de preocupar de consultar l'esquema, l'encaminament, l'autorització, el xifratge, la serialització, la conformació de sol·licituds ni l'agrupació de connexions. Ni tan sols havien de considerar d'on provenien les dades: Azure Cosmos DB, memòries cau o altres tipus d'emmagatzematge.

Figura 02 · Servei Habitat

Flux simplificat de sol·licituds d'Habitat

En desacoblar la lògica d'emmagatzematge en un servei independent, vam establir un únic punt de control per als desplegaments, l'observabilitat i les millores de la plataforma.

  • Sol·licitud
  • Resposta

Client

OpenAI

Azure Cosmos DB

SDK client d'Habitat
envoy
  • habitat-serviceprocés 1
  • habitat-serviceprocés 2
  • habitat-serviceprocés 3
habitat-envoy
  • habitat-cosmos-db-us0
  • habitat-cosmos-db-us1
  • habitat-cosmos-db-eu0

Aquesta biblioteca Python funcionava bé i Habitat es va adoptar ràpidament entre els enginyers de producte d'OpenAI, malgrat que no hi havia cap iniciativa central coordinada per abandonar l'ús autogestionat de Postgres i Azure Cosmos DB.

A mesura que evolucionaven les necessitats del producte, els desenvolupadors podien afegir fàcilment a la biblioteca compartida funcions com la memòria cau al client, la compressió o el xifratge.

Crear un servei que admeti millor diversos productes complexos

A mitjan 2025, Habitat havia arribat als límits com a implementació al client. A mesura que la capa d'Habitat es feia més complexa i augmentava el nombre de serveis d'OpenAI, els canvis de protocol retrocompatibles s'havien tornat inviables.

En un cas, volíem reduir l'abast de l'impacte d'una interrupció en una sola regió sobre els conjunts de dades més crítics migrant-los a diversos comptes d'Azure Cosmos DB distribuïts regionalment. Aquest canvi exigia afegir lògica d'encaminament al client, desactivada mitjançant una marca de funcionalitat, garantir-ne el desplegament a tots els clients i després activar la marca.

Coordinar els desplegaments entre desenes de serveis i treballar amb cada equip per implementar-los va trigar dies. Abans d'activar-ho, ens vam adonar que volíem introduir una duplicació oculta per verificar que la lògica de fragmentació fos correcta. Desplegar-ho va requerir un parell de dies més. I corregir un error en una cosa que vam descobrir que no era correcta? Un parell de dies més. Finalment, estàvem preparats per activar la marca, però un equip va revertir el seu servei, per motius aliens, a una versió anterior i defectuosa del client, cosa que va provocar justament la interrupció que tant ens havíem esforçat a evitar.

Els canvis a la biblioteca client requerien una coordinació complexa entre desenes de serveis, un procés cada cop més fràgil, ineficient i propens a errors operatius. Per reduir aquesta dispersió operativa en futurs desplegaments, vam decidir convertir Habitat en un servei propi.

En desacoblar la lògica d'emmagatzematge en un servei independent, vam establir un únic punt de control per als desplegaments, l'observabilitat i les millores de la plataforma. En lloc de gestionar actualitzacions fragmentades, podíem implementar millores de manera centralitzada i beneficiar immediatament tots els productes d'OpenAI.

Un servei centralitzat també ens ofereix un únic punt de control on aplicar les garanties més sòlides de seguretat i privacitat de les dades. Al servei Habitat podem aplicar centralment les polítiques de control d'accés, registrar auditories i limitar l'accés als recursos d'emmagatzematge subjacents, com ara Azure Cosmos DB. Habitat té un paper essencial en la protecció de les dades dels usuaris i en la prevenció de l'accés no autoritzat per part d'actors externs, interns i agents.

Llançar un servei Python a gran escala

Sabíem que necessitàvem un servei, però encara no volíem migrar de Python, malgrat la sobrecàrrega addicional que comportava usar-lo com a servei. Fer servir Python per a un servei d'alt rendiment augmentava la latència de xarxa i afegia costos considerables d'escalat de CPU i memòria en comparació amb l'execució com a biblioteca local. A més, sabíem que les ineficiències de Python no serien acceptables a una escala 100 vegades superior, de manera que una reescriptura futura era gairebé inevitable.

Tanmateix, ho vèiem com una incursió estratègica en deute tècnic. Aleshores, el nostre objectiu principal no era optimitzar costos o recursos, sinó desencallar els desenvolupadors de producte i estabilitzar la plataforma. En acceptar a curt termini les contrapartides de rendiment d'un servei Python, vam poder prioritzar reptes més immediats, establir les API principals i crear una infraestructura sòlida.

També vam apostar, de manera calculada, que el ràpid progrés dels nostres models de programació simplificaria el camí tècnic en el futur. Vam apostar que, quan calgués migrar completament de Python, Codex i GPT farien viable la migració. Amb el temps, l'aposta va resultar encertada.

Executar Habitat com a servei Python no seria òptim pel que fa al rendiment, però era una opció necessària. Python ens permet avançar ràpidament, però això no volia dir que poguéssim actuar sense cautela i acceptar latències molt pitjors. Quan una sol·licitud mitjana d'usuari genera centenars de crides a la base de dades, l'usuari percep la més lenta. Hem constatat que el principal repte d'executar un servei Python a aquesta escala és gestionar les latències de cua.

Seguir el retard d'asyncio

Asyncio ajuda Python a executar simultàniament càrregues de treball limitades per E/S, però no permet esquivar el GIL de Python ni aporta paral·lelisme de CPU. A més d'intermediar sol·licituds amb molta E/S, Habitat assumeix moltes funcions i tasques en segon pla intensives en CPU: encaminament, compressió, xifratge, sumes de verificació, comprovació de l'estat dels serveis posteriors, duplicació oculta de sol·licituds i cobertura especulativa.

Amb tantes càrregues intensives en CPU i tasques en segon pla al servei, el retard de planificació d'asyncio pot dominar fàcilment la latència de cua de les sol·licituds. Abans d'ajustar el llançament inicial del servei, les traces de sol·licituds amb latència p99 o superior mostraven que, tot i que l'emmagatzematge posterior responia ràpidament, les sol·licituds sovint quedaven aturades esperant que es reprogramés la corrutina responsable d'analitzar la resposta.

Figura 03 · Seguiment del retard d'asyncio

La concurrència no és paral·lelisme de CPU

Asyncio de Python permet processar sol·licituds simultàniament, però només se n'executa una alhora al fil de CPU. Això té un gran impacte en les latències de les sol·licituds quan hi ha molta feina de CPU.

Processament de sol·licituds/respostes per CPULectura/escriptura de xarxa de PythonEspera de Cosmos

Càrrega de CPU baixa

Passos breus de Python; les esperes d'E/S se superposen

Càrrega de CPU alta

Els passos llargs de Python mantenen esperant les respostes preparades

0.0 / 40 unitats il·lustratives

En els serveis Python d'OpenAI, a més de mesurar les mètriques habituals d'ús i saturació de memòria, CPU, xarxa i disc, considerem essencial supervisar el bucle d'asyncio i el seu nivell d'activitat, i ajustar-lo en conseqüència.

En programar periòdicament tasques en segon pla i registrar la diferència entre el temps d'execució previst i el real, podem mesurar empíricament i en temps real el retard de planificació del bucle d'esdeveniments. Amb una utilització alta i moltes tasques costoses, fins i tot un nombre modest de sol·licituds simultànies per procés basta per generar variacions importants en la planificació, de centenars de mil·lisegons i, en alguns casos extrems, de diversos segons.

Per això, limitem cada procés a un nombre reduït de sol·licituds simultànies i, en canvi, ampliem massivament el nombre de processos de treball de Python.

Reduir una latència de cua en les configuracions de marques de funcionalitat

Durant el llançament inicial, el perfilatge de CPU del servei en producció ens va revelar una causa principal de l'elevat retard d'asyncio i de les latències de cua resultants: l'anàlisi periòdica del JSON de les configuracions de marques de funcionalitat mitjançant Statsig, una eina per gestionar aquestes marques, executar proves A/B i més.

Per defecte, Statsig estava configurat per consultar cada minut, sense variació aleatòria, si hi havia configuracions actualitzades, i la configuració incloïa totes les regles de producció de tots els serveis. D'altra banda, s'havia decidit executar fins a vuit processos Python per pod per augmentar l'ús de CPU i reduir les latències. Això implicava que, cada minut, en algun moment tots els processos de treball de cada pod deixaven de processar les sol·licituds en curs i dedicaven els cicles de CPU a analitzar un fitxer de configuració enorme.

Quan el perfilatge de CPU ens va permetre identificar l'arrel del problema, la solució va ser senzilla: desplegar una configuració més petita i específica, ampliar l'interval d'actualització i afegir variació aleatòria a aquestes tasques en segon pla.

Equilibri de càrregues i gestió dels grups de connexions

Per mantenir baix el retard d'asyncio, també és essencial equilibrar bé les sol·licituds entre els processos de servidor; sense els ajustos adequats, l'agrupació de connexions pot acabar anant-hi en contra.

Amb l'agrupació de connexions al client, un únic procés client que faci moltes sol·licituds simultànies pot establir només unes quantes connexions de servidor i, per tant, enviar tota la càrrega a només uns quants processos. Abans d'ajustar l'equilibri de càrrega, la utilització del servei variava molt: alguns processos de cua gestionaven entre cinc i deu vegades més sol·licituds simultànies que la mitjana.

Ho vam descobrir arran d'un incident fortuït en què, tot i haver aturat el client que sobrecarregava una part del servei, alguns processos van continuar degradats molt després de la ràfega de trànsit. De fet, vam observar que aquests processos patien una degradació descontrolada i rebien cada cop més sol·licituds fins que els reiniciàvem. Quan un pod se sobrecarregava, algun comportament hi fixava encara més trànsit. Era una mena d'error que alguns companys coneixien bé per feines anteriors: una fallada metastable(s'obre en una finestra nova).

Sospitàvem del grup de connexions i ho vam provar limitant la durada màxima de reutilització de les connexions. Això va limitar la degradació i va confirmar que la investigació anava ben encaminada. Una investigació posterior va revelar que TCPConnector d'aiohttp de Python reutilitza per defecte les connexions en ordre LIFO: per a la sol·licitud següent se selecciona la connexió retornada més recent. Normalment és una opció predeterminada raonable: reutilitzar les connexions recents permet que les connexions addicionals creades per gestionar ràfegues de trànsit caduquin per inactivitat i redueix el cost de mantenir-les. En aquest cas, ens va provocar una fallada metastable. Durant una ràfega, les sol·licituds enviades als servidors més lents i sobrecarregats retornaven les connexions al grup més tard i, per tant, les sol·licituds posteriors les seleccionaven més sovint, concentrant a poc a poc més trànsit als pods que ja tenien dificultats. Modificar el grup de connexions perquè reutilitzés les connexions en ordre FIFO va trencar aquest bucle de realimentació i també va reduir la variació de sol·licituds en estat estable.

Figura 04A · Agrupació de connexions al client

LIFO torna a enviar feina nova al procés lent

Després d'una ràfega de sol·licituds, els servidors més lents són els últims a retornar connexions al grup. LIFO afavoreix que es concentri més feina en aquests mateixos servidors lents.

Una ràfega inicial arriba a A, B i al procés C, que és més lent.

Figura 04B · Agrupació de connexions al client

FIFO trenca el bucle de realimentació de reutilització de connexions

FIFO manté més connexions actives després d'una ràfega, però equilibra la càrrega de manera justa entre tots els servidors.

Una ràfega inicial arriba a A, B i al procés C, que és més lent.

Avui depenem principalment d'Istio i Envoy per proporcionar agrupació de connexions i estratègies d'equilibri més conscients de la càrrega dels servidors a tota la infraestructura d'OpenAI, i així evitem completament aquest problema.

Evitar inundar els recursos posteriors

Un efecte secundari d'optimitzar per reduir el retard d'asyncio i tenir tants processos Python és que resulta molt fàcil saturar les dependències posteriors amb un nombre enorme de connexions, fenomen conegut com a «allau de sol·licituds».

Un desplegament diari normal, si no s'ajusta perquè sigui lent, pot provocar una rotació considerable de CPU a causa del reciclatge de connexions. O bé una fuita de connexions pot fer caure la xarxa saturant la passarel·la NAT. Aquests problemes tampoc no són estranys en altres serveis, però tenir un ordre de magnitud més de processos redueix molt el llindar que els desencadena i sovint satura recursos de xarxa que els clients no preveuen haver de gestionar en estat estable si només consideren el rendiment.

També confiem en Envoy per maximitzar la concentració de connexions. El fem servir per actualitzar les connexions HTTP/1 de Python a HTTP/2 i aprofitar-ne la multiplexació; després agrupem aquestes connexions i n'allarguem la vida útil. Envoy també ens ofereix un punt central on implementar límits de peticions i disjuntors, que serien menys efectius en cada procés Python independent.

Figura 05 · Concentració de connexions

Les mateixes sol·licituds, menys connexions

L'agrupació de connexions i la multiplexació de connexions HTTP/2 ajuden a reduir la càrrega de connexions als serveis posteriors.

Sol·licitudRespostaConnexió persistent inactiva

Per què Habitat fa menys

Un dels motius pels quals vam poder escalar tant Python va ser l'API restringida d'Habitat, que manté predictible el cost de les sol·licituds. En lloc de permetre que els clients construeixin consultes SQL arbitràries que puguin generar exploracions de taules grans o unions entre moltes taules, Habitat ofereix una API NoSQL senzilla. La manca d'una API potent és una contrapartida explícita del disseny d'Habitat.

Volem optimitzar sol·licituds senzilles, predictibles i de treball constant. Segons la nostra experiència, aquests sistemes són molt més fàcils d'escalar i és difícil configurar-los malament o fer-ne un mal ús. Les sol·licituds amb una expansió impredictible són perilloses operativament: compliquen l'aïllament i l'equilibri de càrrega, i introdueixen salts de latència difícils d'escalar tant per al servei com per als clients.

Abans de migrar a Habitat i Azure Cosmos DB, la major part de les dades en línia d'OpenAI s'emmagatzemava a Postgres. Aleshores era fàcil revisar tots els canvis en consultes i esquemes per comprovar que es comportaven correctament i operaven sobre dades indexades abans de desplegar-los en producció. A mesura que l'equip i els productes van créixer, això es va tornar ràpidament inassumible i va causar interrupcions freqüents: una sola consulta nova i costosa en una ruta crítica podia fer caure la base de dades.

El problema és el desequilibri de costos: escriure consultes SQL costoses i difícils d'executar és barat i fàcil. A Habitat ho evitem i fem que les consultes costoses siguin clarament visibles al client. No hi ha consultes sense límits que puguin sobrecarregar Habitat, i les unions complexes i els recorreguts de grafs exigeixen que els equips de producte assumeixin part de la feina pesada, cosa que afavoreix dissenys més eficients.

Habitat ofereix una API NoSQL basada en tipus d'objectes i arestes definits pel client, inspirada en TAO(s'obre en una finestra nova). Els clients predefineixen els objectes i les arestes i com es relacionen, però no el contingut de cada tipus. Les relacions resultants s'assemblen a un graf, però Habitat no admet les consultes habituals de recorregut de grafs, tret de les arestes directes d'un objecte concret.

Particionem aquest graf perquè cada objecte i les arestes corresponents comparteixin una partició d'emmagatzematge, però no fem cap esforç coordinat a escala de base de dades per col·locar junts els objectes i els objectes remots als quals apunten les seves arestes. Així, el model es particiona fàcilment per escalar horitzontalment, però els recorreguts de grafs són ineficients perquè qualsevol salt entre objectes pot requerir obtenir dades de dos comptes d'Azure Cosmos DB completament diferents i ubicats en regions distintes.

Per als clients amb necessitats de consulta més complexes, oferim una vista secundària fora de línia d'Habitat mitjançant Rockset. Fem servir la captura de dades de canvis (CDC) per transmetre els canvis de l'emmagatzematge en línia a instàncies aïllades de Rockset gairebé en temps real. Cada equip client és responsable d'escalar la seva instància de Rockset per satisfer les necessitats de consulta complexes.

Aquest aprovisionament de Rockset afegeix fricció per als clients, però creiem que ara és la contrapartida adequada: fer que les consultes senzilles siguin l'opció predeterminada i oferir una via alternativa a qui necessiti consultes complexes. Aquest disseny aïlla l'emmagatzematge en línia de les càrregues analítiques i de cerca amb moltes lectures.

Migrar de Python a Rust

Ajornar un any la reescriptura de Python ens va permetre centrar-nos en reptes més urgents i rellevants durant la fase d'hipercreixement. Amb la plataforma més madura i el creixement encara accelerant-se, i com a segon servei d'OpenAI amb més nuclis —i quart pel desplegament d'Envoy—, finalment havia arribat el moment de deixar enrere Python. En el seu punt màxim, Python ens va ajudar a atendre més de 20 milions de sol·licituds per segon.

El segon trimestre de 2026, amb només dos enginyers, Codex i GPT‑5.5, vam poder reescriure tot el servei en Rust. Aquest nou servei Rust ja gestiona el 95 % de les sol·licituds de producció; durant les setmanes vinents retirarem completament Python. Les nostres dades mostren que el servei Rust és sis vegades més eficient en CPU i quinze vegades més eficient en memòria que la versió Python, amb latències mitjanes i de cua molt inferiors. Tenim previst compartir més aprenentatges en una futura entrada del blog.

Optimitzar la capa de base de dades: Azure Cosmos DB

El servei Python —i ara Rust— és només una faceta d'Habitat. A la segona part d'aquesta sèrie sobre com vam escalar ràpidament l'emmagatzematge en línia per atendre més de mil milions d'usuaris de ChatGPT, parlarem de la capa d'emmagatzematge i de com Habitat gestiona més de 500 petabytes i més de 70 milions de sol·licituds per segon.

Si vols treballar en sistemes OLTP a escala d'avantguarda i t'interessa aquesta mena d'enginyeria, consulta aquesta vacant del nostre equip.

Autors

Jon Lee, Chaomin Yu i Ben Ries