TahminApp kendi yan projem: küçük ölçekli bir spor tahmin uygulaması, hâlâ geliştirme aşamasında. Aşağıdakiler ölçülmüş ürün sonuçları değil; projenin mimari tasarım kararları ve tasarım hedefleri.
Problem: Spor tahmin platformunda gerçek zamanlı maç olayları (gol, kart, devre arası) anında 500K+ kullanıcıya push notification gönderme + canlı skor akışını UI'da güncelleme.
Tasarım hedefleri: 500K MAU, p99 latency 180ms, %99.9 üstü uptime, >30dk süren incident yok. Hiçbiri ölçülmüş bir sonuç değil — mimari bu hedeflere göre kuruluyor.
Pro Tip: Bottleneck beklediğin yer değil. Bu tasarımda Firestore write değil, push delivery routing. Her büyük scaling hikâyesi aynı şekilde başlar.
1. Architecture Overview
3-tier:
- Edge layer (CF Workers): Webhook receiver, dedup, fan-out trigger
- Backend (Firestore + Cloud Functions): Persistent state, business logic
- Mobile (iOS native + Flutter Android): Realtime listener + push notification handler
1[Sports Data Feed]2 ↓ webhook3[CF Worker — dedup + transform]4 ↓ event5[Cloud Function — match state update]6 ↓ write7[Firestore — predictions, users, scores]8 ↓ realtime listener9[Mobile Apps — UI update]10 ↓11[FCM/APNs — push notification]2. Bottleneck Hikayesi
İlk hipotez: Firestore writes scale etmez. Bu ölçekte tutmaz — sharding ile çözülür.
İkinci hipotez: Cloud Functions cold start sorun. Warm instance pool ile bu da elenir.
Asıl bottleneck: APNs delivery latency. 500K push'luk bir fan-out'ta varsayılan routing 30 saniye değil 4-6 dakika bandında teslim eder. Büyük maç anlarında "geç bildirim" şikâyetinin tipik kaynağı budur.
Çözüm: Priority routing — match-event push'lar apns-priority: 10 + Cloudflare Workers'tan paralel batch send. Hedef: 500K push 25-35sn bandında teslim.
3. Firestore Tasarımı
500K user × 50 prediction/user × 100 match/season = 2.5M document. Naive design /predictions/{id} bu hacimde çöker.
Doğru pattern — sharded collection:
1/predictions/shard-{0-19}/items/{predictionID}Shard count 20, prediction ID hash'inden assignment. Her shard ayrı index, ayrı write limit. Toplam write throughput 20x.
Realtime listener: Mobile listen /predictions/shard-{userShard} — sadece kendi shard'ını izle. Network savings %95.
4. Cloud Functions Patterns
Tasarımda 40+ Cloud Function öngörülüyor. En kritik 3'ü:
onMatchEvent: webhook trigger, dedup window 30sn, state update + push triggeronPredictionWrite: leaderboard recalc (sharded counter pattern)onUserWrite: profile cache invalidation (Cloudflare KV pürge)
Her function:
- Memory: 256MB (most), 1GB (leaderboard)
- Timeout: 60s
- Max instances: 1000 (auto-scale)
- Retry: 3x exponential backoff
- Idempotency:
eventIDFirestore set-based dedup
5. iOS App Architecture
iOS native (SwiftUI iOS 16+):
- TCA (The Composable Architecture) state management
- Firestore Snapshot Publisher — Combine pattern
- APNS Notification Service Extension — payload decryption + smart action
- Local cache (SwiftData) — offline read-only mode
Memory baseline hedefi: 95MB. Peak (match-time live UI): 145MB.
Crash-free session rate için hedef bant: %99.8+ (Crashlytics ile izlenir).
6. Cost Profile
Tasarımın aylık infrastructure bütçe tahmini (500K MAU peak hedefi varsayımıyla):
Kalem | Cost |
|---|---|
Firestore (read/write/storage) | $420 |
Cloud Functions (invocations) | $180 |
Cloud Messaging (FCM) | $0 (free tier OK) |
APNs | $0 (Apple side) |
Cloudflare Workers | $25 (Pro plan) |
Cloudflare KV | $5 |
Hetzner monitoring server | $7 |
Toplam | $637/ay |
Per-user cost: $0.00127/user/ay. Indie unit economics için fazlasıyla yeterli bir bant.
7. Öğrenimler (Lessons Learned)
1. Tahmin edilen bottleneck nadiren gerçek bottleneck. APNs delivery gibi kalemler ancak gerçek trafik altında görünür; launch sonrası ilk haftalarda ölçüm planı hazır olmalı.
2. Sharding'i ön ödeme yap. 500K user'a vardıktan sonra sharding eklemek aylarla ölçülen teknik borç demek.
3. Idempotency event ID kritik — webhook retry'ları aksi hâlde sessiz duplicate yaratır.
4. Notification Service Extension content modification + alert prioritization için altın.
5. Edge layer (CF Workers) üzerinde dedup + transform yapmak Cloud Functions maliyetini kat kat düşürür.
6. Crashlytics + custom telemetry ikisini birden çalıştır. Crashlytics aggregation, custom telemetry decision data.
7. Bu ürün sınıfında App Store yorumlarının en çok döndüğü konu, büyük maç anlarındaki ortalama notification latency'si. Latency'yi optimize etmek doğrudan rating'i hareket ettiren kalemdir.
Sonuç: 500K user ölçeği genellikle "Firestore" sorunu değil, "delivery infrastructure" sorunu. Architecture'ı en başta multi-tier kur, ölç ve refactor et.
Etiketler
iOS Geliştirme Haberleri
Haftalık Swift tips, SwiftUI tricks ve iOS best practices. Spam yok, sadece değerli içerik.
Onay e-postasındaki bağlantıyı açıp “Aboneliğimi onayla” düğmesine bastığında aboneliğin başlar. Bültende açılma/tıklama istatistikleri tutulur; dilediğin an tek tıkla ayrılabilirsin. Gizlilik
