Day — 4: Caching Client-side, CDN, server-side, cache invalidation
Every time your app asks the server for data it already has, you’re wasting your user’s battery, their data plan, and their time — and they…

Day — 4: Caching Client-side, CDN, server-side, cache invalidation
Every time your app asks the server for data it already has, you’re wasting your user’s battery, their data plan, and their time — and they feel it.
The Problem Every Android Dev Faces
You open an app. You saw this screen five minutes ago. The exact same data. But the app shows a spinner anyway, waits two seconds, then loads the same list you already saw.
That’s a caching failure. Not a network failure — a design failure.
Or the opposite: your app shows data from three days ago because it cached too aggressively and never refreshed. The user thinks the app is broken.
Both problems have the same root cause — no clear caching strategy. This article gives you one.
What Is Caching — Simply Explained
Caching means saving a copy of something close to you so you don’t have to go get it again.
Think of it like your kitchen. You don’t drive to the supermarket every time you need water. You have a bottle in the fridge. The fridge is your cache.

Your goal as an Android developer: answer as many requests as possible from Layer 1 or Layer 2. Only go to Layer 4 when you absolutely have to.
The 5 Caching Strategies — Simply Explained
Strategy 1 — Cache-Aside (the most common one)
Check the cache first. If the data is there — use it. If not — fetch from server, then save it in the cache for next time.
This is what Room + Repository pattern does in Android. It’s the right default for almost everything.
Strategy 2 — TTL (Time To Live)
The data expires after a set time. After 5 minutes, throw it away and fetch fresh data. Simple, but can show stale data right before expiry.
Strategy 3 — Write-Through
When the user changes something, update the cache AND the server at the same time. Always consistent, but every write is slightly slower.
Strategy 4 — Optimistic Update
Update the cache immediately when user does something (like, comment, edit). Then sync with server in the background. If the server fails — roll back.
This is what makes apps feel instant. The user taps Like — the heart fills immediately. They don’t wait for the server.
Strategy 5 — Invalidate on Write
When data changes, delete the old cached version completely. Next read fetches fresh data. Clean but causes one extra network request after every write.
Implementing It in Android
// The Cache-Aside pattern — the right default for Android
@Singleton
class ArticleRepository @Inject constructor(
private val api: ArticleApi,
private val dao: ArticleDao
) {
// Always show cached data first — user sees content instantly
// Then fetch fresh data — user gets updates without waiting
fun getArticles(): Flow<List<Article>> = flow {
// Step 1: Show what we have saved locally (works offline too)
val saved = dao.getAll()
if (saved.isNotEmpty()) emit(saved)
// Step 2: Quietly fetch fresh data from server
try {
val fresh = api.getArticles()
dao.deleteAll() // remove old cached data
dao.insertAll(fresh) // save new data
emit(fresh) // update the UI
} catch (e: IOException) {
// No internet — that's fine, user already sees saved data
if (saved.isEmpty()) throw e
}
}.flowOn(Dispatchers.IO)
// Optimistic update — feel instant, sync in background
suspend fun likeArticle(id: String) {
dao.setLiked(id, true) // update UI immediately
try {
api.likeArticle(id) // tell the server
} catch (e: Exception) {
dao.setLiked(id, false) // server failed — undo
}
}
// Invalidate on write — fresh data after any change
suspend fun deleteArticle(id: String) {
api.deleteArticle(id) // delete from server
dao.deleteById(id) // remove from local cache too
}
}
Common Mistakes Android Developers Make
Mistake 1 — Fetching from network every time the screen opens
// ❌ Every screen open = network request = spinner = bad UX
override fun onResume() {
viewModel.loadFromNetwork()
}
// ✅ Show cache instantly, refresh quietly in background
val articles = repo.getArticles() // emits cache first, then network
Mistake 2 — Caching data that changes every second
Don’t cache live scores, stock prices, or real-time chat messages. Cache things that stay the same for minutes or hours — articles, profiles, product lists.
Mistake 3 — Never invalidating the cache
// ❌ User deletes a post — but cache still shows it
api.deletePost(id)
// ✅ Always clean up the cache when data changes
api.deletePost(id)
dao.deleteById(id) // remove from cache too
Mistake 4 — Caching sensitive data on disk
Never cache auth tokens, passwords, or payment info in OkHttp disk cache or Room without encryption. Use EncryptedSharedPreferences or SQLCipher for anything sensitive.
Production-Ready Example — WorkManager Background Sync
// Sync cache in background even when app is closed
class SyncWorker(ctx: Context, params: WorkerParameters)
: CoroutineWorker(ctx, params) {
override suspend fun doWork(): Result {
return try {
val fresh = api.getArticles()
dao.deleteAll()
dao.insertAll(fresh)
Result.success()
} catch (e: Exception) {
if (runAttemptCount < 3) Result.retry()
else Result.failure()
}
}
}
// Schedule sync every 15 minutes — only when on WiFi
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
"article_sync",
ExistingPeriodicWorkPolicy.KEEP,
PeriodicWorkRequestBuilder<SyncWorker>(15, TimeUnit.MINUTES)
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED) // WiFi only
.build()
).build()
)
Key Takeaways
- Caching means saving data close to you so you don’t fetch it again — like keeping water in your fridge instead of going to the supermarket every time.
- Show cached data first, fetch fresh data in the background — this makes your app feel instant even on slow connections.
- Cache-Aside with Room is the right default for Android — emit from Room first, then network, then Room again.
- Optimistic updates (update UI instantly, sync in background) are what make apps feel fast — not faster internet.
- Never cache sensitive data unencrypted on disk — auth tokens, passwords, and payment info need encryption.
AndroidDevelopment #SystemDesign #Kotlin #MobileDevelopment #SoftwareEngineering
메타데이터
- post_id
- d6987b4deed6
- slug
- day-4-caching-client-side-cdn-server-side-cache-invalidation-d6987b4deed6
- url
- https://medium.com/@a7medsa3dkenawy/day-4-caching-client-side-cdn-server-side-cache-invalidation-d6987b4deed6
- canonical_url
- https://medium.com/@a7medsa3dkenawy/day-4-caching-client-side-cdn-server-side-cache-invalidation-d6987b4deed6
- author_url
- https://medium.com/@a7medsa3dkenawy
- status
- ok
- fetched_at
- 2026-06-12 07:40:50