PostgreSQL JSONB vs MongoDB 2026: Doküman Veri Karşılaştırması
JSONB vs MongoDB karşılaştırması 2026’da artık “ilişkisel mi NoSQL mi” sorusundan çok “tek motorda ne kadar yol gidebilirim” sorusuna dönüştü. Cevap, çoğu yeni proje için net: PostgreSQL JSONB, doküman yüklerinin yaklaşık %80’inde MongoDB’nin yerini tutar ve aynı veritabanı içinde ACID, ilişkisel join, analytics ve full-text search verir. MongoDB ise sharded multi-region replica setleri, change streams ve aggregation pipeline gibi belirli senaryolarda hâlâ üstün kalıyor. Bu yazıda; storage internals, indeks tipleri, sorgu semantiği, throughput/latency benchmarkları, fiyat, operasyon ve geçiş riski boyutlarında ikisini sayısal olarak karşılaştırıyorum.
Stack Overflow Developer Survey 2024’e göre PostgreSQL yaklaşık %49 kullanım payıyla profesyonel geliştiriciler arasında dördüncü kez üst üste en sevilen veritabanı; MongoDB ise %25 paya geriledi. DB-Engines popülerlik skorunda PostgreSQL Ocak 2026 itibarıyla MongoDB’nin önünde (PG ≈ 660 puan, MongoDB ≈ 405 puan, yaklaşık değerler). Bu trend tek başına teknik bir delil değil ama mühendislik yöneticileri için “stack’i azalt, PostgreSQL’i çoklu yük için kullan” kararını destekliyor. Aşağıdaki karşılaştırma, kararı kendi yüküne göre ölçmek isteyen ekipler için hazırlandı.
JSONB ve BSON: Storage Internals’da Ne Farkeder?
PostgreSQL JSONB, JSON belgesini tokenize edilmiş, ayrıştırılmış ve dengeli bir binary ağaç olarak saklar. Anahtarlar deduplicate edilir, değerlere O(log n) erişim sağlanır ve TOAST mekanizmasıyla 2KB’den büyük satırlar arka planda sıkıştırılarak (LZ4 veya PGLZ) ayrı segmente taşınır. MongoDB ise WiredTiger storage engine üzerinde BSON formatı kullanır; alanlar sıralı offset’lerle saklanır, snappy/zstd block-level sıkıştırma uygulanır.
Pratik farklar üç noktada toplanıyor:
- Alan erişim maliyeti: JSONB içinde derin nested alan erişimi, ağaç içi seek yapar; MongoDB BSON’da offset tabanlı doğrudan jump vardır. Küçük belgelerde MongoDB yaklaşık %10-15 daha hızlı tek-alan erişimi gösterebilir.
- Sıkıştırma oranı: WiredTiger zstd ile MongoDB tipik olarak %60-75 sıkıştırma sağlar. PostgreSQL TOAST + LZ4 ise %40-55 bandında kalır; ancak PG17+ ile zstd desteği yaygınlaştı ve fark daraldı.
- In-place update: MongoDB belgeyi yerinde güncelleyebilir (eğer boyut artmazsa). PostgreSQL MVCC nedeniyle her UPDATE yeni satır yaratır; HOT update optimizasyonu yalnız indekslenmemiş alanlarda devreye girer. Yüksek write-heavy doküman yüklerinde bu, autovacuum yüküne dönüşür.
| Boyut | PostgreSQL JSONB | MongoDB 7/8 |
|---|---|---|
| Format | Tokenize binary tree | BSON (binary JSON) |
| Sıkıştırma | LZ4 / PGLZ / zstd (PG17+) | snappy / zstd (varsayılan zstd) |
| Tipik sıkıştırma oranı | %40-55 (LZ4), %55-70 (zstd) | %60-75 |
| Update modeli | MVCC (yeni satır) | In-place (boyut artmazsa) |
| Maksimum belge boyutu | ~1 GB (TOAST ile) | 16 MB |
| Şema validasyonu | CHECK constraint + JSON Schema | $jsonSchema validator |
| İşlem sınırı | Tam ACID, çok-satır transaction | Multi-document transaction (4.0+, perf cost) |
Belge boyutu farkı kritik: MongoDB’nin 16 MB sınırı, log/timeseries gibi büyük belgelerde GridFS’e itiyor. JSONB’de 1 GB’a kadar (TOAST ile pratikte 2-50 MB ideal) tek alan saklanabilir; ama bu boyutta sorgu yerine kolon olarak ayırmak her zaman daha iyi karardır.

