Cambia tema

Scegliere il database da soli: D1, Postgres, R2, S3 o SQLite

Easton editorial illustration: central four-way data-routing hub, structured relational database cylinder, object-storage bucket holding file sheets, single local database disk, sealed backup archive box

"La pagina ufficiale dei prezzi di D1 descrive rows read/written, limiti di storage, effetto degli indici sulle righe scansionate e comportamento quando Free raggiunge il limite giornaliero."

Il progetto contiene una tabella users, orders, usage_events, un upload in uploads/2026/06/report.pdf, la cache cache:daily-stats e dati locali in local-dev.sqlite. Dove dovrebbe vivere ogni oggetto? Se i fatti di business diventano file nell’object storage, backup, query ed esportazioni si complicano rapidamente. In D1, filtri senza indice consumano presto rows read e possono generare costi extra nel piano Paid. La scelta deve quindi partire dal tipo di dato.

Tabella di collocazione: dove salvare ogni dato

Anche in un progetto individuale, oggetti diversi richiedono sistemi diversi. I fatti di business hanno bisogno di query, relazioni e controllo degli accessi. Gli eventi richiedono scritture affidabili e conservazione economica. I file oggetto richiedono permessi di download, ciclo di vita e un modello di costo adatto al traffico. Bisogna capire se servono query strutturate e permessi, la frequenza di accesso e la sensibilità ai costi di uscita.

La tabella offre un punto di partenza pratico.

Sette tipi di dati e relative opzioni

Tipo di datoOggetti concretiStorage consigliatoCriterio
Fatti di businessusers, orders, diritti di abbonamento, pagamentiSupabase Postgres prima scelta, o D1 nei casi sempliciQuery strutturate (SELECT/JOIN), permessi (RLS), backup o ripristino temporale adatto al piano e audit
Eventiusage_events, azioni operative, statisticheD1 per scritture edge o Postgres per auditScritture frequenti e query semplici; l’analisi ordinaria può avere priorità di recovery inferiore, non sicurezza e fatturazione
File oggettouploads/2026/06/report.pdf, risultati, esportazioni, immaginiR2 in Cloudflare, S3 in AWS o Supabase StorageNiente blob nel DB; valutare egress R2, ecosistema S3 o integrazione Supabase Auth/Postgres
Cachecache:daily-stats, stato breve, calcoli temporaneiCloudflare KV, D1 o SQLite localeAccessi frequenti e dati normalmente eliminabili o rigenerabili; KV/D1 all’edge, SQLite locale
Dati localilocal-dev.sqlite, test, amministrazione per una personaFile SQLiteUn utente, nessun sistema di permessi, facile da copiare ed eseguire
Dati edge leggeriContatori Workers, configurazioni, mappature di dominiD1 o Cloudflare KVAccesso nativo Workers, relazioni leggere, prevalenza di letture
BackupDump del database, snapshot di esportazioneR2/S3 più copia localeModello egress R2, governance/lifecycle S3 e copia indipendente contro guasti del provider

Perché i fatti di business iniziano spesso in Postgres

Utenti, ordini, diritti di abbonamento e pagamenti sono record centrali. Perderli cambia accesso dei clienti e ricavi. Servono:

  • Query strutturate: un database relazionale esegue SELECT, JOIN, WHERE e ORDER BY; un object storage no.
  • Controllo accessi: Supabase Postgres può applicare Row Level Security alle query dei client. D1 oggi non offre RLS nativo.
  • Backup e ripristino: Supabase Pro, Team ed Enterprise hanno backup giornalieri; PITR è un add-on a pagamento da attivare separatamente. D1 Time Travel conserva 7 giorni in Workers Free e 30 in Workers Paid.
  • Audit trail: trigger e tabelle di audit dedicate per cambi a pagamenti e diritti sono più semplici in Postgres.

