\n\n\n\n Le mie bollette Cloud sono troppo alte: cosa vedo ora - AgntMax \n

Le mie bollette Cloud sono troppo alte: cosa vedo ora

📖 12 min read2,213 wordsUpdated Apr 4, 2026

Ciao a tutti, Jules Martin qui, di nuovo su agntmax.com!

Oggi voglio parlare di qualcosa che mi sta dando fastidio, e probabilmente anche a molti di voi, da circa un anno: l’aumento progressivo dei costi dell’infrastruttura cloud, in particolare per quanto riguarda le funzioni serverless. Siamo stati tutti conquistati dal sogno del “paga per ciò che usi”, e per molto tempo è sembrato una realtà. Ma ultimamente, ho visto le bollette aumentare, a volte in modo inspiegabile, anche quando i modelli di traffico sembrano stabili. È come se fossimo stati spennati dal prezzo stesso della flessibilità che abbiamo abbracciato. Quindi, esploriamo qualcosa di molto specifico e attuale: Domare il Mostro Serverless: Svelare e Ridurre i Costi Nascosti di AWS Lambda.

Il mio viaggio in questo campo è iniziato circa sei mesi fa. Abbiamo un microservizio fondamentale che gestisce l’autenticazione degli utenti e la gestione delle sessioni. È costruito quasi interamente su AWS Lambda, API Gateway, DynamoDB e Cognito. Per lungo tempo, i costi erano perfettamente prevedibili. Poi, l’estate scorsa, la nostra bolletta AWS per quel servizio specifico è aumentata di circa il 15%. Nessuna nuova funzionalità, nessun picco di traffico significativo. Inizialmente l’ho attribuito a qualche fluttuazione stagionale o a un piccolo bug che non avevo ancora trovato. Ma quando è arrivata la bolletta del mese successivo, addirittura più alta, sapevo di dover indagare. Questo non era solo un’anomalia; era una tendenza, e ci stava costando soldi veri.

L’Illusione dei Tier “Gratuiti” e la Realtà delle Invocazioni “Minime”

Uno dei punti di forza del serverless, specialmente per startup o team più piccoli, è il generoso piano gratuito. E lo è! Un milione di invocazioni gratuite al mese per Lambda, oltre a una quantità significativa di tempo di calcolo. Il problema è che, man mano che la tua applicazione cresce, quelle invocazioni “gratuite” scompaiono più velocemente di una fetta di pizza a un meetup tecnologico. Ciò che spesso viene trascurato è il volume di invocazioni piccole, apparentemente irrilevanti, che si accumulano. Pensate ai cron job, ai controlli di salute interni o persino ai meccanismi di riprova da altri servizi. Ognuna di queste conta.

La mia indagine sul nostro servizio di autenticazione ha rivelato esattamente questo. Avevamo una funzione Lambda, chiamiamola auth-token-refresher, progettata per aggiornare periodicamente i token dei servizi interni. Era impostata per essere eseguita ogni cinque minuti. Sembra innocua, giusto? 288 invocazioni al giorno. Moltiplicalo per 30 giorni e hai 8.640 invocazioni al mese. Aggiungi i nostri ambienti di sviluppo, staging e produzione, e all’improvviso sono oltre 25.000 invocazioni solo per un piccolo compito di manutenzione. Avevamo una dozzina di tali funzioni. All’improvviso, le nostre invocazioni “minime” non erano più così minime.

Trovare i Colpevoli: Le Metriche di CloudWatch sono il Tuo Miglior Amico

Il primo passo per domare questa bestia è sapere dove vanno a finire i tuoi soldi. AWS CloudWatch è indispensabile qui. Non limitarti a guardare il pannello di fatturazione di alto livello; esplora le metriche specifiche per le tue funzioni Lambda.

Ecco su cosa mi sono concentrato:

  1. Invocazioni: Questa è la metrica più semplice. Alti conteggi di invocazioni per funzioni che non gestiscono traffico diretto da utenti sono segnali di allerta immediati.
  2. Durata: Quanto tempo dura ogni invocazione? Durate più lunghe significano costi di calcolo più elevati.
  3. Uso della Memoria: Stai sovraprovisionando la memoria per le tue funzioni? Paga per ciò che allocchi, non per ciò che usi.
  4. Percentuale di Errori: Alte percentuali di errori possono portare a ripetizioni, il che significa più invocazioni e cicli di calcolo sprecati.

