When we use Atom.keepAlive, the cache persists forever — the Atom never refetches automatically. This works well for data that rarely changes, but it also means users could be looking at stale data indefinitely.
What if you want the benefits of caching—no spinner on every page visit—but also want the data to eventually refresh?
This is where Atom.setIdleTTL comes in. Instead of keeping the cache alive forever, you specify how long the cache should persist after all subscribers unmount. Once that time passes, the Registry discards the cache. The next time a subscriber mounts, the Atom fetches fresh data.
Let’s set a 2-second TTL to see this in action.
Update atoms/user.ts as shown below:
import { Atom } from "@effect-atom/atom-react";import { Duration, Effect } from "effect";
import { atomRuntime } from "@/atom-runtime";import { UserService } from "@/services/user-service";
// ============ Users Atom ============export const usersAtom = atomRuntime .atom( Effect.gen(function* () { return yield* UserService.getUsers(); }), ) .pipe(Atom.setIdleTTL(Duration.seconds(2)));Go to the home page and wait for the users to load. Click the Add User link to navigate away. Wait about 3 seconds, then return to the home page. You’ll see the spinner because the cache expired while you were away.
Now try again, but return within 2 seconds. The data loads instantly from cache because the TTL hadn’t expired yet.
Before continuing, update the TTL to a more practical value:
.pipe(Atom.setIdleTTL(Duration.hours(1)));