Supabase Postgres non è un’astrazione limitata. Ogni progetto riceve un database Postgres completo, fondamento di Auth, Storage, Realtime ed Edge Functions (documentazione Supabase Database). Le normali capacità di Postgres restano disponibili.

Separare eventi e record di business

usage_events, azioni operative e statistiche di accesso si comportano diversamente:

  • Vengono scritti spesso; le query comuni filtrano intervalli o aggregano valori.
  • Le analisi non soggette ad audit possono avere priorità di ripristino inferiore, ma richiedono regole esplicite di conservazione e perdita. Sicurezza, fatturazione e diritti non sono semplici page view.
  • Molte scritture consumano quote di rows written e storage.

Il confine è concreto:

  • Se l’evento fa parte di un audit trail con user_id e action, usa Postgres.
  • Se è solo un contatore o un segnale analitico rigenerabile, D1 o KV può bastare.

Non mettere i file oggetto nel database

Upload, risultati generati, archivi di esportazione e immagini non dovrebbero stare in una colonna blob:

  • Costo dei backup: ogni blob entra nel backup e aumenta tempo e volume.
  • Carico delle query: mescolare oggetti grandi e righe relazionali aumenta trasferimento, cache, backup e manutenzione; una query ampia può restituire il file per errore.
  • Distribuzione CDN: l’object storage si integra meglio con CDN, regole cache e download firmati; un blob richiede spesso un proxy applicativo.
  • Egress: servire un blob usa banda del database e dell’app. Il trasferimento diretto da R2 a Internet non ha costo egress R2; S3 dipende da regione e destinazione.

Il database conserva solo l’object key, per esempio uploads/2026/06/report.pdf. Il file resta in R2, S3 o Supabase Storage.

Cache e dati locali di sviluppo

Una cache come cache:daily-stats, uno stato breve o un calcolo temporaneo ha spesso queste caratteristiche:

  • Letture e scritture frequenti, ma normalmente può scadere o essere rigenerata. Le sessioni sensibili richiedono regole proprie di coerenza, scadenza e revoca.
  • La cache rigenerabile in genere non entra nei backup del database di business; revoche di sessione e altri stati di sicurezza richiedono persistenza separata.
  • L’accesso edge è sensibile alla latenza.

Opzioni pratiche:

  • Cloudflare KV o D1 per una cache edge leggera in Workers.
  • File SQLite o cache in memoria nello sviluppo locale.

local-dev.sqlite è un caso monoutente senza sistema di permessi:

  • SQLite è pensato per dati locali e file applicativi (quando usare SQLite).
  • Non risolve lo stesso problema di un database client/server: SQLite privilegia locale e monoutente; Postgres un repository condiviso multiutente.

Dati edge leggeri e backup

D1 o KV è un buon inizio per contatori Workers, piccole configurazioni e mappature di domini:

  • Accesso nativo: binding Worker o API HTTP senza pool di connessioni separato.
  • Relazioni leggere: schema semplice senza JOIN complessi o grande rete di foreign key.
  • Prevalenza di lettura: molte più letture che scritture.

Le esportazioni di backup richiedono recupero economico e copia indipendente:

  • R2 non addebita egress R2 per download diretti verso Internet.
  • S3 offre Object Lock, varie classi di archivio e gestione del ciclo di vita.
  • Una copia locale o presso un altro provider protegge da guasti di account e piattaforma. L’unica copia di restore non deve stare accanto alla produzione.

D1: database serverless nativo di Workers

D1 è il database serverless gestito di Cloudflare con semantica SQL di SQLite (panoramica D1). Le capacità principali sono:

  • Time Travel: ripristino a qualsiasi minuto degli ultimi 7 giorni in Workers Free o 30 giorni in Workers Paid. Il restore sovrascrive il database, quindi va verificato l’orario.
  • Read replication: riduce latenza e amplia la capacità di lettura per carichi con molte letture.
  • Accesso Workers e API HTTP: binding o API senza gestire un pool di connessioni proprio.
  • Disaster recovery integrato: Cloudflare gestisce storico e meccanismo di ripristino.