Per il nostro auth-token-refresher, ho guardato alla sua metrica `Invocazioni`. E certo, stava funzionando come un orologio, ogni cinque minuti. La durata era minima, solo circa 50 ms. Ma il volume complessivo contribuiva al nostro costo di invocazione totale.

Esempio Pratico 1: Consolidare e Pianificare in Modo Intelligente

La soluzione per auth-token-refresher e diverse altre funzioni di manutenzione simili è stata sorprendentemente semplice: consolidamento. Invece di avere funzioni Lambda individuali attivate da eventi CloudWatch (o EventBridge al giorno d’oggi) su orari separati, ho creato un’unica Lambda chiamata “Maintenance Runner”.

Questo “Maintenance Runner” è attivato da una singola regola di evento CloudWatch, ad esempio, una volta all’ora. All’interno di questo runner, ho un semplice dispatcher che controlla l’ora attuale ed esegue i compiti necessari. Ad esempio:


import os
import datetime

def lambda_handler(event, context):
 current_hour = datetime.datetime.now().hour
 current_minute = datetime.datetime.now().minute

 # Compito 1: Refresh auth token (era eseguito ogni 5 minuti)
 if current_minute % 10 == 0: # Esegui ogni 10 minuti ora
 print("Eseguendo il refresh del token di autenticazione...")
 # Chiamata alla logica di refresh del token effettivo o a un’altra funzione interna
 refresh_auth_token()

 # Compito 2: Pulisci i log vecchi (era eseguito ogni ora)
 if current_hour % 1 == 0 and current_minute == 0: # Esegui all'inizio dell'ora
 print("Eseguendo la pulizia dei log...")
 cleanup_old_logs()

 # Compito 3: Controlla lo stato del servizio esterno (era eseguito ogni 30 minuti)
 if current_minute == 0 or current_minute == 30:
 print("Controllando lo stato del servizio esterno...")
 check_external_service()

 return {
 'statusCode': 200,
 'body': 'Compiti di manutenzione eseguiti.'
 }

def refresh_auth_token():
 # ... logica effettiva di refresh del token ...
 pass

def cleanup_old_logs():
 # ... logica effettiva di pulizia dei log ...
 pass

def check_external_service():
 # ... logica effettiva di verifica del servizio esterno ...
 pass

Questo semplice cambiamento ha immediatamente ridotto il numero di invocazioni per questi compiti di manutenzione da centinaia di migliaia al mese a poche migliaia. I risparmi sui costi erano tangibili, non solo in termini di invocazioni Lambda, ma anche per quanto riguarda l’assunzione dei log di CloudWatch e le chiamate a API Gateway (se alcune di queste erano esposte tramite API Gateway).

La Trappola della Sovrapprovisionamento della Memoria

Questo è un altro fattore di costo sottile che spesso viene trascurato. Quando crei una funzione Lambda, allocchi una certa quantità di memoria (ad esempio, 128MB, 256MB, 512MB). Paga per quella memoria allocata, indipendentemente da quanto effettivamente utilizzi la tua funzione. Inoltre, la potenza della CPU scala proporzionalmente con l’allocazione della memoria. Quindi, se allochi 1GB di memoria per un semplice script Python che necessita solo di 128MB, non stai solo pagando troppo per la memoria; stai anche pagando troppo per cicli della CPU di cui non ha bisogno.

Ho imparato questa lezione nel modo difficile con una Lambda per l’elaborazione dei dati che era inizialmente configurata con 1GB di memoria “per ogni evenienza”. Quando ho guardato le sue metriche CloudWatch per l’uso della memoria, è rimasta costantemente sotto i 200MB, anche durante i carichi di lavoro di picco. Stavamo essenzialmente pagando per 800MB di RAM inutilizzata e il corrispondente aumento della CPU.

Esempio Pratico 2: Ottimizzare l’Allocazione della Memoria con Lambda Power Tuning

