Caching in Kotlin: Redis, Memcached, and Built-in Solutions: from A to Z
\n\nModern Kotlin applications require high response speed and efficient data processing. One of the key tools for achieving this goal is caching. In this article, we will cover three approaches: using Redis, Memcached, and built-in solutions at the JVM level. You will learn how to choose the right strategy and get ready-made code examples for integration into your project.
\n\n1. Built-in Caching in Kotlin (In-Memory Cache)
\n\nThe simplest way is to use a cache within the application. In Kotlin (running on the JVM), you can use standard collections or specialized libraries such as Caffeine or Guava Cache.
\n\nExample with Caffeine (recommended)
\nAdd the dependency to build.gradle.kts:
implementation("com.github.ben-manes.caffeine:caffeine:3.1.8")\n\nCreate a caching service:
\nimport com.github.benmanes.caffeine.cache.Cache\nimport com.github.benmanes.caffeine.cache.Caffeine\nimport java.util.concurrent.TimeUnit\n\nclass UserCache {\n private val cache: Cache<String, User> = Caffeine.newBuilder()\n .expireAfterWrite(10, TimeUnit.MINUTES)\n .maximumSize(1000)\n .build()\n\n fun getUser(id: String): User? = cache.getIfPresent(id)\n\n fun putUser(id: String, user: User) {\n cache.put(id, user)\n }\n}\n\nPros: minimal latency, no network calls, easy setup.
\nCons: cache is lost on application restart, limited by JVM memory size.
2. Caching with Redis in Kotlin
\n\nRedis is a powerful in-memory store that supports complex data structures. Ideal for distributed systems.
\n\nSetup via Spring Data Redis
\nAdd the dependency:
\nimplementation("org.springframework.boot:spring-boot-starter-data-redis")\nimplementation("org.jetbrains.kotlin:kotlin-reflect")\n\nConfiguration (application.yml):
\nspring:\n redis:\n host: localhost\n port: 6379\n timeout: 2000ms\n lettuce:\n pool:\n max-active: 8\n max-idle: 4\n\nExample service with Spring Cache annotations:
\nimport org.springframework.cache.annotation.Cacheable\nimport org.springframework.stereotype.Service\n\n@Service\nclass ProductService {\n\n @Cacheable("products", key = "#id")\n fun getProduct(id: Long): Product {\n println("Loading from DB: $id")\n return Product(id, "Product $id")\n }\n}\n\nFor working with Redis directly (without Spring):
\nimport io.lettuce.core.RedisClient\nimport io.lettuce.core.api.sync.RedisCommands\n\nclass RedisCache {\n private val commands: RedisCommands<String, String>\n\n init {\n val client = RedisClient.create("redis://localhost:6379")\n commands = client.connect().sync()\n }\n\n fun set(key: String, value: String, ttlSeconds: Long = 300) {\n commands.setex(key, ttlSeconds, value)\n }\n\n fun get(key: String): String? = commands.get(key)\n}\n\nPros: distributed cache, persistence, support for TTL and complex structures.
\nCons: requires a separate server, slightly higher latency (network call).
3. Caching with Memcached in Kotlin
\n\nMemcached is a lightweight distributed store optimized for storing small objects in memory.
\n\nIntegration via the xmemcached library
\nAdd to build.gradle.kts:
implementation("com.googlecode.xmemcached:xmemcached:2.4.8")\n\nUsage example:
\nimport net.rubyeye.xmemcached.MemcachedClient\nimport net.rubyeye.xmemcached.XMem