Adatto ad app Workers-native con molte letture

D1 è adatto a:

  • Progetti Workers o Pages che evitano di attraversare un’altra piattaforma per ogni query.
  • Dati relazionali leggeri come configurazione, contatori e mappature senza rete complessa di relazioni.
  • Carichi dominati dalle letture che possono scalare con repliche.
  • Progetti che usano già Workers, R2, KV o Vectorize e richiedono un livello relazionale nello stesso ecosistema.

D1 è meno adatto a:

  • SaaS multiutente che richiedono permessi maturi e RLS.
  • Ordini e diritti di abbonamento che richiedono vincoli, audit e restore verificato. Postgres è spesso il punto di partenza più sicuro; la finestra dipende da piano e add-on.
  • Sistemi ricchi di audit che dipendono da trigger e pattern Postgres.

Fatturazione rows read: righe scansionate, non restituite

D1 fattura rows read, rows written e storage. Rows read sono le righe scansionate dalla query, non quelle restituite.

A luglio 2026, la pagina ufficiale mostra le seguenti quote e tariffe. Vanno ricontrollate prima della pubblicazione o di una decisione importante.

VoceWorkers FreeWorkers Paid
Rows read5M/giornoPrimi 25B/mese inclusi
Rows written100K/giornoPrimi 50M/mese inclusi
Storage5 GB totaliPrimi 5 GB inclusi, poi $0.75/GB-month
Eccedenza rows readNon disponibile$0.001/million rows read
Eccedenza rows writtenNon disponibile$1/million rows written
Egress/bandaNessun costo separatoNessun costo separato

Se SELECT * FROM orders WHERE user_id = ? LIMIT 20 gira su 50.000 righe senza indice su user_id, D1 può scansionare quasi tutta la tabella per restituirne 20. Rows read si avvicina a 50.000, non a 20.

Un filtro senza indice può quindi scansionare tutta la tabella per pochi risultati. Consulta meta.rows_read dell’esecuzione reale, non il numero di risultati.

Indici ed efficienza delle query

Per controllare rows read:

  1. Crea un indice come CREATE INDEX idx_user_id ON orders(user_id); perché D1 legga il sottoinsieme indicizzato. Controlla meta.rows_read.
  2. Seleziona solo le colonne necessarie per ridurre risposta e accoppiamento. D1 conta però le righe scansionate, non le colonne; indici e filtri riducono rows read.
  3. Confronta rows_read con le righe restituite. Il meta e il dashboard espongono rows read/written per individuare scansioni complete.

Indicazioni per gli indici:

  • Indicizza colonne usate in WHERE come user_id e created_at.
  • Indicizza chiavi di JOIN come order_id e product_id.
  • Evita indici inutili, perché INSERT e UPDATE possono scrivere anche righe di indice.
  • Controlla nel dashboard D1 le query con rows read insolitamente elevato.

Quota gratuita D1 e segnali di passaggio

Workers Free limita oggi D1 a:

  • 5M rows read al giorno. Una query da 50K rows read gira circa 100 volte prima del limite.
  • 100K rows written al giorno, consumate rapidamente da carichi con molte scritture.
  • 5 GB di storage totale per account.

Valuta Workers Paid quando:

  • Rows read si avvicina a 5M al giorno. Le query Free falliscono dopo; Paid include 25B mensili e addebita l’eccedenza.
  • Rows written si avvicina a 100K al giorno; Paid include 50M al mese.
  • Lo storage supera 5 GB; l’eccedenza costa $0.75/GB-month.

D1 è forte per dati relazionali leggeri vicini a Workers, non come default per qualsiasi carico con molte scritture o grande volume. Monitora rows read, rows written e storage.

Supabase Postgres: scelta BaaS pratica