Indeks Aileleri: GIN, B-tree, Wildcard ve Compound
Doküman veritabanlarında performansı belirleyen tek faktör indeks stratejisidir. JSONB’de üç ana indeks ailesi vardır; MongoDB’de ise dört. Hangi sorgu kalıbının hangi indekse düştüğünü bilmek, latency’yi 10-50 kat değiştirir.
- GIN (Generalized Inverted Index) — JSONB için varsayılan:
CREATE INDEX ON tbl USING GIN (data jsonb_path_ops). Her key/value çiftini ayrı term olarak indeksler.@>containment operatörü için ideal. jsonb_path_ops varyantı yalnız containment’i destekler ama %30-40 daha küçük indeks ve %20-25 daha hızlı. - B-tree expression index: Tek bir JSONB alanı için
CREATE INDEX ON tbl ((data->>'user_id')). Eşitlik ve aralık sorgularında GIN’den çok daha hızlı (1-2 ms vs 8-15 ms). - GIN trigram (pg_trgm): JSONB içindeki text alanlar için fuzzy/LIKE araması. Full-text için
tsvectorile birleşir. - MongoDB single-field / compound / multikey / wildcard / text / 2dsphere: Wildcard index belge içindeki tüm alanları indeksler ama disk maliyeti yüksektir; compound index sıra-duyarlıdır ve ESR (Equality-Sort-Range) kuralına göre tasarlanmalıdır.
| Sorgu tipi | JSONB indeks | MongoDB indeks | Tipik latency (1M doc) |
|---|---|---|---|
Eşitlik: data->>'status'='active' | B-tree expression | Single-field | 0.5-2 ms |
Containment: belgede {"tags":["red"]} var mı | GIN jsonb_path_ops | Multikey | 2-8 ms |
| Aralık + sıralama | B-tree compound expression | Compound (ESR) | 3-12 ms |
| Full-text (TR) | tsvector + GIN | $text (sınırlı TR) | 5-25 ms |
| Dinamik / bilinmeyen alan | GIN tüm belge | Wildcard index | 10-40 ms |
| Geo (radius) | PostGIS GEOGRAPHY | 2dsphere | 2-10 ms |
Önemli detay: JSONB GIN indeksleri yazma sırasında yaklaşık 2-4 kat daha pahalıdır (CPU + WAL). Write-heavy bir koleksiyonda GIN’i pending list (gin_pending_list_limit) ile lazy yapmak veya yalnız okuma replikalarında tutmak yaygın bir taktiktir. MongoDB tarafında compound indeksleri ESR sıralamasına uyduğunda explain plan’da IXSCAN görmek hedeftir; COLLSCAN üretim ortamında yok sayılamaz.
Sorgu Dili: SQL+JSONPath vs Aggregation Pipeline
JSONB’nin gücü, doküman sorgusunu SQL ile birleştirebilmesidir. jsonb_path_query, @?, @@ operatörleri ve SQL/JSON path expression’ları (PG12+) ile MongoDB’deki $elemMatch, $exists, $regex karşılıklarını yazabilirsiniz. Ayrıca aynı sorguda ilişkisel tablolarla JOIN yapabilirsiniz — MongoDB $lookup bunu yapar ama optimize edilmemiş, çoğu zaman cross-collection performansı düşüktür.
Şu örnek, kullanıcı belgelerinden son 24 saatte 3’ten fazla satın alma yapanları, ilişkisel orders tablosuyla doğrulayarak getirir:
SELECT u.id, u.data->>'email' AS email, COUNT(o.id) AS purchases
FROM users u
JOIN orders o ON o.user_id = u.id
WHERE u.data @> '{"plan":"pro"}'
AND o.created_at > now() - interval '24 hours'
GROUP BY u.id, u.data->>'email'
HAVING COUNT(o.id) > 3;
Aynı sorguyu MongoDB’de yapmak için $lookup + $match + $group pipeline’ı kurmak gerekir; orta veri hacminde (10M+ user, 100M+ order) bu pipeline’ın p95 latency’si yaklaşık 3-7 kat daha yüksektir. PostgreSQL performans optimizasyonu rehberinde JSONB sorgularını planlayıcıya doğru göstermenin (statistics, partial index, expression index) detayları var.

