Sitemap

Coil — A simple image loader for Android

2 min readFeb 5, 2026

--

Press enter or click to view image in full size

Coil is a simple Android library to load images. It has 2 levels of cache enabled by default:

  • Memory cache
  • Disk cache

The memory cache has a size between 20% to 25%, which is not the percentage of your memory ram, but a combination of ram, screen resolution and other factors. From my test, I can see it is about 195 MB on Pixel 9 Pro XL, which makes it around 10 MB.

The disk cache has a default size of 2% of available space. This size has a constraint of minimum 10 MB and Maximum 250 MB (Coil version 3.3.0).

To attach the image loaded, update the Application class

class MyApplication: Application(), SingletonImageLoader.Factory {
override fun newImageLoader(context: PlatformContext): ImageLoader {
return ImageLoader(this).newBuilder()
.build()
}
}

To change the memory cache, which could be set by maximum size or per maximum percentage, it is done as following.

ImageLoader(this).newBuilder() // this is context
.memoryCachePolicy(CachePolicy.ENABLED)
.memoryCache {
MemoryCache.Builder()
.maxSizePercent(this, 0.1) // 10%
// or it can be set as size as
// .maxSizeBytes(10 * 1024 * 1024) // 10 MB
.strongReferencesEnabled(true)
// or weak reference
// .weakReferencesEnabled(true)
.build()
}
.build()

The disk cache could be updated as following:

import coil3.disk.DiskCache
import coil3.disk.directory

ImageLoader(this).newBuilder() // this is context
.diskCachePolicy(CachePolicy.ENABLED)
.diskCache {
DiskCache.Builder()
.maxSizePercent(0.03)
.directory(cacheDir)
.build()
}
.networkCachePolicy(CachePolicy.ENABLED)
.build()

Note the import of the extension coil.disk.directory . Otherwise the code won’t compile.

The network cache policy need to be enabled. This is allow the backend send TTL (Time To Live) along with the image response, which will tell to the app how long in seconds that the image should remain valid.

Get Switch your coding life’s stories in your inbox

Join Medium for free to get updates from this writer.

Beside this, the disk cache works as LRU cache (Least Recent Used) cache, meaning that once it is full, the least used content will be removed.

Here is an example of how to load an image

val imageUrl = "https://www.livehome3d.com/assets/img/articles/design-house/how-to-design-a-house@2x.jpg"
AsyncImage(
model = imageUrl,
contentDescription = null,
modifier = Modifier
.fillMaxWidth()
.aspectRatio(1400f/800f)
)

It also have logger, that could be attached as following:

import coil3.util.DebugLogger

ImageLoader(this).newBuilder()
.logger(DebugLogger())
.build()

With the following command on the console, you should be able to see the image request and responds.

adb logcat RealImageLoader:I \*:S

This is what it will show (disk, memory, network and cancelled request)

02-05 17:36:38.565  2065  2065 I RealImageLoader: 💾 Successful (DISK) - https://.....
02-05 17:36:39.730 2065 2065 I RealImageLoader: 🧠 Successful (MEMORY_CACHE) - https://.....
02-05 17:37:14.563 2065 2065 I RealImageLoader: ☁️ Successful (NETWORK) - https://.....
02-05 21:12:54.158 4077 4077 I RealImageLoader: 🏗 Cancelled - .....

Now, once the image is stored, either we can remove the whole content of the cache

imageLoader.diskCache?.clear()
imageLoader.memoryCache?.clear()

Or remove a specific image

imageLoader.diskCache?.remove("MyImageKey")
imageLoader.memoryCache?.remove(MemoryCache.Key("MyImageKey"))

Source: https://www.youtube.com/watch?v=qQVCtkg-O7w

Source code: https://github.com/jiahaoliuliu/CoilImageCaching

--

--

Switch your coding life
Switch your coding life

Written by Switch your coding life

[Remote available] I am a software engineer with 15 years of experience. Currently, I am working at Glovo, one of the biggest food delivery companies in Europe.