Spring Boot auto-configuration for chat memory functionality in Spring AI applications
Performance optimization guidance for Spring AI Chat Memory.
Best Practice: Use persistent repository for production to avoid memory constraints.
Optimization Tips:
Index conversation_id column:
CREATE INDEX idx_conversation_id ON chat_memory(conversation_id);Connection Pooling:
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.minimum-idle=5Batch Operations: Use add(conversationId, List<Message>) instead of multiple single adds
Partitioning: For very large datasets, consider table partitioning by conversation_id
Query Performance:
Optimization Tips:
Enable Indexes:
spring.ai.chat.memory.repository.mongo.create-indices=trueTTL for Automatic Cleanup:
spring.ai.chat.memory.repository.mongo.ttl=PT24HWrite Concern: Adjust based on durability vs. performance needs
mongoTemplate.setWriteConcern(WriteConcern.ACKNOWLEDGED);Read Preference: Use secondary reads for non-critical queries
Performance Characteristics:
Optimization Tips:
Partition Key Design: conversation_id as partition key provides optimal distribution
Consistency Level: Adjust based on requirements
.withConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM)TTL at Table Level:
spring.ai.chat.memory.repository.cassandra.time-to-live=P30DPerformance Characteristics:
Optimization Tips:
Performance Characteristics:
Optimization Tips:
.consistencyLevel(ConsistencyLevel.SESSION)Performance Characteristics:
Bad Practice (Multiple network calls):
for (Message message : messages) {
chatMemory.add(conversationId, message); // N network calls
}Good Practice (Single network call):
chatMemory.add(conversationId, messages); // 1 network callPerformance Impact: 10-100x faster for batch operations
All repository implementations should be thread-safe:
// Safe for concurrent access
conversationIds.parallelStream()
.forEach(id -> chatMemory.add(id, new UserMessage("test")));For high-concurrency scenarios, consider conversation-level locking:
private final ConcurrentHashMap<String, ReentrantLock> locks = new ConcurrentHashMap<>();
public void addWithLock(String conversationId, Message message) {
ReentrantLock lock = locks.computeIfAbsent(conversationId, k -> new ReentrantLock());
lock.lock();
try {
chatMemory.add(conversationId, message);
} finally {
lock.unlock();
}
}@Scheduled(cron = "0 0 2 * * *") // Daily at 2 AM
public void cleanupOldConversations() {
List<String> ids = repository.findConversationIds();
Instant cutoff = Instant.now().minus(Duration.ofDays(30));
ids.parallelStream()
.filter(id -> isOlderThan(id, cutoff))
.forEach(repository::deleteByConversationId);
}MongoDB:
spring.ai.chat.memory.repository.mongo.ttl=P7DCassandra:
spring.ai.chat.memory.repository.cassandra.time-to-live=P30D@Service
public class CachedChatMemoryService {
@Autowired
private ChatMemory chatMemory;
private final LoadingCache<String, List<Message>> cache = Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterWrite(Duration.ofMinutes(10))
.build(conversationId -> chatMemory.get(conversationId));
public List<Message> getCached(String conversationId) {
return cache.get(conversationId);
}
public void invalidate(String conversationId) {
cache.invalidate(conversationId);
}
}When to Use:
When NOT to Use:
repository.findConversationIds().size()@Component
public class ChatMemoryMetrics {
@Autowired
private ChatMemoryRepository repository;
@Autowired
private MeterRegistry meterRegistry;
@Scheduled(fixedRate = 60000)
public void recordMetrics() {
int conversationCount = repository.findConversationIds().size();
meterRegistry.gauge("chat.memory.conversations", conversationCount);
}
}| Operation | In-Memory | JDBC | MongoDB | Cassandra | Neo4j | Cosmos DB |
|---|---|---|---|---|---|---|
| Add Message | < 1ms | 5-10ms | 5-10ms | 2-5ms | 10-20ms | 10-30ms |
| Get Messages | < 1ms | 5-15ms | 5-10ms | 5-10ms | 15-30ms | 10-30ms |
| Clear Conversation | < 1ms | 10-20ms | 5-10ms | 5-10ms | 20-40ms | 10-30ms |
Note: Actual performance varies based on:
tessl i tessl/maven-org-springframework-ai--spring-ai-autoconfigure-model-chat-memory@1.1.0