Performans Benchmarkları: YCSB ve Gerçek Yük
YCSB (Yahoo! Cloud Serving Benchmark), her iki sistemi de test eden en yaygın referans. 2024-2025 yayınlanan birkaç bağımsız çalışma (EnterpriseDB, Percona blog, Severalnines) tutarlı bir tablo veriyor. Aşağıdaki rakamlar 16 vCPU / 64 GB RAM / NVMe SSD / 100 GB veri seti / 50 concurrent client koşullarında tipik aralıklardır (gerçek değerler yüke göre değişir, ±%20 sapma normal).
| YCSB workload | PostgreSQL 16 JSONB | MongoDB 7 | Galip |
|---|---|---|---|
| A (50% read, 50% update) | ~38K ops/sec, p95 12ms | ~52K ops/sec, p95 9ms | MongoDB +35% |
| B (95% read, 5% update) | ~95K ops/sec, p95 4ms | ~88K ops/sec, p95 5ms | PostgreSQL +8% |
| C (100% read) | ~110K ops/sec, p95 3ms | ~100K ops/sec, p95 3ms | PostgreSQL +10% |
| D (read latest, insert-heavy) | ~60K ops/sec, p95 8ms | ~75K ops/sec, p95 6ms | MongoDB +25% |
| E (range scan) | ~22K ops/sec, p95 18ms | ~19K ops/sec, p95 22ms | PostgreSQL +15% |
| F (read-modify-write) | ~28K ops/sec, p95 15ms | ~42K ops/sec, p95 11ms | MongoDB +50% |
Sayılardan üç çıkarım:
- Read-heavy yüklerde (B, C, E) PostgreSQL JSONB %8-15 önde. Sebep: shared_buffers + OS page cache kombinasyonu ve daha verimli b-tree taraması.
- Write/update-heavy yüklerde (A, D, F) MongoDB %25-50 önde. Sebep: in-place update, WiredTiger’ın daha hafif WAL’ı (oplog) ve MVCC’siz yapı.
- Sharding ve replikasyon hesaba katıldığında MongoDB tek bir cluster ile yüzlerce node’a yatay ölçeklenebilir; PostgreSQL’de aynı esneklik için Citus, YugabyteDB veya manuel sharding gerekir.
Eğer yükünüz okuma ağırlıklıysa, analytics ve OLTP’yi karıştırıyorsa ve veri 10 TB altındaysa PostgreSQL JSONB çoğu zaman daha iyi total-cost-of-performance sunar. 50 TB+ doküman, multi-region active-active, sharded yazma yüklerinde MongoDB Atlas hâlâ daha düşük operasyon yüküyle çalışır.
Ölçeklenebilirlik: Sharding, Replikasyon, Multi-Region
MongoDB sharding tasarımı 2009’dan beri olgunlaştı: shard key seçimi config server + mongos router üzerinden otomatik chunk migration ile yönetiliyor. Hashed shard key, ranged shard key ve zone-based sharding desteklenir. Replica set 50+ üyeye kadar resmen desteklenir (pratikte 7-9 önerilir).
PostgreSQL tarafında native sharding yok ama üç yaklaşım var:
- Citus (Microsoft): PostgreSQL’i distributed hale getiren extension. Coordinator + worker mimarisi, hash/range shard key, columnar storage desteği. Citus 12 ile schema-based sharding eklendi.
- YugabyteDB / CockroachDB: PostgreSQL wire-compatible distributed SQL. Multi-region active-active, Raft consensus. Gerçek anlamda yatay ölçek için en güçlü seçenek ama JSONB performansı vanilla PG’den yaklaşık %20-40 daha düşük.
- Manuel sharding (application-level): Müşteri/tenant ID’sine göre farklı PG cluster’lara yönlendirme. Esnek ama operasyon yükü yüksek.
| Yetenek | MongoDB | PostgreSQL (vanilla) | PostgreSQL + Citus / YB |
|---|---|---|---|
| Native horizontal sharding | Evet | Hayır | Evet |
| Multi-region active-active | Atlas Global Clusters | BDR (3rd party) | YB/Cockroach native |
| Streaming replication | Oplog tabanlı, async/sync | WAL streaming, sync/async/quorum | WAL + Raft |
| Automatic failover | Replica set election (~12 sn) | Patroni / repmgr (~20-40 sn) | YB native (~5-10 sn) |
| Read replicas | Sınırsız, secondary tag | Sınırsız, hot standby | Sınırsız |
| Change data capture | Change Streams (native) | Logical replication / Debezium | Aynı + native CDC |
Change Streams MongoDB’nin en güçlü farklarından biri: koleksiyon/database/cluster seviyesinde gerçek zamanlı event akışı verir. PostgreSQL’de eşdeğeri için Debezium + Kafka kurmak gerekir; bu kombinasyon Change Streams’in açık kaynak alternatifi olarak yaygın kullanılıyor.