Calcolare manualmente l’impostazione di memoria ottimale può essere noioso. Devi distribuire, testare, monitorare, regolare e ripetere. Fortunatamente, esiste un fantastico strumento open-source chiamato AWS Lambda Power Tuning (sviluppato da Alex Casalboni di AWS) che semplifica notevolmente questo processo.

È un’applicazione serverless essa stessa che ti aiuta a visualizzare e identificare l’impostazione di memoria ottimale per le tue funzioni Lambda in base ai costi e alle prestazioni. La distribuisci al tuo account AWS, e poi puoi usarla per testare le tue funzioni.

Ecco come funziona generalmente:

  1. Distribuisci lo strumento di Power Tuning tramite il Serverless Application Repository o SAM.
  2. Invoca una macchina a stati (creata dallo strumento) con l’ARN della tua funzione Lambda e un payload.
  3. La macchina a stati invoca la tua Lambda più volte con configurazioni di memoria variabili (ad esempio, 128MB, 256MB, 512MB, 1024MB, ecc.).
  4. Analizza quindi i log di esecuzione e fornisce una visualizzazione che mostra i compromessi tra costi e velocità per ciascuna impostazione di memoria.

Per la mia Lambda di elaborazione dati, eseguendola tramite il Power Tuner, si è mostrato che 256MB era il punto dolce per i costi, con una trascurabile degradazione delle prestazioni rispetto a 1GB. Abbiamo immediatamente ridotto l’allocazione della memoria a 256MB, risultando in una riduzione del 75% dei costi di calcolo per quella specifica funzione. Non è stata un’eccezione; da allora ho reso pratica standard il passare nuove funzioni o funzioni rivalutate attraverso questo strumento.

Per usarlo, dopo la distribuzione, di solito inizio la macchina a stati con qualcosa del genere (regolando ARN e payload):


aws stepfunctions start-execution \
 --state-machine-arn "arn:aws:states:REGION:ACCOUNT_ID:stateMachine:powerTuningStateMachine" \
 --input '{ "lambdaARN": "arn:aws:lambda:REGION:ACCOUNT_ID:function:YOUR_FUNCTION_NAME", "num": 100, "payload": {}, "parallel": 5 }'

L’output fornisce un grafico chiaro, mostrando esattamente dove i tuoi costi e la velocità si intersecano per prestazioni ottimali. È un cambiamento significativo per l’ottimizzazione dei costi.

Verbostità dei Log e Avvii a Freddo

Due altre aree che spesso ti colpiscono sono la verbosità dei log e gli avvii a freddo. I Log di CloudWatch non sono gratis. Ogni riga che la tua funzione Lambda stampa viene assorbita e archiviata, e per questo paghi. Mentre un buon log è cruciale per il debug, una registrazione eccessivamente verbosa (ad esempio, stampare oggetti interi o ripetere messaggi di stato inutilmente) può rapidamente gonfiare la tua bolletta di log di CloudWatch.

Ho trovato alcune funzioni che registravano il corpo completo della richiesta HTTP a ogni invocazione. Anche se utile per lo sviluppo iniziale, in produzione, questo era solo rumore e costo. Un rapido aggiustamento per registrare solo i metadati essenziali (ID della richiesta, codice di stato, endpoint) ha ridotto notevolmente la nostra assunzione di log.

I cold start, sebbene non siano un “costo” diretto allo stesso modo, impattano l’esperienza dell’utente e possono indirettamente portare a più ritenti o a una durata di fatturazione più lunga se la tua funzione deve attendere risorse. Anche se AWS ha fatto notevoli progressi nella riduzione dei tempi di cold start, ottimizzare la dimensione del pacchetto della tua funzione ed evitare una logica di inizializzazione complessa al di fuori dell’handler può ancora fare la differenza. Per le funzioni critiche e sensibili alla latenza, la concorrenza riservata è un’opzione, ma sii consapevole che paghi per quella concorrenza allocata anche quando è inattiva.

Esempio Pratico 3: Logging Intelligente e Variabili d’Ambiente

Per il logging, la soluzione più semplice è spesso la migliore. Usa le variabili d’ambiente per controllare i livelli di log. In Python, ad esempio, puoi fare così:


import os
import logging

