Yeni bir proje açılışında çoğu geliştirici refleks olarak PostgreSQL kurar: ayrı servis, ayrı port, kullanıcı yetkileri, yedekleme scripti, bağlantı havuzu ayarı. Oysa işin gerçeği şu: veritabanınızın yarısı gibi görünen bu kurulum zinciri, çoğu projede kimseye hizmet etmiyor. SQLite, tek bir dosyadan ibaret ve dünyada en çok dağıtılan veritabanı motoru — doğru senaryoda PostgreSQL'in kurulumunu tamamen gereksiz bırakıyor.

Yeterli olduğu on durum

  1. Kişisel projeler ve hobiler — tek kullanıcılı uygulama; sunucu bakımı diye bir yükünüz yok.
  2. Blog ve içerik siteleri — okuma yoğun, yazı seyrek; bu sitenin doğal doğası.
  3. Yerel geliştirme ortamları — ekip her docker compose up yerine sqlite3 app.db açar.
  4. Mobil ve masaüstü uygulamalar — cihaz içi veri; zaten rakipsiz.
  5. CI/CD test süreçleri — her koşuda temiz veritabanı; testler saniyeler içinde döner.
  6. CLI araçları — kullanıcı bilgisayarında daemon çalıştırmak lüks.
  7. Edge ve sunucusuz fonksiyonlar — process içi veritabanı, ağ gecikmesi sıfır.
  8. Prototip ve MVP'ler — fikir doğrulaması için mimari yük boşluk.
  9. Küçük işletme içi araçlar — on kişilik ekip, saatte on sorgu; tek dosya yeter.
  10. Veri analizi ve raporlama — CSV yerine sorgulanabilir tek dosya; DuckDB bile altından beslenir.

Ortak payda: aynı anda tek sunucu, düşük yazma eşzamanlılığı, verinin tek makinede yaşaması. Bu üçü sağlanıyorsa PostgreSQL kurulumu ekstra operasyon yükünden başka bir şey kazandırmıyor.

Neredeyse bedava performans: WAL modu

SQLite'ın tek gerçek zayıf noktası eşzamanlı yazmadır: klasik modda yazarken okuma kilitlenir. WAL (Write-Ahead Logging) modu bunu büyük ölçüde çözer — yazarken bile okuyucuları engellemez. İki PRAGMA ile:

-- Uygulama açılışında bir kez çalıştırın
PRAGMA journal_mode = WAL;    -- okuma/yazma kilidini büyük ölçüde kaldırır
PRAGMA synchronous = NORMAL;  -- hız/dayanıklılık dengesi (WAL ile güvenli)
PRAGMA foreign_keys = ON;     -- unutulmaması gereken klasik

-- Bağlantı havuzu: tek yazıcı ilkesine dikkat
-- (pratikte: tek process + çok thread için her bağlantıda foreign_keys tekrar açılır)
// better-sqlite3 ile tipik kurulum
import Database from 'better-sqlite3';

const db = new Database('app.db');
db.pragma('journal_mode = WAL');
db.pragma('foreign_keys = ON');

// Hazırlanmış ifade: tekrar derlenmez, hızlıdır
const makaleEkle = db.prepare(
  'INSERT INTO articles (slug, title, body) VALUES (?, ?, ?)'
);

export function makaleEkleVeKaydet(slug: string, title: string, body: string) {
  // transaction otomatik: satır yoksa geri alınır
  return db.transaction(() =>
    makaleEkle.run(slug, title, body)
  )();
}

Gerçek sınır nerede?

PostgreSQL'i gerçekten hak eden durumlar var: çok sunuculu mimariler, yüksek yazma eşzamanlılığı (yüzlerce eşzamanlı işlem), LISTEN/NOTIFY gibi sunucu özellikleri, satır düzeyinde yetkilendirme, sütun tipi zenginliği (dizi, JSONB, coğrafi). Bunların hiçbiri sizin senaryonuzdaysa SQLite'ı zorlamayın. Ama blog, panel, CLI veya prototip yazıyorsanız, "kurulumdan ibaret bir mimari"yi temizlemek için SQLite çoğu zaman tek doğru cevap.

Geçiş de tek yönlü korkulacak bir şey değil: SQLite'tan PostgreSQL'e taşınmak için ORM'inizin göç komutunu çalıştırmak çoğu zaman yeterli — Drizzle ve Prisma, şemayı yeniden yazdırır. Yani erken seçim mahkûmiyeti değil: bugün tek dosyayla başlayın, yarın ihtiyaç doğduğunda durup veritabanı sunucusu kurun. Mimari kararların çoğu geri döndürülemez sanılır; veritabanı seçimi neyse ki o grupta değil. Mantıklı olan, bugünkü ihtiyaçtan büyüğünü kurmaktır.