Ogni progetto Supabase ha un database Postgres completo, non un’astrazione ridotta (documentazione Supabase Database). Auth, Storage, Realtime ed Edge Functions si basano su di esso; restano disponibili query complesse, foreign key, trigger, transazioni, MVCC ed estensioni.

RLS per controllare l’accesso client

Row Level Security è un vantaggio importante di Supabase Postgres. Un’architettura tradizionale riserva il database al server e fa usare un’API al client. Con policy e chiavi corrette, RLS applica permessi per riga alle query client.

RLS aiuta a:

  • Controllare l’accesso: una policy mostra solo le righe il cui user_id corrisponde all’utente autenticato.
  • Progettare l’audit: RLS definisce il confine; tabella di audit, trigger o log registrano chi ha fatto cosa e quando.
  • Ridurre logica duplicata: le regole possono vivere nel database, ma il server continua a verificare identità, proteggere chiavi privilegiate e controllare operazioni elevate.

È adatto a fatti di business, app con permessi, SaaS multiutente, ordini e diritti di abbonamento. RLS è un confine del database, non sostituisce schema o audit.

Backup e ripristino

A luglio 2026, i piani ufficiali Supabase indicano:

VoceFreeProTeam
Dimensione database500 MB inclusi per progetto8 GB inclusi, poi eccedenza8 GB inclusi, poi eccedenza
Prezzo$0$25/mese$599/mese
Backup automaticiNon inclusiGiornalieri, 7 giorniGiornalieri, 14 giorni
PITRNon inclusoAdd-on a pagamento, circa $100/mese per 7 giorniAdd-on a pagamento, circa $100/mese per 7 giorni

Tre conseguenze pratiche:

  • Un progetto Free non può considerare i backup della piattaforma come piano di ripristino. Esegui regolarmente supabase db dump o pg_dump e conserva una copia esterna.
  • Pro e Team hanno backup giornalieri, ma possono perdere modifiche successive all’ultimo.
  • PITR non è incluso in Pro. Richiede almeno Small compute ed è addebitato a parte per 7, 14 o 28 giorni.

La dimensione da sola non decide il piano. Per ordini e diritti, definisci prima RPO, RTO e frequenza dei test, poi scegli tra backup giornaliero e PITR.

D1 rispetto a Supabase: permessi e ripristino

DimensioneD1Supabase Postgres
PosizioneDatabase serverless Workers-nativeBaaS Postgres gestito
AccessoNessun RLS nativoRLS può proteggere le query client
RipristinoTime Travel: Free 7 giorni, Paid 30 giorniBackup giornalieri Pro/Team/Enterprise; PITR a pagamento
Uso adattoDati relazionali leggeri in WorkersFatti di business, SaaS multiutente, ordini, diritti
FatturazioneRows read/written e storageStorage, compute e uso del piano

Possono convivere:

  • D1 conserva configurazione edge con molte letture, contatori e domini.
  • Supabase Postgres conserva utenti, ordini, diritti e pagamenti.

Uno strumento SaaS può tenere configurazione e contatori in D1, utenti e diritti in Postgres. D1 resta vicino a Workers; Postgres offre permessi, vincoli e ripristino maturi.

R2: object storage senza costo egress R2

R2 è lo storage compatibile S3 di Cloudflare. I trasferimenti diretti da R2 tramite Workers API, S3 API o r2.dev a Internet non generano costo egress R2 (prezzi R2); un altro servizio a consumo collegato può addebitare. R2 serve upload, risultati ed esportazioni, ma egress gratuito non significa storage e operazioni gratis.

Fatturazione delle operazioni Class A/B

R2 fattura storage, operazioni Class A e Class B. Infrequent Access aggiunge costi di recupero.

A luglio 2026, la tabella indica:

