When a payment authorisation team misses its sub-100-millisecond latency target, the first investigation usually points at the database. The second points at the cache — specifically, at whether the cache is working. What rarely surfaces until much later is a more fundamental question: where the cache lives relative to the code that uses it, and whether the network separating them is costing more latency than the original database query ever did.
Redis is the default answer to distributed caching, and in most contexts it is the right one. But Redis is an external process. Every read requires a serialisation step on the way out and a deserialisation step on the way back, plus a TCP round trip. At the scale of a risk engine evaluating hundreds of portfolios per minute, or a payment router checking four limit counters per authorisation request, those microseconds accumulate into the tail latency problem that the engineering team presents at the next capacity review.
In-process caching — embedding a data grid like Hazelcast IMDG directly inside the application JVM — eliminates the network hop entirely for locally-owned partitions. The data lives on the JVM heap; reads are heap lookups, not socket calls. The latency improvement on compute-intensive workloads is not marginal. It is the kind of improvement that makes a latency SLA achievable that was previously unreachable with tuning alone.
The decision the VP of Enterprise Integration or Chief Architect has to make is not which technology is faster. It is whether the operational costs of embedding state in application pods are acceptable for the specific workloads on the table.
What the regulator cares about
From SAMA’s Technology Risk Management perspective, a distributed cache — whether Redis or Hazelcast — introduces two categories of concern. The first is data residency: all caches holding customer or transaction data must operate within the Kingdom’s data boundaries. Both Redis and Hazelcast can be deployed on-premises or in a SAMA-approved cloud region; this is a deployment constraint, not a technology constraint.
The second concern is data persistence and recovery. A pure in-memory cache that loses all state on pod restart is acceptable for derived, recomputable data. It is not acceptable for state that is considered authoritative — for example, a settlement window counter that determines whether a payment is allowed to proceed. The architecture decision must be explicit about which Hazelcast maps are cache (lose-able) and which are operational state (must survive restarts). Hazelcast’s persistence options (disk-backed stores in Platform edition, or external persistence via MapLoader) handle the second category, but they must be deliberately configured. The default is volatile in-memory data.
The question to put to your architects before approving an in-process cache: if every application pod restarts simultaneously, which data structures must be repopulated from the database before the first transaction can be processed, and how long does that take?
What the trade-off looks like to the business
The latency case for in-process caching is clear in specific workloads. The costs are less visible and often discovered late.
GC pressure. Embedded Hazelcast data lives on the JVM heap. In a risk engine holding 50,000 limit-matrix entries in a Hazelcast IMap, those objects compete with the application’s working memory for heap allocation. A large young-generation object allocation from a request spike can trigger a full GC pause that affects the cache, the application, and every in-flight request simultaneously. With Redis, the cache has its own process and its own memory; a GC pause in the application does not affect cache availability. This is the cost that surprises teams moving from client-server Hazelcast to embedded Hazelcast in search of lower latency.
Deployment coupling. In embedded topology, the Hazelcast cluster is a peer-to-peer network of all application pod instances. When you scale out the application, you scale out the cache. When you roll deploy with three replicas, a third of the cluster restarts at each step and partition migration runs under traffic. The cache and the application have become a single operational unit. This simplifies some concerns (no separate cache cluster to operate) and complicates others (you cannot scale the cache independently of the application, and a bad deploy that crashes pods also disrupts partition ownership).
Serialisation versioning. A rolling deploy means two versions of the application run simultaneously in the same Hazelcast cluster. If the new version changes the structure of a serialised object stored in IMap, the old version will fail to deserialise values written by the new version — and vice versa. This is a breaking change that conventional application versioning does not protect against. It requires explicit versioning in the Hazelcast serialisation layer (IdentifiedDataSerializable or Portable serialisation with version fields). Teams that do not address this early ship a version and discover the problem when the first pod in the rolling deploy starts failing to read data written by the second pod.
Where Hazelcast wins cleanly. For the subset of workloads where the data is compute-intensive rather than just lookup-intensive — risk calculations that iterate object graphs, payment routers that evaluate limit counters atomically, fraud detection that maintains sliding windows per account — the embedded model is genuinely the right architecture. The engineering investment in serialisation versioning and heap sizing is one-time. The latency benefit is permanent and substantial.
The decision the architecture team needs from leadership
The choice between Redis and embedded Hazelcast cannot be made service by service without a governing principle. Left to individual teams, the result is a fleet of microservices where some use Redis, some use embedded Hazelcast, and the operational model for the caching layer is inconsistent across the estate. The VP’s job is to set the segmentation rule so that teams have a clear decision boundary.
A workable principle: Redis for reference data and session state shared across heterogeneous consumers; Hazelcast embedded for compute-intensive workloads where a single service owns the data and latency matters more than operational simplicity. The payment router’s limit counters are Hazelcast. The API gateway’s rate-limit counters are Redis. The risk engine’s portfolio cache is Hazelcast. The customer session cache shared across the mobile, web, and open-banking APIs is Redis. The segmentation holds because the distinguishing question is always the same: does this data need to be accessed by more than one service, and is the access pattern a lookup or a computation?
Once the principle is set, the infrastructure team needs to deliver two things. First, a Hazelcast configuration baseline for Kubernetes that handles member discovery, graceful shutdown, and partition backup correctly — the defaults are not production-ready. Second, a serialisation versioning standard that every embedded-Hazelcast service follows from day one, not as a retrofit. Neither is complex engineering; both require explicit decision and documentation before the first production service adopts the pattern.
What the team needs from leadership to ship it
The first embedded Hazelcast service at a bank is a platform decision disguised as a service delivery. It establishes the heap sizing convention, the serialisation versioning approach, the Kubernetes RBAC setup for member discovery, the Prometheus alerting rules for partition migration, and the graceful shutdown configuration. All of this must be done correctly on the first service, because it will be inherited by every subsequent service that adopts the pattern.
Leadership needs to fund that first service at two times the effort estimate for the equivalent Redis-backed service. The overhead is front-loaded. The second and third services cost less, because they inherit a working baseline. If the first service is treated as a normal delivery with normal estimates, the team will cut corners on serialisation versioning and graceful shutdown — the two areas where the technical debt is most expensive to retrofit.
The other ask: resist the pressure to benchmark embedded Hazelcast against Redis in a synthetic load test and make the decision based on that. The relevant benchmark is your own highest-latency production workload running against both options with production-representative data sizes and concurrency. Synthetic tests consistently underestimate the GC impact of heap-resident data in embedded mode and overestimate the serialisation overhead of Redis in production-optimised configurations. The right test is real traffic on real data, run for long enough to observe the GC tail latency pattern under sustained load.
For the engineering depth behind this pattern — embedded vs client-server topology, PartitionAware key design, EntryProcessor atomics, near-cache configuration, split-brain merge policy, and Kubernetes RBAC setup — see the companion Lab article: Hazelcast IMDG for In-Process State.