The Context: "The 3 AM Trigger"
It was March 2024. Our hedge-fund client, "QuantumTrade" (name changed), engaged us to audit their algorithmic trading engine. They were running a typical microservice layout: Java Spring Boot apps communicating with a managed Redis cluster over the network. Every time a new market tick arrived, the trading engine fetched the current portfolio state from Redis, ran an algorithm, and updated the state. It worked brilliantly in backtesting. But at 3 AM during a volatile session in the Asian markets, the network latency between the AWS EC2 instances and the ElastiCache Redis cluster jittered from 0.5ms to 2.5ms. Because the algorithm required 4 sequential fetches to execute one trade, a single trade took 10ms. In high-frequency trading, 10ms is an eternity. We missed 3,000 profitable arbitrage opportunities in two minutes because we were waiting on TCP network packets. Total baigan topology. We had to completely eliminate the network from the read path.
The Problem Statement
Our constraints for the trading architecture:
- Latency: Reading portfolio state must take < 50 microseconds (0.05ms).
- Consistency: The state must be globally synchronized across 40 trading JVMs within 1ms.
- Topology: Eliminate all external network hops to a database or cache for read-heavy algorithms.
- Resilience: A JVM crash must not result in data loss.
Visual Architecture
The Core Logic / Process
Data Flow
We ripped out the external Redis cluster entirely. Instead, we embedded Hazelcast directly inside the existing Spring Boot JVMs. This transformed our architecture from a Client-Server topology into an In-Memory Data Grid (IMDG). When JVM 1 boots up, it automatically discovers JVM 2 via Kubernetes headless services, and they form a peer-to-peer cluster.
The portfolio data isn't stored "elsewhere"; it is stored directly on the heap (and off-heap) of the application themselves. When the algorithmic thread needs to read the portfolio state, it executes a get() against the local Hazelcast ConcurrentMap. Because the data structurally lives inside the same exact OS process, there is zero network I/O, zero serialization overhead, and the read latency drops to roughly 20 microseconds.
Concurrency & Locking
To avoid locks, we used Hazelcast's EntryProcessor. If multiple JVMs receive a market tick that warrants updating the exact same portfolio element, they do not pull the object out, mutate it, and put it back.
Instead, the JVM sends an EntryProcessor (a small compiled lambda function) over the network to the specific JVM that owns the primary partition for that data. The partition owner executes the lambda locally, updating the data in-place atomically. This guarantees strict thread-safety without ever executing a distributed lock.
Failure Modes
What happens if JVM 1 crashes? Hazelcast dynamically partitions the data across the grid. Every piece of data has a primary owner (e.g., JVM 1) and a backup owner (e.g., JVM 2). If JVM 1 suffers a catastrophic JVM kill, JVM 2 instantly promotes its backup partitions to primary. The grid rebalances itself seamlessly. We paired this with Hazelcast's asynchronous Write-Behind pattern (MapStore) to persist the finalized state back to Oracle eventually, preserving safety while maximizing speed.
The "Baigan" Take (Expert Insights)
Look, embedded data grids sound like the holy grail until you encounter the Java Garbage Collector.
If you store 10GB of portfolio data directly on the JVM heap of your Spring Boot app, G1GC will eventually trigger a Full GC pause trying to scan millions of tiny object references. A 400ms GC pause in a trading engine is a death sentence.
The baigan trick to making Hazelcast embedded nodes work at massive scale is enabling High-Density Memory Store (Off-Heap memory). We allocated 2GB of standard Heap for the Spring Boot logic, and 16GB of Off-Heap memory for Hazelcast via Unsafe native memory allocation. Hazelcast manages this chunk of RAM completely outside the view of the Java Garbage Collector. We got the lightning-fast 20-microsecond access speeds of in-memory data, but completely bypassed GC pauses.
Performance Checklist
- Use Embedded Hazelcast topology to eliminate network I/O for aggressive read-heavy workloads.
- Use Hazelcast
EntryProcessorfor atomic, lock-free distributed updates. - Configure Off-Heap memory using Hazelcast High-Density Memory Store to avoid catastrophic GC pauses.
- Use a
MapStorewith Write-Behind configured to persist state to Oracle asynchronously.