Skip to main content
xyz.refineryteam.refinerycore.api.storage provides a non-persistent, in-memory key-value store for data that only needs to live for the current server session (or shorter, via TTLs) — combat tags, pending confirmations, session caches, and similar. Nothing in this package ever touches disk or survives a restart.
Need data to actually survive a restart? Use Database and a Repository instead — that’s the persistent-storage layer.

TemporaryStorage<K, V>

The core contract — a typed key-value store scoped to a single key/value type pair:
TemporaryStorage.java
The Duration ttl overload of put stores a value that automatically expires — and is treated as absent — once the duration elapses.

InMemoryStorage — the default implementation

A ConcurrentHashMap-backed implementation of TemporaryStorage, safe for concurrent access from multiple threads (e.g. async tasks alongside the main thread):
MainStorage.java
Expired entries are treated as absent lazilyget, contains, keys(), and size() all check expiry on access and evict the entry if it’s expired, so correctness doesn’t depend on any background task running.

Proactive cleanup

If you’d rather not wait for the next access to evict expired entries (e.g. to keep size() accurate for a live display, or just for general memory hygiene), schedule periodic cleanup:
MainStorage.java
This is purely a housekeeping convenience — get() already treats expired entries as absent regardless of whether this is called.

StorageRegistry — named stores

Rather than declaring a TemporaryStorage field for every unrelated system in your plugin, StorageRegistry hands out named instances on demand, backed by a shared registry:
MainStorage.java
Each name lazily creates its own independent InMemoryStorage the first time it’s requested, and returns the same instance on subsequent calls with that name.
StorageRegistry#of is generically typed per call site (TemporaryStorage<K, V> of(String name)), but the underlying map only tracks one instance per name — reusing the same name with different K/V type parameters elsewhere in your plugin will produce ClassCastExceptions at runtime. Keep store names unique per logical key/value shape.