VoceQuota gratuitaStandardInfrequent Access
Storage10 GB-month/mese$0.015/GB-month$0.01/GB-month
Operazioni Class A1M/mese$4.50/million$9.00/million
Operazioni Class B10M/mese$0.36/million$0.90/million
RecuperoNessunoNessuno$0.01/GB
Uscita InternetGratuitaGratuitaGratuita
Durata minimaNessunaNessuna30 giorni

Le classi includono:

  • Class A, più costosa: PutObject, CopyObject, ListObjects e transizioni lifecycle. Scritture e liste rientrano qui.
  • Class B, meno costosa: GetObject, HeadObject e HeadBucket. Le letture rientrano qui.
  • Operazioni gratuite: DeleteObject, DeleteBucket e AbortMultipartUpload.

Cosa non significa la quota gratuita R2

10 GB-month non è storage illimitato:

  • Storage: misura la capacità durante il periodo, non il traffico. Più dati richiedono pagamento o pulizia.
  • Class A: 1M di operazioni mensili copre molti siti piccoli, ma upload in batch possono consumarle presto.
  • Class B: 10M di operazioni mensili copre molte letture, ma un’origine immagini trafficata può superarle.

Infrequent Access ha una durata minima di 30 giorni. Eliminare prima non evita il minimo. È adatto a backup e oggetti duraturi, non a risultati temporanei.

Adatto a upload e risultati generati

R2 è adatto a:

  • File utente come uploads/2026/06/report.pdf, immagini e documenti, soprattutto con molti download.
  • Report generati, esportazioni e risultati di elaborazione immagini.
  • Dump e snapshot da recuperare a basso costo.
  • Progetti che usano Workers, D1, KV o Vectorize.

R2 non è adatto a:

  • Fatti di business come utenti e ordini, che richiedono query strutturate e controllo degli accessi.
  • Carichi che richiedono S3 Object Lock, più classi o replica AWS nativa tra bucket e regioni.

R2 rispetto a S3

DimensioneR2S3
Uscita InternetGratuita lato R2; servizi collegati possono addebitareDipende da regione, destinazione e uso; consultare i prezzi AWS correnti
Storage$0.015/GB-month in StandardVarie classi, incluse Standard e Glacier
EcosistemaNativo in Workers e PagesIntegrazione AWS profonda, compresa Lambda
GovernanceLifecycle, Standard/IA ed eventi QueueObject Lock, classi Glacier, lifecycle, Replication e varie destinazioni
Uso adattoEcosistema Cloudflare e delivery sensibile all’egressEcosistema AWS, governance, data lake e app aziendali

Scegli R2 quando:

  • I download rendono il costo di uscita importante.
  • L’app gira già su Workers o Pages.

Scegli S3 quando:

  • Lambda, data lake o flussi aziendali dipendono da AWS.
  • Servono Object Lock, più classi Glacier, replica tra regioni o governance IAM AWS.
  • L’insieme AWS con CloudWatch, IAM e operazioni batch porta valore.

R2 e S3 non sono sostituti completi. Un prodotto Cloudflare può tenere file CDN e risultati in R2, archivi soggetti a governance in S3.

S3: ecosistema AWS e governance

Amazon S3 è un servizio di object storage per data lake, siti, app mobili, backup/restore, archivi, app aziendali, IoT e analytics (Amazon S3 User Guide). Offre:

  • Classi come Standard, Intelligent-Tiering, Glacier e Glacier Deep Archive.
  • Regole lifecycle che spostano o eliminano oggetti automaticamente.
  • Object Lock con conservazione WORM contro sovrascrittura ed eliminazione.
  • Same-Region e Cross-Region Replication per recovery, latenza e governance.
  • IAM, policy dei bucket e Block Public Access.
  • Notifiche di eventi per Lambda e altre destinazioni AWS.

Adatto a integrazione AWS e governance

S3 è adatto a:

  • Prodotti che usano già Lambda, EC2, RDS o DynamoDB.
  • Requisiti di Object Lock, classi di archivio e conservazione formale.
  • Data lake e pipeline IoT dipendenti dagli analytics AWS.
  • Backup, restore e archivi lunghi gestiti dal lifecycle.

