Writes stay fast. Disk work moves aside.
Mutations update memory first. A background writer coalesces changed keys, serializes the latest state, and forces each batch once.
Embedded Java record store
NitroMap combines fast in-memory access with asynchronous persistence, SQL-like querying, REST, and shared-nothing clustering.
NitroMap<String, String> customers =
NitroMap.strings("data/customers");
customers.put("customer-1", "Ada");
String customer =
customers.get("customer-1");
One small library
NitroMap keeps the common path direct while adding the storage and query capabilities that embedded applications usually have to assemble themselves.
Mutations update memory first. A background writer coalesces changed keys, serializes the latest state, and forces each batch once.
ConcurrentMap on the surface.A composed ConcurrentHashMap keeps reads direct while every supported mutation passes through persistence and index hooks.
Filter, join, group, aggregate, order, and limit records with a focused SQL-like language.
SELECT city, SUM(total)
FROM orders
GROUP BY city
Stable logical partitions route each key to exactly one owner. No replica, quorum, or hidden fallback copy.
Expose one or many named maps using Java's built-in networking, with authorization and filter hooks.
Opt into background eviction, bounded query operators, and disk spill for larger joins, groups, and sorts.
Designed around the hot path
A persistent mutation changes the map, marks the key, and returns. Serialization and file I/O happen on the background writer.
SQL-like querying
Compose multiple joins, nested conditions, parameters, grouping, common aggregates, ordering, and limits in one cached query plan.
SELECT c.city, c.name,
COUNT(*) AS order_count,
SUM(o.total) AS total_sales,
AVG(o.total) AS average_order,
MIN(o.total) AS smallest_order,
MAX(o.total) AS largest_order
FROM customers c
JOIN orders o ON c._key = o.customerId
WHERE (c.city = :primaryCity
OR c.city = :secondaryCity)
AND c.score >= :minimumScore
AND o.total >= :minimumOrder
GROUP BY c.city, c.name
ORDER BY total_sales DESC, average_order DESC
LIMIT 20
Shared-nothing clustering
Stable FNV-1a hashing maps every key to a logical partition and one configured owner. Each node remains an ordinary local NitroMap with its own persistence.
Zero replicationNo quorum, replica, or fallback read.
Bounded distributed SQLStreamed scans, hash shuffles, partial aggregation, and disk spill.
Explicit failureIf an owner is unavailable, its partitions fail instead of returning stale data.
Measured, not imagined
Reference results from the project harness on Apple silicon. They are directional, transparent, and intentionally free of speed assertions.
1 Reference run: macOS on ARM, 10 available processors, Java 25 runtime, compiled for Java 17. Workload, hardware, filesystem, thermals, and contention will change results. Run the bundled benchmark profile on your target system.
Start in one minute
Add NitroMap from Maven Central, choose persistent or memory-only storage, and keep using normal map operations.
<dependency>
<groupId>io.github.kirstenali</groupId>
<artifactId>nitromap</artifactId>
<version>0.3.0</version>
</dependency>
NitroMap<String, String> customers =
NitroMap.strings("data/customers");
customers.put("customer-1", "Ada");
Clear tradeoffs
01Asynchronous by designRecent writes can be lost on hard termination before the next disk batch.
02No hidden availability storyCluster owners hold the only copy. Losing a node loses access to its partitions.
03Focused SQL, not a database disguiseNo transactions, outer joins, subqueries, or cluster-wide snapshots.
Open source · Apache 2.0
Fast local state, practical persistence, and query power in one compact Java library.