Why Your AI Chatbot Forgets Everything — And How to Fix It A developer demonstrated how to give a stateless LLM chatbot persistent memory by storing per-session conversation history in a Java ConcurrentHashMap and resending the full message list on every Gemini API call, then outlined the approach's limits — data loss on server restart, shared-state concurrency issues, and unbounded token growth — and proposed PostgreSQL-backed persistent storage with session isolation as the production fix. In the last article we built a working chat endpoint. Send a message, get a reply. It felt like magic. Then I tried to have an actual conversation. Me: "My name is Sham." AI: "Hi Sham How can I help you?" Me: "What's my name?" AI: "I don't have access to personal information about you." The model had completely forgotten who I was. Not because it was broken — because of something fundamental about how LLMs work. Every API call is completely independent. The model has no memory between calls. If you want it to remember anything, that's your problem to solve. This article shows how — starting from the simplest possible solution, hitting its limits, then building the real one. When you call the Gemini API, you send a list of messages. The model reads them, generates a reply, and the call ends. The next call starts completely fresh — the model has no idea the previous call ever happened. So when the user sends message 5, the model only sees message 5. It has no knowledge of messages 1 through 4. The fix is simple in concept: include all previous messages in every call. Send the full conversation history every time, so the model always has context. Let's build that. The simplest fix: a Map where the key is a session ID and the value is the list of messages for that session. @RestController @RequestMapping "/api/chat" public class ChatController { private final ChatClient chatClient; // session ID → list of messages for that session private final Map