Memory Expiration
Some facts are only true for a while. A trial plan ends, a seasonal preference goes stale, a support ticket ages past its retention window. Set anexpiration_date on a memory and Mem0 stops surfacing it once that date passes, so you don’t need a cleanup job hunting for rows to delete.
Expiration hides a memory, it does not delete it. The record stays in storage untouched. search() and get_all() skip it, fetching it by ID still returns it, and clearing the date brings it straight back.
How it works
- Format: a plain
YYYY-MM-DDdate. No time component, no timezone offset. - Evaluated in UTC, never against the caller’s local timezone.
- Inclusive of the date itself: a memory set to expire on
2030-01-31stays visible all through2030-01-31UTC and disappears on2030-02-01. - Only list-shaped reads filter:
search()andget_all()(getAll()in TypeScript) hide expired memories.get(memory_id)always returns the memory, so there is noshow_expiredparameter on that path. - No expiration date means never expires. That is the default for every memory.
- Malformed dates fail open: a stored value Mem0 can’t parse is treated as not expired. A bad date never makes a memory silently vanish.
Set an expiration date
Set it when you add the memory:update():
Read expired memories back
Passshow_expired (showExpired in TypeScript) to include them. It defaults to false on every client.
Memory class. See Search Memories and Get Memories.
Expired memories are dropped before your
top_k is applied, so Mem0 widens the internal candidate pool first and short result sets are rare. They are not impossible: if nearly every memory in a scope has expired, a call can still return fewer than top_k results. Pass show_expired: true to get the full set back.Clear an expiration date
Pass an explicitNone (Python) or null (TypeScript) to make the memory permanent again. The SDKs deliberately preserve that null instead of treating it as “argument not supplied”.
update() needs at least one of text, metadata, or expiration_date, and raises if you pass none of them. Clearing the date satisfies that on its own: the memory’s content and metadata are left alone.What each client accepts
| Client | Accepted input | Notes |
|---|---|---|
| Python (Platform and OSS) | str in YYYY-MM-DD form, or a date / datetime object | Normalized to YYYY-MM-DD before storage. |
| TypeScript (Platform and OSS) | string in YYYY-MM-DD form only | Stricter than new Date(): rejects 12/31/2099, 2099-12-31T23:00:00, and non-days like 2099-02-30 or 2100-02-29. |
| Self-hosted REST server | string in YYYY-MM-DD form | Same normalization as OSS Python underneath. |
CLI (mem0 add --expires) | string in YYYY-MM-DD form | Must be strictly in the future, checked against the local system date. The SDKs have no such restriction. Platform only: the CLI has no OSS backend. |
Reading the field back
Most clients return expiration as a top-level field on the memory:expiration_date in Python (Platform and OSS) and in the REST API, expirationDate in the Platform TypeScript SDK.
The OSS TypeScript SDK is the one exception. There, expiration round-trips under
result.metadata.expiration_date, not result.expirationDate, on both get() and getAll().Expiration, decay, and delete
These three get conflated. They solve different problems:| Memory Expiration | Memory Decay | Delete | |
|---|---|---|---|
| What it does | Hides a memory once a date you set passes | Re-ranks results by how recently a memory was used | Removes a memory permanently |
| Data still stored? | Yes | Yes | No |
| Filters results? | Yes, after the date | Never, it only reorders scores | Yes, permanently |
| Reversible? | Yes, clear or push back the date | Yes, toggle decay off | No |
| Set where | Per memory, by you | Per project, opt-in | Per call |
| Available in | Platform and OSS | Platform only | Platform and OSS |
Common patterns
Trial and subscription facts. “Alice is on the Pro trial” is true until the trial ends. Setexpiration_date to that end date when you write the fact. If she upgrades, clear the date and the memory becomes permanent. If she doesn’t, it stops surfacing the next day on its own.
Seasonal preferences. “Alex wants gift ideas for the holidays” matters in December and is noise in July. A short-lived expiration date keeps it from competing with evergreen preferences in every search.
Retention windows. Data-retention policies usually want a soft window before a hard delete: keep a ticket’s memories searchable for 90 days, stop surfacing them, purge them later on a schedule. Expiration is the soft step, and a scheduled delete is the permanent one.