S3 è meno adatto quando:

  • Molti download rendono sensibile il costo di uscita; usa i prezzi AWS correnti per regione, destinazione, cache e volume.
  • L’app è nativa Cloudflare e accede direttamente a R2 da Workers o Pages.

S3 rispetto a R2: profondità di ecosistema e governance

Il vantaggio di S3 è l’ampiezza di integrazioni AWS e governance:

  • Destinazioni eventi: S3 Event Notifications invia a SNS, SQS, Lambda ed EventBridge. R2 può inviare object-create e object-delete a Cloudflare Queues, consumate da Worker o HTTP pull.
  • Classi: S3 offre più classi Glacier; R2 oggi si concentra su Standard e Infrequent Access.
  • Object Lock: la conservazione WORM impedisce sovrascrittura o eliminazione nel periodo.
  • Replication: S3 copia oggetti, metadata e tag in un bucket della stessa regione o di un’altra.

Scegli S3 quando:

  • Lambda, data lake o app aziendali dipendono da AWS.
  • Servono Object Lock, classi Glacier o governance lifecycle.
  • Gli archivi lunghi beneficiano della famiglia Glacier.

Scegli R2 quando:

  • Upload e risultati vengono scaricati spesso.
  • Workers e Pages sono il runtime principale.

Un’architettura mista può mettere file CDN e risultati in R2, backup soggetti a governance in S3. Decidono tipo e accesso, non una regola mono-provider.

SQLite: prima locale ed embedded

SQLite è adatto a dati locali, file applicativi, siti a traffico basso o medio, analisi e cache (quando usare SQLite). Non compete direttamente con database SQL client/server. Questi privilegiano repository condiviso, concorrenza, centralizzazione e controllo; SQLite privilegia dati locali monoutente in un file copiabile.

Adatto a strumenti monoutente e backend locali

SQLite è adatto a:

  • Strumenti monoutente, dashboard locali, utility di analisi, piccoli giochi e dataset in un file.
  • Formati file di app CAD, finanza o gestione media.
  • Siti a traffico basso o medio. SQLite indica che meno di 100K hits/giorno in genere funziona, ma è un’osservazione prudente, non una garanzia. Hardware, complessità e scritture concorrenti determinano la capacità.
  • Dati locali come local-dev.sqlite.
  • Cache e calcoli temporanei senza stato condiviso durevole.

SQLite è meno adatto a:

  • SaaS multiutente con permessi, scritture concorrenti e audit.
  • Ordini e diritti che richiedono backup maturi e ripristino temporale.
  • Alta concorrenza di scrittura, perché SQLite accetta molti lettori ma un writer alla volta.

SQLite rispetto a Postgres: segnali di migrazione

DimensioneSQLitePostgres
PosizioneDati locali e file applicativoRepository client/server condiviso
Uso adattoStrumenti monoutente, giochi, dashboard localiSaaS multiutente, ordini, diritti
ConcorrenzaUn writer, molti lettoriPiù writer con MVCC
PermessiNessuna gestione utenti integrataRLS e gestione utenti/ruoli
CostoNessun server database separatoDipende da self-hosting o piano gestito, compute e backup

Passa da SQLite a Postgres quando:

  1. Uno strumento monoutente diventa SaaS multiutente e richiede permessi.
  2. Più utenti o istanze modificano lo stesso stato insieme.
  3. I pagamenti introducono ordini e diritti che richiedono audit e ripristino testato.
  4. Un modello users/roles/permissions richiede controllo nel database.

Una dashboard personale può restare su SQLite. Quando più clienti paganti condividono il servizio, Postgres segna spesso un confine più chiaro.

SQLite non sostituisce Postgres

