Using dictionary like data structures is very common in software engineering; storing indexed data, accessing stateful entities by id and so on. There are many ways and technologies to implement this; in this article I’m demonstrating a few ways how Akka actors can be used to store and access indexed data or entities. I’m going to compare four different approaches to store dictionary like data: In-memory Scala Map In-memory Akka actor Persistent actor cluster singleton Persistent entity actors with cluster sharding The benchmark consists of two parts: we fill a dictionary with about 2.5 million random words we look up 5 million random words. In-memory Scala Map Simple solution to populate a plain map with two and half million random values. Scala 5.9 seconds to populate the dictionary, 2.4 second to look up the keys. Running time: 2.2 heap is used, 430 after garbage collection. Memory: MB MB this is listed only as a reference point, it has very little value as it’s non-persistent and single threaded solution. Use case: solution This benchmark allows us to see how much memory and processing time is required to generate and store the pure data. In-memory Akka actor A single stateful actor; different messages used to insert and look up values: The benchmark app uses streams to populate and to query the state: Akka 14.3 seconds to populate the dictionary, 18.7 second to look up the keys. Running time: 2.3 heap is used, 420 after garbage collection. Memory: GB MB simple and easy to implement, thread safe Pros: non-persistent, single threaded message processing Cons: for simple cache purposes Use case: Persistent cluster singleton actor , version of the previous in-memory actor, backed with database: Persistent event-sourced Cassandra The benchmark app is almost identical to the in-memory actor version, only difference is how the singleton actor was created: 1665.8 seconds to populate the dictionary, 30.2 seconds to look up the keys. Running time: 800 MB heap is used, 430 MB after garbage collection. Memory: easy to implement, persistent, thread safe, fast lookups Pros: single threaded, can introduce memory bottleneck, slow population time Cons: centralised naming service Use case: Persistent entity actors with cluster sharding for each dictionary entry. The actor can hold an optional value; if the entry doesn’t exist, if it does: Persistent, event-sourced entity actor None Some(X) We need to have the sharding set up, extracting the and from the incoming message: entityId shardId In this version of benchmark app we can populate the map in parallel: 605 seconds to populate the dictionary, 280 second to look up the keys. Running time: 5 GB heap is used, 4.6GB after garbage collection. Memory: persistent, multi threaded, fast population time Pros: slower lookups, higher memory usage, easy to over-engineer Cons: virtually unlimited number of stateful actors with any type of behaviour Use case: Summary It’s worth to highlight how lightweight Akka is; in the last benchmark about five million actors were created and they used 4.6GB memory; that’s less than 1KB per actor. only There’s no silver bullet; always pick the most appropriate approach for solving your problem. References Cluster Sharding Cluster Singleton Thanks for reading, your comments are appreciated. One last thing… If you liked this article, click the💚 below so other people will see it here on Medium. Thank you, Tamas .