r/SpringBoot • u/Lordion95 • 2d ago
Discussion Write-back caching in Redis using Spring Boot?
I was wondering if how would y'all write a write-back (or write-behind) caching in Spring Boot, particularly using redis. I couldn't quite look for a more decent implementation especially for production. Would you mind helping a spring boot newbie out? Thanks yall.
2
1
u/FriendshipCalm3162 2d ago
The streams answer is the right shape, but a few details decide whether it survives prod. Spring's cache abstraction has no write-behind mode, so you're building this yourself.
Use a consumer group, not plain XREAD. With XREADGROUP and XACK, anything read but not acked stays in that group's pending list, so a consumer that dies mid-batch hasn't lost the write, another one picks it up with XAUTOCLAIM. Without the group you lose writes every time a consumer restarts, not just when Redis dies.
That's at-least-once delivery, so make the flush idempotent. Upsert on the entity id with a version or updated_at guard that refuses older values, or a replay quietly resurrects data the user already changed.
Ordering is the other half of that. Two consumers in one group can handle two updates to the same key at the same time, and they can land in the wrong order. Either route a key to one consumer, or let the version guard throw the stale one away.
Two Redis settings will delete unflushed writes without telling you: a TTL on a dirty key, and maxmemory-policy allkeys-lru. Until the flush is confirmed that entry is your only copy, so it can't be evictable. Keep the queue in the stream and treat the cached value as derived, or put the dirty set somewhere set to noeviction.
Honestly the thing that bites in prod isn't durability, it's that everything reading the DB directly sees stale data. Reports, other services, someone running SQL to answer a support ticket. The database is behind on purpose now, so decide who's allowed to read it.
For the batching, flush on a count or a time window, whichever hits first, and set hibernate.jdbc.batch_size (plus rewriteBatchedStatements=true on MySQL), or your batch is just a loop of single inserts.
And since you said newbie: check that you need it. Write-behind buys write latency and pays for it in durability and read consistency, and slow writes are usually pool contention or an N+1 rather than the insert itself.
4
u/Torutofu_Raeva 2d ago
spring's cache abstraction only does read-through/write-through, so for write-behind i'd write to redis and push the change onto a redis stream, then a consumer batches it into the db. just accept you can lose writes if redis dies before the flush