ai newsDi., 3. Nov.
EilmeldungLLMJacking: Stolen Credentials Fuel LLM Access Resale and $1M in Cumulative Charges

Your AI Agent's Memory Needs Two Clocks

Agent memory goes stale because it tracks when a fact was stored and not when it happened. A practical guide to bitemporal memory: event time and write time.

HackerNoonMontag 23:41 · 02.11.5 Min. Lesezeit
Bild: HackerNoon

Signup Write New Story Your AI Agent's Memory Needs Two Clocks by Rudraj Mehta by Rudraj Mehta | @ rudrajmehta Product @Mem0

Consumer agents run for years with the same user. A companion, a coach, or a journaling app collects thousands of small facts, most of which are only true for a while or evolve over time. Things like a race next Sunday, a trial ending in January, a trip last week, etc. With time, the memories stay in the pool even after the event time has passed.

Most setups store what the user said and when the system stored it, and nothing about when it actually happened. And the agent has no way to tell what is still true at retrieval time. For continuity, we will use one running example in this article - a fitness coach app called Stride, with a user named Sam.

Event time is when the thing happened: Sam ran the race on Sunday. Write time is when your app got to know about it: during a user’s chat session or during a later data import. Tracking these two independent timelines, when the event happened and when the system learned about it, is bitemporal reasoning, and relational databases have done it for decades. Most memory setups keep only write time, and that holds until the two timelines disagree. They disagree often, and we’ll discuss the list of possible cases here.

Stride has run for two years and wants to import old chats. Sam wrote "I ran my first 10K last weekend" in June 2025. Store it today, and the system reads "last weekend" against today, so the memory becomes "Sam ran a 10K this week," wrong by a year and stuck that way since the import loses the original date. Pass the original conversation time on every write and resolve the phrase against it.

memory.add( [{"role": "user", "content": "I ran my first 10K last weekend, finished in 58 minutes."}], user_id="sam", event_time=1750075200, # 2025-06-16, the day Sam said it )

The stored memory now reads "User ran a 10K on the weekend of 2025-06-14 to 2025-06-15," its created date reads June 2025, and a date filter for June 2025 finds it.

Sam says "I started the new knee meds yesterday." Resolve the phrase at write time, because only then do you know the actual conversation date, and store the date instead of the word. You also need a precision scale: "yesterday" is a day, "last month" is a month, and you should not invent an exact day from a vague phrase. Pass the exact instant the message was sent so time zones work out. "This morning" sent at 5 AM in Singapore is still the previous day in UTC.

Sam is vegetarian, then starts eating fish. Sam lives in Lisbon, then moves to Berlin. Both were true at different times, and a coach app that mixes them suggests tofu for lunch recommendations in a city Sam doesn’t live in anymore. Do not delete the old fact. It needs to be retained and linked to the new fact to create a chain of events. A user may ask need the current value or the history depending on different cases:

memory.search("Where do I go for dinner this weekend?", user_id="sam") memory.search("Where did I use to go for my weekend runs last year?", user_id="sam") 4. Facts with an end date "Training for the Berlin half on Nov 15" should stop affecting responses after Nov 15. "Dry January" ends Jan 31. Certain memories need an expiration setting at the time of writing, and the expiration should hide a memory rather than delete it, because the record still matters for history. The memory needs to stay visible through the date and drop out of search results the day after, with a way to show expired ones on request.

Before each reply, the coach app asks "what did Sam struggle with last week?" or "my knee injury’s progress from July to September." Two tools do different jobs:

Pass "now" into each read instead of letting the system decide the time autonomously. A nightly job at 02:00 UTC is morning in Singapore and the previous evening in San Francisco. An eval asking "what would the app have known on 2026-03-21?" should stay fixed as the day changes. A reference date fixes this.

memory.search("What did I eat last night?", user_id="sam", as_of="2025-08-10T12:00:00Z") 7. Old facts crowding out new ones After 18 months, 2025 knee injury memories continue to match for the keyword "knee." Memory age alone is not a strong enough signal; how often a memory still gets retrieved is a stronger one. Memories need to be retrieved based on usage-based reranking and not directly filtered, so a two-year-old allergy stays reachable while a healed injury drifts down, and comes back up only if Sam specifically mentions the knee again.

Sam says "I told you about my injury and you still pushed me to run hills." You need a way to reliably investigate what the app knew on a given day. Pull every memory written up to that date without any filters, and check whether the injury's creation date precedes the hill session.

For a single memory, its change history should return each write and update with the old text, the new text, and when it changed.

If you build or buy a memory layer for long-running consumer agents, these are the knobs it needs:

event-time, duration, and precision parameters on write

linking chain of events, with a current-only filter

an expiry field, plus a way to show expired

created-at filters with required logic operations

a created-at filter with per-memory history

The idea is simple: track both event time and write time for every memory with the above parameters and filters, and your app’s memory setup should be able to take care of almost all time-related scenarios.

Multi-tenant agent memory isolation is a filtering problem, not a ranking problem

Quelle: HackerNoon (HackerNoon). Original öffnen