Use an Elixir map when one process owns the index and can pass updated immutable state explicitly. Consider ETS when multiple processes need keyed access to shared index data. Neither is universally faster: the right choice depends on posting-list sizes, update patterns, concurrency, and consistency requirements, so benchmark a representative workload before deciding.
What an inverted index stores
An inverted index maps a term to the document or record IDs that contain it. For example, the key "elixir" might map to a collection of IDs such as [12, 31, 48]. It is a secondary lookup structure: it can speed up term searches, but it must remain consistent with the source records.
Repeated terms need a representation that can hold multiple relationships. With a map, store a list or set of IDs as the value for each term. With ETS, you can likewise store one posting collection per term, or use a bag table to store separate term–ID objects.
Map or ETS: how to choose
| Decision | Map | ETS |
|---|---|---|
| Ownership and access | Fits an index owned by one process, with updated map values passed explicitly. | A runtime table can be accessed across processes; choose its owner and access mode deliberately. Elixir ETS guide and Erlang/OTP ETS reference. |
| Posting representation | Map each term to a list or set of matching IDs; choose based on the queries and updates you need. | Use a set for one posting-list object per term, a bag for separate objects sharing a term key, or an ordered_set when ordered keys matter. Erlang/OTP ETS reference. |
| Updates | An update produces an updated map value. | Operations mutate shared table state. If a posting list is one value, changing one ID may require a read-modify-write; separate bag objects have different update and deletion behavior. |
| Lifecycle | The value remains available as long as application references or process state retain it. | The table is destroyed when its owner exits unless ownership is transferred or otherwise managed. Erlang/OTP ETS reference. |
| Performance evidence | Do not assume performance from the word “map” or from small-map guidance alone. | ETS documents table-operation complexity, but that does not establish which complete inverted-index design is faster for your workload. |
When a map is a good fit
A map is a straightforward starting point when one process owns the index and other parts of the application can work with state passed to them. It keeps index access and updates within that process’s state-management model, without introducing an ETS table owner and access policy.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
The posting value still matters. A list or set of IDs may be simple to query, but updates to a term’s collection should be considered alongside how often documents are added or removed. There is no general performance recommendation for an inverted index implied by the Erlang/OTP documentation on maps. Its description of “small maps” means maps with at most 32 elements; that is a terminology boundary, not a recommended index size. Erlang/OTP Maps documentation.
When ETS is a good fit
ETS is a strong candidate when several processes need access to keyed index entries. The table type should match the shape of your postings:
set: one stored object per term, such as a term paired with its full posting list. The ETS reference describes insertion and lookup time as constant regardless of table size.bagorduplicate_bag: multiple objects can share a key, which can represent separate term–ID relationships. The documented operation cost depends on the number of objects with that key.ordered_set: useful when ordered keys are part of the access pattern. The ETS reference describes operation time as proportional to the logarithm of the number of stored objects.
These are documented complexity descriptions, not wall-clock guarantees for a complete application. Index updates, fetching source records, posting-list size, contention, and the rest of the query path all affect end-to-end results. Erlang/OTP ETS reference.
Plan ETS ownership and access
An ETS table has an owner, and its lifetime is tied to that owner unless ownership is transferred. Decide which process creates and supervises the table, and what should happen to the index when that process stops. An accidental owner exit can remove the table and its contents.
Rank #3
Access mode is another design decision. A protected table can be read by all processes but written only by its owner; public and private have different access rules. Choose the narrowest access that supports your application, and make the owner and restart plan explicit. Elixir ETS guide and Erlang/OTP ETS reference.
Account for index consistency and concurrency
Because the index is secondary to the source records, every relevant insert, update, or deletion must be reflected in the postings. That maintenance adds write work; the trade is worthwhile when it saves enough search work. Erlang/OTP’s tables-and-databases guide illustrates using a secondary index to resolve a non-unique field to IDs before fetching source rows, and notes both the need to maintain the index and the insertion overhead. Erlang/OTP Tables and Databases.
Rank #4
Also decide what consistency a search needs while records and postings are changing. A single ETS operation does not by itself settle how your application coordinates a multi-step change across source data and index entries. If you store a whole posting list under one key, changing one relationship can involve a read-modify-write; if you use separate bag objects, additions and removals have their own semantics. Choose the representation and update protocol together.
ETS supports concurrency options, but they are workload-dependent tuning choices. The Elixir guide demonstrates read_concurrency: true for concurrent reads and cautions against adding ETS caching before measuring bottlenecks. Enable concurrency options only when representative measurements justify them. Elixir ETS guide and Erlang/OTP ETS reference.
Recommended Free Tools
Best Value
Benchmark the workload that matters
The official documentation does not publish a direct benchmark comparing maps and ETS for this inverted-index workload. Benchmark the actual access and update pattern instead of treating a table’s complexity description as a prediction of application throughput.
- Use a representative term distribution, including common terms and terms with long posting lists.
- Measure lookups as well as insertions and deletions, including the cost of maintaining the index alongside source records.
- Include index startup or rebuild time, memory use, and the mix of concurrent readers and writers your application expects.
- Compare the posting representation you would deploy: a list or set value per term versus separate ETS bag objects.
- Check whether the measured design preserves the consistency your search results require.
Elixir’s ETS guide advises: “Don’t use ETS as a cache prematurely! Log and analyze your application performance and identify which parts are bottlenecks, so you know whether you should cache, and what you should cache.” The same discipline applies when deciding whether an index belongs in ETS or a map. Elixir ETS guide.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

