Voorbij gebruikslimieten: de toegang tot Codex en Sora opschalen
Door Jonah Cohen, lid van de technische staf
Het afgelopen jaar zijn zowel Codex als Sora in rap tempo omarmd, waarbij het gebruik onze oorspronkelijke verwachtingen snel overtrof. We zien daarbij een terugkerend patroon: gebruikers gaan enthousiast aan de slag, ontdekken de waarde, maar lopen vervolgens tegen gebruikslimieten aan.
Gebruikslimieten helpen om de vraag te spreiden en eerlijke toegang te garanderen. Maar als gebruikers net productief aan het werk zijn, is zo'n harde stop frustrerend. We zochten naar een manier om gebruikers door te laten gaan, zonder de systeemprestaties of het vertrouwen in onze aanpak in gevaar te brengen.
Om dit op te lossen, bouwden we een realtime toegangs-engine die het gebruik meet. Een van de lagen in dat systeem is de mogelijkheid om credits te kopen. Wanneer gebruikers hun limiet bereiken, kunnen ze dankzij deze credits onze producten blijven gebruiken door hun saldo aan te spreken.
Hieronder ligt een complex systeem dat limieten, realtime verbruiksmeting en creditsaldi samenbrengt in één toegangsmodel. Dit artikel beschrijft waarom het opschalen van Codex en Sora een nieuwe blik op toegangscontrole vereiste, hoe een aantoonbaar correct systeem limieten en credits combineert per verzoek, en hoe dat fundament nu extra toegang mogelijk maakt voor beide producten.
Als we uitzoomen, dwingen traditionele toegangsmodellen je vaak tot een keuze:
- Gebruikslimieten kunnen in het begin nuttig zijn, maar zorgen voor een slechte ervaring als ze op zijn: de gebruiker krijgt simpelweg de boodschap 'kom later terug'
- Op gebruik gebaseerde facturering is flexibel, maar laat gebruikers betalen vanaf de eerste token: niet ideaal om vroege verkenning en experimenten te stimuleren
Voor Codex en Sora voldeden geen van de bestaande opties. Als we de gebruikslimieten simpelweg zouden verhogen, zouden we grip verliezen op de spreiding van de vraag en eerlijke toegang. Bovendien zouden we capaciteit tekortkomen om iedereen te bedienen. Als we volledig zouden vertrouwen op asynchrone facturering achteraf, zou dit leiden tot vertragingen, onbedoelde overschrijdingen of afstemmingsproblemen: precies de zaken die het meest storen wanneer gebruikers het actiefst zijn.
We hadden een hybride systeem nodig dat realtime limieten combineert met pay-as-you-go-toegang:
Dit systeem moest:
- Handhaaf gebruikslimieten totdat deze zijn bereikt
- Ga naadloos over op credits binnen hetzelfde verzoek
- Realtime beslissingen nemen
- Extreem nauwkeurig en controleerbaar zijn bij het bijhouden van creditverbruik
Een van de belangrijkste conceptuele verschuivingen die we maakten, was het modelleren van toegang als een beslissingswaterval. In plaats van te vragen 'Is dit toegestaan?', vragen we: 'Hoeveel is toegestaan, en vanuit welk saldo?' Bij het tellen van het gebruik doorloopt het systeem de volgende volgorde:
Dit model weerspiegelt hoe gebruikers het product daadwerkelijk ervaren. Gebruikslimieten, gratis niveaus, credits, promoties en zakelijke rechten zijn allemaal lagen in dezelfde beslisboom. Voor de gebruiker voelt het niet alsof hij van systeem wisselt; hij blijft Codex en Sora gewoon gebruiken. Daarom lijken credits onzichtbaar: ze zijn slechts een onderdeel van de 'waterval'.
We hebben externe facturerings- en meetplatforms overwogen voor het beheren van creditverbruik. Hoewel deze geschikt zijn voor facturatie en rapportage, voldeden ze niet aan twee cruciale eisen:
Wanneer een gebruiker een limiet bereikt en credits beschikbaar heeft, moet het systeem dit onmiddellijk weten. Niet-gegarandeerde of vertraagde metingen leiden tot onverwachte blokkades, inconsistente saldo's en onterechte afschrijvingen. Voor interactieve producten zoals Codex en Sora zijn dergelijke fouten direct zichtbaar en frustrerend.
We moesten ook transparantie bieden bij elke uitkomst:
- Waarom een verzoek is toegestaan of geblokkeerd
- Hoeveel er is verbruikt
- Welke limieten of saldi zijn toegepast
Deze functionaliteit moest nauw geïntegreerd zijn in onze beslisstructuur, en niet geïsoleerd in een apart facturatiesysteem dat slechts een deel van het plaatje ziet. Om toegang te bieden zonder het vertrouwen te schaden, hadden we volledige controle nodig over correctheid, timing en inzichtelijkheid. Daarom kozen we voor een interne oplossing.
Hiervoor bouwden we een gedistribueerd gebruiks- en saldosysteem, specifiek ontworpen voor synchrone toegangsbeslissingen.
Op hoofdlijnen doet het systeem het volgende:
- Houdt het gebruik per gebruiker en per functie bij
- Handhaaft tijdvensters voor gebruikslimieten
- Beheert realtime creditsaldi
- Schrijft saldi idempotent af via een asynchrone streaming-processor
Elk verzoek doorloopt één evaluatiepad dat in real time beslist hoeveel gebruik is toegestaan door synchroon gebruikslimieten aan te spreken en (indien nodig) te controleren op voldoende credits. Vervolgens wordt één definitieve uitkomst teruggestuurd, terwijl de afschrijving van credits asynchroon wordt verwerkt. Dit zorgt voor consistent gedrag in alle producten en voorkomt dubbele logica bij verschillende teams.
Een van de belangrijkste ontwerpprincipes van dit systeem is dat we moeten kunnen bewijzen dat onze facturering klopt. Dit weerspiegelt de oorsprong van onze credit-ondersteuning, die begon bij zakelijke klanten. In het systeemdiagram hierboven zien we drie afzonderlijke datasets die met elkaar verbonden zijn:
- Productgebruik-events: Wat de gebruiker daadwerkelijk deed
- Afreken-events: Wat we de gebruiker in rekening brengen voor hun gebruik
- Saldo-updates: Hoeveel we het creditsaldo van de gebruiker hebben aangepast en waarom
Deze datasets zijn geen toevallig bijproduct: ze sturen het systeem aan, waarbij elke dataset de volgende in gang zet. Door onderscheid te maken tussen wat er gebeurde, de bijbehorende kosten en wat we daadwerkelijk hebben afgeschreven, kunnen we elke laag onafhankelijk controleren, opnieuw verwerken en verifiëren. Dit is een bewuste keuze. We geven prioriteit aan aantoonbare correctheid, ten koste van een lichte vertraging in de saldo-updates. Hoe we dit hebben bereikt:
- Events voor productgebruik worden gepubliceerd voor alle gebruikersactiviteit, ongeacht of dit credits kost. Dit zorgt voor een audit trail van gebruikersactiviteit en stelt ons in staat uit te leggen waarom we wel of geen credits in rekening hebben gebracht.
- Elk event bevat een stabiele idempotency key. Hierdoor kunnen nieuwe pogingen, replays of herstarts van werkprocessen nooit leiden tot een dubbele afschrijving. Hiermee kunnen we ook offline batch-controles uitvoeren om ons werk te verifiëren.
- We voeren saldo-updates asynchroon (maar bijna realtime) uit in plaats van synchroon, om zo een audit trail te creëren. We accepteren een kleine vertraging bij het bijwerken van het saldo. Zo kunnen we bewijzen dat het systeem goed werkt en gebruikers garanderen dat we niet verkeerd factureren. Als we door die korte vertraging per ongeluk meer verbruiken dan het saldo van de gebruiker toelaat, nemen we die kosten voor onze rekening. We kiezen voor aantoonbare correctheid en vertrouwen boven strikte handhaving.
- We verlagen het creditsaldo en voegen een Balance Update-record toe in één enkele atomaire databasetransactie. Saldo-updates worden per account serieel verwerkt, zodat gelijktijdige verzoeken nooit in een race condition terechtkomen om dezelfde credits uit te geven. Het Balance Update-record bevat zowel het afgeschreven bedrag als een verwijzing naar het monetarisatie-event dat de update veroorzaakte. Door dit in één databasetransactie te verpakken, garanderen we een audit trail voor elke aanpassing van het creditsaldo.
Al deze zorgvuldigheid dient één doel: toegang eenvoudig en veilig maken. Wanneer mensen aan het creëren of programmeren zijn, zouden ze zich niet moeten afvragen of een verzoek slaagt, of ze te veel betalen en of hun saldo wel klopt. Door gebruik, facturatie en saldo's aantoonbaar correct te maken, bieden we gebruikers een systeem dat niet afleidt van hun ervaring. Hierdoor kunnen we harde stops vervangen door ononderbroken toegang. Het maakt credits bruikbaar tijdens het echte werk, in plaats van dat ze alleen achteraf op een factuur verschijnen.
Het leidende principe achter onze aanpak is het beschermen van het momentum van de gebruiker. Elke architectonische beslissing staat in dienst van de gebruikerservaring. Realtime saldo's voorkomen onnodige onderbrekingen, atomair verbruik voorkomt dubbele afschrijvingen en uniforme toegangslogica zorgt voor voorspelbaar gedrag. Het resultaat is dat mensen langer kunnen doorwerken, zaken grondiger kunnen uitdiepen en projecten verder kunnen brengen zonder harde stops of gedwongen abonnementswijzigingen.
Wanneer gebruikers gefocust zijn, moet het systeem hen verder helpen en niet in de weg staan. Limieten en credits verdwijnen hierdoor naar de achtergrond.
Om die ervaring te bouwen, moesten we toegang, gebruik en facturatie behandelen als één geïntegreerd systeem. We moesten infrastructuur bouwen die correctheid beschouwt als een essentiële producteigenschap. Ditzelfde fundament kan in de loop der tijd worden uitgebreid naar meer producten; Codex en Sora zijn nog maar het begin.