LOG_LEVEL = os.environ.get('LOG_LEVEL', 'INFO').upper()
logging.basicConfig(level=LOG_LEVEL)
logger = logging.getLogger()

def lambda_handler(event, context):
 logger.debug("Questo è un messaggio di debug, visibile solo se LOG_LEVEL è DEBUG")
 logger.info("Elaborazione evento: %s", event.get('request_id'))
 try:
 # ... logica della funzione ...
 logger.debug("Elaborazione completata per request_id: %s", event.get('request_id'))
 return {
 'statusCode': 200,
 'body': 'Successo'
 }
 except Exception as e:
 logger.error("Errore nell'elaborazione di request_id %s: %s", event.get('request_id'), str(e), exc_info=True)
 return {
 'statusCode': 500,
 'body': 'Errore'
 }

Impostando LOG_LEVEL su INFO in produzione e DEBUG in sviluppo/staging, puoi ridurre significativamente la tua fattura di CloudWatch Logs senza sacrificare l’osservabilità quando ne hai bisogno.

Un altro trucco è prestare attenzione a cosa viene inizializzato al di fuori dell’handler. Qualsiasi codice direttamente nello scope globale della tua funzione Lambda verrà eseguito durante il cold start. Se hai operazioni costose come il pooling delle connessioni al database o importazioni di grandi librerie, prendi in considerazione di posticiparle fino a quando non sono effettivamente necessarie all’interno dell’handler, o assicurati che siano memorizzate in cache in modo efficiente per le invocazioni calde successive.

Raccomandazioni Pratiche per la Tua Crociata contro i Costi Serverless

Bene, abbiamo coperto abbastanza. Ecco un riassunto dei passi pratici che puoi intraprendere subito per iniziare a ridurre quei costi Lambda subdoli:

  • Monitora incessantemente: Non limitarti a dare un’occhiata alla tua fattura AWS complessiva. Esplora le metriche di CloudWatch per Invocazioni, Durata e Utilizzo della Memoria per ogni funzione Lambda. Imposta allarmi per picchi inaspettati.
  • Consolida i cron job: Se hai molte piccole funzioni Lambda pianificate, considera di combinarle in un unico “Maintenance Runner” che distribuisce i compiti in base a un programma meno frequente. Questo riduce drasticamente i conteggi delle invocazioni.
  • Ottimizza l’allocazione della memoria: Usa strumenti come AWS Lambda Power Tuning per trovare l’impostazione di memoria ottimale per le tue funzioni. Non indovinare e sovrallocare. Ricorda, più memoria significa più CPU, e paghi per entrambi.
  • Controlla la verbosità del logging: Implementa livelli di log basati su variabili d’ambiente (ad esempio, INFO per produzione, DEBUG per sviluppo). Evita di registrare interi corpi di richiesta o stati interni eccessivi in produzione. La tua fattura di CloudWatch Logs ti ringrazierà.
  • Rivedi le funzioni non utilizzate: Effettua periodicamente un audit delle tue funzioni Lambda. Ci sono funzioni vecchie, sperimentali o deprecate ancora attive e che generano costi? Eliminale!
  • Tieni d’occhio la dimensione dei pacchetti: Pacchetti di distribuzione più piccoli significano cold start più rapidi e costi di archiviazione inferiori. Includi solo le dipendenze necessarie.
  • Comprendi il tuo modello di prezzo: Rileggi la pagina sui prezzi di Lambda. Comprendi come vengono fatturate le invocazioni, i GB-secondi e il trasferimento dati. La conoscenza è potere, specialmente quando si tratta del tuo portafoglio.

Domare il mostro serverless non significa evitarlo; significa essere intelligenti e intenzionali su come lo usiamo. La flessibilità e la scalabilità sono inestimabili, ma senza la giusta vigilanza, quei “piccoli” costi possono accumularsi fino a costituire una parte significativa del tuo budget. Vai avanti, monitora, ottimizza e risparmia!

Questo è tutto per oggi. Fammi sapere nei commenti se hai altri suggerimenti o trucchi per l’ottimizzazione dei costi Lambda!

🕒 Published:

✍️
Written by Jake Chen

AI technology writer and researcher.

Learn more →
Browse Topics: benchmarks | gpu | inference | optimization | performance
Scroll to Top