Fiyat ve TCO: Managed vs Self-Hosted
Veritabanı seçiminde 3 yıllık TCO, lisans + altyapı + operasyon mühendis maliyetini içermelidir. Aşağıdaki tablo, yaklaşık 1 TB veri / 5K QPS / 3-node HA cluster için kasım 2025 listfiyatlarına dayanan kaba kıyastır (kurumsal indirimsiz, USD/ay).
| Servis | Compute (3 node) | Storage (1 TB) | Yedek/IOPS | Yaklaşık aylık |
|---|---|---|---|---|
| MongoDB Atlas M40 (AWS) | ~$2,650 | ~$160 | Backup dahil | ~$2,800 |
| AWS RDS PostgreSQL (db.r6g.xlarge) | ~$1,180 | ~$125 | ~$200 (gp3 IOPS) | ~$1,500 |
| Aurora PostgreSQL Serverless v2 | ~$1,600 (ACU dynamic) | ~$200 | I/O dahil (Aurora I/O-Opt) | ~$1,800 |
| Azure Cosmos DB for MongoDB (vCore) | ~$2,200 | ~$250 | Geo-replication ekstra | ~$2,450 |
| Google AlloyDB | ~$1,450 | ~$170 | Backup ~$80 | ~$1,700 |
| Self-hosted PG 16 (Hetzner AX52 ×3) | ~$330 | Local NVMe | Backup S3 ~$30 | ~$360 |
Bu rakamlar mühendis saatini içermiyor. Self-hosted PG yıllık 80-120 saat (~$8K-$15K) operasyon yükü getirir; Atlas/Aurora bunu 20-30 saate düşürür. Yine de orta ölçek (1-5 TB, 5-50K QPS) için PostgreSQL self-hosted veya yarı-yönetilen seçenek tipik olarak %50-65 daha ucuza geliyor. TCO çerçevesinin yöntemi aynı: workload profili → fiyat matrisi → 3 yıllık projeksiyon.
Operasyon: Backup, Monitoring, Upgrade
İki sistemin operasyon yüzeyi belirgin biçimde farklı. PostgreSQL için ekosistem olgun ama parçalı: pgBackRest veya WAL-G ile incremental backup, Patroni ile HA orchestration, pgBouncer veya PgCat ile connection pooling, pg_stat_statements + pgBadger ile sorgu analizi, Prometheus postgres_exporter ile metrik. Major upgrade pg_upgrade ile genelde dakikalar içinde olur ama extension uyumluluğu önceden test edilmelidir.
MongoDB tarafında Atlas kullanırsanız çoğu şey otomatik: backup (Continuous Cloud Backup), rolling upgrade, query profiler, Performance Advisor, alerting. Self-hosted MongoDB’de Ops Manager (Enterprise) veya manuel mongodump/mongorestore + mongotop/mongostat kullanılır. Major version upgrade’lerde featureCompatibilityVersion adımlarına dikkat etmek şart — atlama yapılmaz.
- Avantaj PG: Açık ekosistem, vendor-bağımsızlık, yüzlerce extension (pgvector, PostGIS, TimescaleDB, pg_partman). Vector veritabanı karşılaştırmasında pgvector’ün özel bir veritabanına ne zaman yetmediğini detaylandırdım.
- Avantaj MongoDB: Atlas managed deneyimi (özellikle multi-region), tek tıkla auto-sharding, integrated full-text search (Atlas Search üzerinden Lucene), Realm/App Services ile backend-as-a-service.
- Dezavantaj PG: HA için 3rd party araç (Patroni) zorunlu, sharding native değil, connection limit (varsayılan ~100) pooler olmadan kolay tıkanır.
- Dezavantaj MongoDB: Self-hosted Enterprise lisans pahalı, vendor lock-in riski (Atlas-spesifik özellikler), schema-less olmanın uzun vadede getirdiği teknik borç.
Geçiş Senaryoları: MongoDB’den PostgreSQL JSONB’ye
2023-2026 arasında orta ölçek SaaS şirketlerinin önemli bir kısmı (publicly: The Guardian, OkCupid’in bir kısmı, çeşitli fintech ekipleri) MongoDB’den PostgreSQL JSONB’ye geçti. Sebepler genelde: (a) ACID multi-document transaction güveni, (b) analytics için aynı veritabanını kullanma isteği, (c) Atlas maliyeti, (d) mühendis havuzunda PostgreSQL bilgisinin daha geniş olması.
Tipik geçiş planı:
- Şema keşfi: MongoDB koleksiyonlarındaki belge yapısını
mongo-schema, Variety veya$jsonSchemaile çıkar. Hangi alanlar gerçekten dinamik, hangileri her belgede var? Sabit alanlar PG’de kolon, dinamikler JSONB içinde kalır. - Pilot tablo: En küçük koleksiyondan başla.
CREATE TABLE users (id bigserial PRIMARY KEY, data jsonb NOT NULL, email text GENERATED ALWAYS AS (data->>'email') STORED UNIQUE);gibi hibrit yapı kur. - Dual-write window: Uygulama hem MongoDB’ye hem PG’ye yazar (1-4 hafta). Tüketici (reader) trafiği önce %5, sonra %25, %50, %100 PG’ye geçer.
- Veri reconcile: Her gece checksum karşılaştırma, fark varsa MongoDB’den re-sync.
- Indekleme: En sık WHERE clause’lardaki alanları expression index yap. GIN’i sadece gerçekten containment sorgusu varsa kur.
- Cut-over: Yazma trafiğini PG’ye al, MongoDB read-only mode’a düşür, 7-14 gün sonra decommission.
Tipik geçiş süresi 50M belge ve 200 GB veri için 6-10 hafta sürer; mühendis maliyeti yaklaşık 200-400 saat. Geçişten sonra elde edilen kazançlar (gerçek vakalardan): %30-60 altyapı maliyeti düşüşü, %40-70 daha az “schema drift” hatası, analytics query time’ında 2-5 kat hızlanma. Bu tip migration projelerini planlarken Ömer Önal’ın yürüttüğü danışmanlık çerçevesinde önce 2 haftalık pilot, sonra dual-write, sonra cut-over modeli uygulanıyor.

