Aller au contenu

Compter ce que le client consomme

Un client hébergé consomme des ressources, et il faut bien les compter. Le noyau ne mesure pas des processeurs : il compte des crédits de calcul, une unité portable qui vaut la même chose sur un portable et sur un serveur.

crédits = base + durée_ms // ms_par_crédit

Exécuté avec les valeurs par défaut (ms_par_crédit = 100, base = 1) :

requête instantanée : 1 crédit
requête de 350 ms : 4 crédits
job de 12 s : 121 crédits

Une base plate pour que le travail instantané coûte quand même quelque chose, un terme de durée pour que le travail long coûte plus. Le temps écoulé est un substitut du coût réel, pas une mesure de processeur : le choix est assumé, il rend le compteur portable et prévisible.

Les lectures sont gratuites

Seules les écritures et les jobs sont comptés. GET, HEAD, OPTIONS ne coûtent rien.

Ce n’est pas de la générosité, c’est une correction : un écran d’administration éclate en plusieurs dizaines d’appels de lecture, donc compter les lectures transformait un budget de calcul en plafond de nombre de requêtes, qu’une simple navigation épuisait. Une démonstration atteignait 115 % du plafond sans une seule écriture.

Le plafond, et ce qu’il fait au dépassement

assert_within_compute_quota(engine, period="2099-01", credits_delta=30)

Exécuté sur une fenêtre à 60 crédits consommés pour un plafond de 100 :

une écriture à 30 crédits : autorisée
une écriture à 50 crédits : refusée -> compute quota exceeded for 2099-01: 110 > 100

Côté HTTP, le refus est un 402 Payment Required sur les écritures, et les lectures continuent de passer.

Et pour la même raison, la barrière échoue ouverte : si la table de quota est illisible ou que la base hoquette, la requête passe. Un incident d’infrastructure de facturation ne doit pas mettre l’API par terre.

Un plafond absent n’est pas un plafond à zéro

sans plafond : même un milliard de crédits passe

Le défaut est non plafonné. C’est la licence signée qui pousse la valeur (max_compute_credits) dans le sous-système à l’installation : le plafond appartient au contrat, pas au code.

Calibrer sur ses propres données

Les trois nombres sont des paramètres par client (metering.*), donc réglables sans toucher au code. Et l’outil les recommande à partir des durées réellement enregistrées :

$ kewos metering recommend --database-url ...
samples (recorded job runs): 872
median duration: 47 ms p90: 1005 ms
current ms_per_credit=100 request_base=1 job_base=1
recommended ms_per_credit=9 request_base=1 job_base=1

Sur cette instance, la médiane des jobs est à 47 ms : avec la granularité par défaut, presque tous les jobs coûtent leur base et le terme de durée ne dit rien. La recommandation resserre la granularité pour que la médiane retombe sur la cible. recommend ne change rien ; apply-recommendation persiste.

Une purge mensuelle taille les fenêtres passées au-delà de l’horizon de rétention : le compteur ne grossit pas indéfiniment.