SQLite stesso indica di non voler sostituire un database SQL client/server:

  • SQLite ottimizza semplicità locale monoutente e un database copiabile come file.
  • Postgres ottimizza un repository multiutente con modifiche concorrenti e record critici per i pagamenti.

SQLite non richiede un server separato. Il costo di Postgres dipende da self-hosting o servizio gestito, compute, storage e backup. Entrambi richiedono un processo di restore testato.

Scegli SQLite per:

  • Utility locali e piccoli giochi senza pagamenti né permessi.
  • Fixture di sviluppo e dati temporanei.
  • Siti personali e strumenti di documentazione con poche scritture concorrenti.

Scegli Postgres per:

  • SaaS multiutente con ordini, abbonamenti e permessi.
  • Modifiche operative e di diritti da sottoporre ad audit.
  • Dati di business che richiedono ripristino temporale configurabile.

Possono convivere: SQLite per sviluppo locale o cache rigenerabili, Postgres per fatti di business in produzione.

Tre errori da evitare

Gli errori più comuni sono salvare fatti di business come oggetti, ignorare la fatturazione D1 per scansione e trattare la quota gratuita R2 come illimitata. Rendono difficile il recovery, rallentano le query e rendono i costi imprevedibili.

Errore 1: salvare fatti di business nell’object storage

Tabelle come users, orders e usage_events soggetti ad audit non vanno in R2 o S3. L’object storage non offre query relazionali, vincoli, permessi per riga né pattern di audit del database.

Le conseguenze sono concrete:

  • Niente SELECT o JOIN: lo storage usa key. Per rispondere a SELECT * FROM orders WHERE user_id = ? LIMIT 20, l’app dovrebbe elencare e scaricare gli oggetti ordine.
  • Restore difficile: una raccolta di file non è una cronologia transazionale. Un dump SQL o un sistema point-in-time gestito offre recovery più coerente.
  • Esportazioni lente: una query può trasmettere i record filtrati; un oggetto per ordine può richiedere di scansionare molti file.

I fatti di business restano nel database e i file nell’object storage. Il database conserva un object key stabile; R2, S3 o Supabase Storage contiene il file.

Errore 2: ignorare la fatturazione rows read

D1 conta righe scansionate, non restituite. Un filtro senza indice può consumare molte più rows read di quanto suggerisca il risultato.

Su 50.000 righe orders, SELECT * FROM orders WHERE user_id = ? LIMIT 20 può leggere molte righe senza indice. meta.rows_read mostra l’uso fatturabile. Le query Free falliscono dopo 5M giornaliere; Paid addebita oltre la quota mensile.

Correzione:

  1. Indicizza la colonna reale, per esempio CREATE INDEX idx_user_id ON orders(user_id);.
  2. Verifica con EXPLAIN QUERY PLAN e meta.rows_read se resta una scansione completa.
  3. Seleziona solo le colonne necessarie per ridurre la risposta, ricordando che D1 conta righe, non colonne.

Errore 3: considerare illimitata la quota gratuita R2

R2 Free include oggi 10 GB-month di Standard storage, 1M operazioni Class A e 10M Class B al mese. Sono quote.

Errori comuni:

  • 10 GB-month misura la capacità conservata nel tempo, non il trasferimento.
  • PutObject è Class A. La creazione in batch può esaurire la quota anche con volume totale ridotto.
  • Infrequent Access impone 30 giorni minimi; eliminare prima comporta comunque il costo minimo.

Monitora storage e operazioni, fai scadere i risultati vecchi e non usare Infrequent Access per temporanei. SQLite locale o cache può essere migliore per dati brevi.

Conclusione

Decide il tipo: fatti di business, eventi, oggetti, cache, dati locali, dati edge leggeri e backup. Supabase Postgres conserva spesso i fatti grazie a vincoli, RLS, ripristino configurabile e audit. D1 gestisce dati relazionali leggeri vicini a Workers, R2/S3 gli oggetti e SQLite i dati locali monoutente.

