Skip to content

What is shelf?

shelf combines ETS (fast, in-memory) with DETS (persistent, on-disk) to give you microsecond reads with durable storage. It implements the classic Erlang persistence pattern, wrapped in a type-safe Gleam API.

block-beta
  columns 2
  App["Your Application"]:2
  Shelf["shelf (this library)"]:2
  ETS["ETS (memory)\n• μs reads\n• μs writes\n• in-process"]
  DETS["DETS (disk)\n• persistence\n• survives restarts"]

Reads always go to ETS — consistent microsecond latency regardless of table size.

Writes go to ETS immediately. Persistence to DETS depends on the write mode.

If you only need ETS or DETS individually, check out these standalone wrappers:

  • bravo — Type-safe ETS wrapper for Gleam
  • slate — Type-safe DETS wrapper for Gleam

shelf coordinates both together, using Erlang's native ets:to_dets/2 for efficient bulk saves. When loading from disk, entries are validated individually through user-provided decoders, ensuring type safety at the boundary between untyped DETS storage and your Gleam code.

  • Microsecond reads: All reads go through ETS for consistent performance
  • Cross-process reads: ETS tables are created protected, so any process can read them concurrently while a single owner handles writes
  • Runtime type safety: Decoder-gated loading ensures data from disk matches your Gleam types
  • Write modes: Choose between WriteBack (batched) or WriteThrough (immediate persistence)
  • Three table types: set, bag, duplicate_bag
  • Atomic counters: Increment integer values atomically in ETS
  • Safe resource management: with_table ensures tables are always closed
  • No native dependencies: No NIFs or build steps; backed entirely by OTP's built-in ETS and DETS