Hibrit Mimari: İkisini Birlikte Kullanmak
Çoğu olgun stack tek motora bağlanmaz. Pragmatik mimari, her veritabanını güçlü olduğu yerde tutmaktır. Örnek bir SaaS stack 2026:
- PostgreSQL JSONB: Kullanıcı, hesap, fatura, abonelik, ürün katalog, izin yönetimi (ACID kritik veriler).
- MongoDB: Event log, audit trail, IoT telemetry, esnek analytics belgeleri (yüksek hacimli, append-mostly veriler).
- ClickHouse / DuckDB: Time-series ve aggregate sorgular.
- Redis: Cache, session, rate limit, pub/sub.
- S3 + Apache Iceberg: Soğuk veri, ML training set’leri. Data lakehouse mimarisi bu katmanı detaylandırır.
Bu hibrit yaklaşım, “kafa karıştırıcı” gibi görünse de toplam maliyeti ve performansı tek-motor stack’inden çoğu zaman daha iyi optimize eder. Önemli olan veri kontratlarını netleştirmek, CDC ile katmanlar arası akışı tasarlamak ve stream processing ile aralarda dönüşüm yapmak. Her domain kendi storage’ını seçen data mesh yaklaşımında merkezi veritabanı dayatması yoktur.
Sık Sorulan Sorular (SSS)
JSONB MongoDB’nin yerini tamamen alır mı?
Hayır. Çoğu OLTP ve karışık yükte alır ama 50 TB+ doküman, native sharding, multi-region active-active, change streams ve managed Atlas deneyimi gerektiren senaryolarda MongoDB hâlâ daha düşük operasyon yüküyle çalışır. Karar yük profiline bağlıdır; tek cevap “her zaman X” değildir.
JSONB ne zaman ilişkisel kolon yerine tercih edilmeli?
Şema sık değişiyorsa, alanlar tenant’a göre farklılaşıyorsa veya 3rd party API’den gelen heterojen payload saklanıyorsa JSONB doğru seçim. Sık WHERE/JOIN’e giren, sabit anlamlı alanlar (email, user_id, status) ise kolon olarak çıkarılmalı. Generated column ile ikisini hibrit kullanmak yaygın patterndir.
MongoDB Atlas vs self-hosted PostgreSQL hangisi daha ucuz?
1 TB ve 5K QPS gibi orta ölçekte self-hosted PostgreSQL Atlas’tan yaklaşık 5-7 kat daha ucuz olabilir; ancak mühendis saatini dahil ettiğinizde bu fark 2-3 kata düşer. Küçük ekiplerde mühendis zamanı pahalıysa Atlas veya Aurora gibi managed servisler 3 yıllık TCO’da yarışabilir.
JSONB GIN indeksi yazma performansını ne kadar etkiler?
Tipik olarak yazma maliyetini 2-4 kat artırır ve WAL hacmini büyütür. Write-heavy bir koleksiyonda gin_pending_list_limit ile lazy update yapmak veya GIN’i yalnız okuma replikalarında tutmak yaygın taktiktir. Yalnız containment sorgusu için jsonb_path_ops varyantı daha hafif çalışır.
Geçişte veri kaybı riski nasıl yönetilir?
Dual-write window, checksum tabanlı nightly reconcile ve aşamalı reader migrasyonu (% 5 → 25 → 50 → 100) ile risk minimize edilir. MongoDB en az 14 gün read-only mode’da tutulur, sonra decommission edilir. Tüm migration boyunca veri kalitesi testleri ile sürekli doğrulama yapılmalıdır.
Sonuç
2026’da yeni bir doküman veri katmanı seçerken varsayılan kararınız PostgreSQL JSONB olmalı. Sebep tek bir benchmark sayısı değil; tek motorda ACID, ilişkisel join, JSONB esnekliği, full-text search, vektör arama (pgvector), geospatial (PostGIS) ve time-series (TimescaleDB) elde etmenizdir. Karmaşıklık azalır, operasyon yüzeyi küçülür, mühendis havuzu daha geniştir.
MongoDB’yi seçmek için somut bir gerekçe olmalı: 50 TB+ doküman, native sharding, multi-region active-active, change streams, Atlas Search’e bağımlı text yetenekleri veya zaten MongoDB üzerinde işleyen olgun bir mühendislik organizasyonu. Bu gerekçeler varsa MongoDB hâlâ sınıfının en iyisi. Yoksa stack’i sadeleştirmek, uzun vadede her zaman daha düşük TCO ve daha az teknik borç demektir.
Hangi yöne karar verirseniz verin, veriyi taşıma planını mühendislik kararı olarak ciddiye alın: pilot, dual-write, reconcile, gradual cut-over. Daha derin yük profili analizi, geçiş planı veya hibrit mimari tasarımı için iletişim sayfasından ulaşabilirsiniz; senin yüküne göre 2 haftalık pilot tasarlayıp ölçülmüş bir karar verelim.
Kaynaklar ve daha derin okuma: PostgreSQL JSON Types resmi dokümantasyonu, MongoDB BSON ve document model docs, YCSB benchmark repo, Stack Overflow Developer Survey 2024 — Databases, DB-Engines Ranking, Percona MongoDB performance blog, AWS RDS PostgreSQL pricing.










Ömer ÖNAL
Mayıs 16, 2026Veri mühendisliği projelerinde sıkça gördüğüm darboğaz: pipeline mimarisine yatırım yapmadan önce veri kalitesi metriklerinin baseline’ı yok. Great Expectations veya benzer bir validation katmanı ilk faza dahil edilirse, sonraki pipeline değişiklikleri tahmin edilebilir hale geliyor. Yorumlarınız ne yönde?