Tre azioni rendono più sicura la prima versione:

  1. Classifica ogni oggetto e registra query, permessi, frequenza e requisiti di costo.
  2. Indicizza le colonne filtro D1 e verifica con le metriche rows read.
  3. Tieni i record di business fuori dall’object storage, evita scansioni senza indice e stima tutta la quota R2, non solo lo storage.

I prossimi articoli trattano pagamenti e utenti. Rafforzano il confine: gli ordini richiedono vincoli Postgres, backup e audit; diritti e permessi utente richiedono RLS e ripristino testato.

Se la destinazione di un oggetto resta incerta, torna alla tabella e agli articoli precedenti su principi architetturali, backend e deployment. Definisci prima il confine del sistema, poi affina lo storage.

Assegnare lo storage a un progetto individuale

Separa in sei passaggi, dall'inventario al test di ripristino, i ruoli del database e dell'object storage.

  1. 1

    Step 1: Inventariare gli oggetti

    Elenca users, orders, usage_events, uploads, cache, file locali e backup senza raggrupparli subito per prodotto.
  2. 2

    Step 2: Classificare ogni oggetto

    Segna ogni elemento come fatto di business, evento, file oggetto, cache, dato locale o backup e indica se può scadere o essere rigenerato.
  3. 3

    Step 3: Definire coerenza e permessi

    Registra transazioni, vincoli, RLS, scritture concorrenti, audit e condivisione tra istanze per scegliere Postgres o D1.
  4. 4

    Step 4: Stimare accessi e costi

    Stima D1 rows read/written, R2 Class A/B operations, volume, frequenza di lettura e possibili costi di egress.
  5. 5

    Step 5: Progettare riferimenti stabili

    Conserva object key, owner, status e metadata nel database, il contenuto nell'object storage e nomi delle key stabili.
  6. 6

    Step 6: Testare backup e migrazione

    Prepara esportazioni, copie esterne, finestre di eliminazione e prove di restore; migra metadata, poi oggetti e infine le letture.

FAQ

Un progetto individuale dovrebbe iniziare con D1 o Supabase Postgres?
D1 può andare bene per dati relazionali semplici e soprattutto letti in Workers o Pages. Utenti, ordini, abbonamenti, permessi e query complesse appartengono in genere a Supabase Postgres.
Cosa va conservato in R2 o S3?
Entrambi sono adatti a immagini, PDF, esportazioni, backup e risultati generati. Il database conserva metadata, owner, status e object key, non il contenuto voluminoso del file.
SQLite può sostenere il primo SaaS?
Può bastare per uno strumento su una macchina e poche scritture concorrenti. Stato condiviso tra istanze, permessi complessi, diritti di pagamento o molte scritture simultanee indicano Postgres.
Gli upload degli utenti possono stare nel database?
In genere no. Metti i file in R2, S3 o Supabase Storage e riferimenti e permessi nel database per gestire meglio backup, download, CDN ed eliminazione.
Cosa significa la fatturazione D1 rows read?
Conta le righe scansionate, non quelle restituite. Un filtro senza indice può leggere molte righe per pochi risultati; verifica indici, EXPLAIN QUERY PLAN e meta.rows_read.
Il livello gratuito di Cloudflare R2 è sufficiente?
Stima insieme Standard storage, Class A/B operations e frequenza di lettura. Oggi include 10 GB-month, 1M richieste Class A e 10M Class B al mese; può cambiare e non vale per Infrequent Access.

19 min di lettura · Pubblicato il: 9 ott 2026

Percorso di lettura della serieParte 8 di 8

Guida allo stack tecnico per solo founder

Se arrivi dalla ricerca, il modo più veloce per orientarti è passare all’articolo precedente o successivo della stessa serie.

Vedi hub della serie

Articoli correlati

Commenti

Accedi con GitHub per lasciare un commento

Easton BlogEaston Blog