akanjilal.dev
Back to reference architectures
Reference architectureEvent driven coreca-central-1 and ca-west-1

Resilient transaction processing core

A transaction core has one essential responsibility. It must apply each transaction exactly once, never lose one, and never leave money half moved, even when a component fails or a whole region becomes unavailable. This reference architecture is an idempotent, event driven backbone for high value transactions, built across two Canadian regions, coordinated with the saga pattern, recorded in an append only ledger, and designed deliberately against all six pillars of the AWS Well Architected Framework.

The difficult part of a transaction system is not the normal path but the failure cases: a caller that retries because it did not hear back, a step that succeeds while the next one fails, a queue that backs up under load, or a primary region that becomes unreachable during peak traffic. The design here treats every one of those as a normal event rather than an exception, because in a system that runs at scale they are normal. Two ideas carry most of the weight. Every operation is idempotent, so doing it twice is the same as doing it once, and every multi step transaction is a saga, so a failure partway through unwinds cleanly.

Requirements

The requirements the core has to satisfy, the quality attributes it is judged on, the constraints it must respect, and the assumptions it rests on. The quality attributes are deliberately the six pillars of the Well Architected Framework, because this is a workload where all six matter.

Functional requirements

NumberRequirement
1Accept a high rate of transactions and never lose one once accepted.
2Apply each transaction exactly once, even when a caller retries.
3Coordinate multi step transactions so that a partial failure never leaves money half moved.
4Keep a durable, ordered, and auditable record of every transaction.
5Publish events so that downstream systems react without being coupled to the core.
6Continue processing through the loss of an availability zone with no action.
7Recover from the loss of a region within the recovery objective.

Quality attributes, the six pillars

PillarIntent
Operational excellenceEverything defined as code, with traceability of every transaction through the system.
SecurityAuthenticated entry, least privilege, encryption everywhere, inside the landing zone production segment.
ReliabilityTolerate a zone loss with no action, and a region loss within the recovery objective, with no double processing.
Performance efficiencyAbsorb spikes through queues and scale the processors to demand.
Cost optimizationPay for work done rather than for idle capacity, with a warm rather than a full standby.
SustainabilityServerless and managed components scaled to actual load rather than provisioned for peak.

Constraints and assumptions

NumberConstraint
1Data residency in Canada and the two approved regions.
2The core sits inside the landing zone production segment and inherits its controls.
3Every transaction must be traceable end to end and retained for audit.
4Recovery point objective near zero, and recovery time objective in minutes.
NumberAssumption
1Callers are authenticated services rather than anonymous clients.
2Downstream consumers can react to events asynchronously.
3The ledger is the system of record for anything of value.

Architecture decisions and rationale

The decisions that shaped the core, each with the alternative that was set aside and the cost that was accepted.

1. Event driven rather than a synchronous chain of calls

Decision. Accept a transaction quickly, place the work on a durable queue, and process it asynchronously, with components communicating through events.

Alternatives. A synchronous chain in which the caller waits while each downstream system is called in turn.

Rationale. A synchronous chain is only as available as its least available link and falls over under load, where a queue absorbs spikes, decouples the parts, and lets each scale and fail independently. This serves functional requirements 1 and 5 and the performance and reliability pillars.

Consequences. The system is eventually consistent for downstream effects, which is handled by emitting clear events and designing consumers to expect them.

2. Idempotency keys rather than hoping callers do not retry

Decision. Give every transaction an idempotency key recorded in DynamoDB, and make every operation safe to repeat under that key.

Alternatives. Assuming each request arrives exactly once.

Rationale. At scale, retries are inevitable, from clients, from networks, and from the platform itself, so the only safe assumption is that any request may arrive more than once, and the idempotency key makes a repeat harmless. This serves functional requirement 2 and the reliability pillar.

Consequences. Every operation must check and record the key, which is a small and consistent overhead.

3. The saga pattern rather than a distributed transaction

Decision. Coordinate multi step transactions with AWS Step Functions as an explicit saga, where each step has a compensating action.

Alternatives. A distributed transaction that tries to lock every system and commit them together.

Rationale. A lock held across independent services does not scale and creates new failure modes, where a saga makes the steps and their compensations explicit and lets a late failure unwind the earlier steps cleanly. This serves functional requirement 3.

Consequences. Each step needs a compensation written for it, which is the deliberate cost of doing this correctly.

4. An append only ledger as the system of record rather than mutable rows

Decision. Record every movement in an append only ledger in Amazon Aurora, and archive an immutable copy to object storage.

Alternatives. Updating balances in place and trusting the latest value.

Rationale. An append only record can always be replayed and audited, where a mutable balance loses the history that a regulated system has to be able to reconstruct. This serves functional requirement 4 and the operational excellence pillar.

Consequences. The ledger grows and is summarized for fast reads, which is a normal and well understood pattern.

5. Domain events for downstream rather than direct integration

Decision. Publish domain events to Amazon EventBridge for downstream systems to consume.

Alternatives. Calling each downstream system directly from the core.

Rationale. Direct calls couple the core to every consumer and make it fragile, where an event bus lets consumers come and go without the core knowing or caring. This serves functional requirement 5 and the operational excellence pillar.

Consequences. Consumers must handle events that may arrive more than once, which the idempotency discipline already assumes.

6. Multi region active and warm standby rather than a single region

Decision. Replicate idempotency keys through DynamoDB global tables and the ledger through Aurora Global Database, with a warm standby promoted on failover.

Alternatives. A single region, or a pair fully active in both regions.

Rationale. A single region cannot meet the recovery objective, and a fully active pair would have to resolve conflicting writes to the ledger, which is more risk than this objective needs, so the standby is warm and is promoted deliberately. This serves functional requirement 7 and the reliability and cost pillars.

Consequences. A failover is a rehearsed action that takes minutes, and because idempotency keys replicate, a request retried after a failover is still recognized and never applied twice.

The core

A transaction enters through an authenticated entry behind the web application firewall, is made idempotent immediately, and is placed on a durable queue. From there the processors pick it up, the saga coordinates the steps, the ledger records the movements, and an event is published for anyone downstream who needs to know. Each box in the picture can scale and fail on its own, which is the point of separating them.

An event driven transaction core with idempotency, a queue, processors, a Step Functions saga, an Aurora ledger, and EventBridge events
The event driven core. Accept and make idempotent, queue, process, coordinate the saga, record in the ledger, and publish events.

The layers, end to end

It helps to walk the core one layer at a time, because each has a single job and a clear contract with the layers on either side of it. A transaction touches all of them in order on the way in, and the resilience of the whole comes from each layer being able to scale, retry, and fail on its own.

LayerResponsibilityBuilt with
Edge and entryTerminate the connection, filter hostile traffic, authenticate the caller, and apply a first rate limit before anything reaches the core.Amazon CloudFront, AWS WAF, an authenticated API behind a private load balancer
Ingestion and idempotencyValidate the request, claim its idempotency key, and either accept it once or return the result of the accepted original. Nothing past this layer runs twice for the same key.A thin ingestion function and a DynamoDB idempotency table with a conditional write
Durable bufferHold accepted work safely so that a spike or a slow downstream never drops a transaction, and so the processors scale independently of the arrival rate.Amazon SQS, with a dead letter queue for anything that cannot be processed after retries
Processing and orchestrationPull work from the buffer, run the saga that moves the money, and decide success, retry, or compensation for each step.Amazon EKS with Fargate workers driving an AWS Step Functions saga
System of recordAppend every movement to an ordered, immutable ledger and keep a summarized balance for fast reads. This layer is the truth.Amazon Aurora for the ledger, with an immutable archive in Amazon S3 under Object Lock
EventingPublish a domain event for every committed transaction so that downstream systems react without being wired into the core.Amazon EventBridge, with one bus and well defined event schemas
ObservabilityTrace any single transaction through every layer by its identifier, and alarm on what matters before a human notices.AWS X-Ray traces, structured logs, and CloudWatch metrics and alarms

How the services talk to each other

The most important boundary in the core is the line between synchronous and asynchronous communication, and it is drawn deliberately. The caller talks to the core synchronously for exactly one thing, which is to have its transaction accepted and made idempotent. That call is fast and does almost no work, so it stays available under load. Everything after acceptance is asynchronous, because the moment work is on a durable queue it cannot be lost, and the parts that do the real work scale and fail without the caller ever waiting on them.

Inside the core, two communication styles do different jobs. A command, which is an instruction to do one specific thing such as debit this payer, travels on a queue to exactly one processor, so that it is handled once and can be retried safely if the processor dies mid step. An event, which is a statement that something has already happened such as this transaction settled, is published to the bus, where any number of consumers may read it, now or later, without the core knowing they exist. Commands are point to point and express an intended action, while events are broadcast and record something that has already happened.

Three rules keep that communication reliable. First, every message carries the transaction identifier and the idempotency key, so a redelivery, which a durable queue will eventually cause, is recognized and ignored rather than acted on twice. Second, failures retry with exponential backoff a bounded number of times, and anything that still fails lands in a dead letter queue for inspection rather than blocking the line behind it or being silently dropped. Third, where the order of operations matters, the queue is configured for strict ordering on the transaction identifier, so the steps of one transaction never overtake each other while unrelated transactions still run in parallel. The result is a system that absorbs a surge by letting the queue grow, drains it as the processors scale out, and never confuses backpressure with data loss.

The wider system, and the services the core depends on

The core does one thing well and delegates everything else, so in practice it sits at the centre of a small constellation of services rather than standing alone. Before a transaction posts, it consults a few decision services and treats their answers as part of the contract. After a transaction commits, it informs a wider set that react on their own time. Naming these and being explicit about which calls block matters, because every synchronous dependency is part of the acceptance latency budget and part of the failure surface.

ServiceResponsibilityInteraction
Risk DecisionScores the transaction for fraud and returns allow, deny, or step up.Synchronous, hard deadline, fails closed
ScreeningChecks the payer and payee against sanctions and watchlists.Synchronous, hard deadline, fails closed
LimitsEnforces per account and per window value and velocity limits.Synchronous, backed by an in memory store
Account DirectoryResolves account status, ownership, and eligibility.Synchronous, cached
NotificationTells the customer the outcome.Asynchronous, on a domain event
Reconciliation and SettlementNets and settles to the scheme and reconciles the ledger against the scheme statement.Asynchronous
Analytics sinkLands every event for reporting and modeling.Asynchronous
Scheme ConnectorCarries the outbound instruction to the external network and ingests its responses.Asynchronous, isolated

The four synchronous services share the acceptance budget, so the core calls them in parallel rather than in sequence, gives each its own short timeout, and treats a missed answer exactly as it treats a deny. In a payments system a risk service that does not answer in time is not a reason to take the risk, so the default on a timeout is to refuse the transaction cleanly with a reason the caller can act on. These services are usually owned by other teams and run in their own accounts inside the landing zone, reached over private connectivity, so the core depends on their published contracts and never on their internals.

The saga and idempotency

The saga is an explicit state machine. Funds are reserved, the payer is debited, the payee is credited, and the result is confirmed and emitted, and every step has a compensating action so that a failure late in the sequence reverses the earlier steps rather than leaving the transaction half done. Because each step is idempotent and keyed on the transaction identifier, a retry repeats the intent without repeating the effect.

A saga of reserve, debit, credit, and confirm, each with a compensating action that reverses it on a later failure
The saga. Each forward step has a compensation, so a late failure unwinds cleanly rather than leaving money half moved.

Expressed as a state machine, each step catches its own failure and routes to the compensation for the steps that already succeeded.

{
  "Comment": "Transaction saga with compensations",
  "StartAt": "ReserveFunds",
  "States": {
    "ReserveFunds": {
      "Type": "Task", "Resource": "arn:aws:states:::lambda:invoke",
      "Parameters": { "FunctionName": "reserve-funds", "Payload.$": "$" },
      "Catch": [ { "ErrorEquals": ["States.ALL"], "Next": "Fail" } ],
      "Next": "DebitPayer"
    },
    "DebitPayer": {
      "Type": "Task", "Resource": "arn:aws:states:::lambda:invoke",
      "Parameters": { "FunctionName": "debit-payer", "Payload.$": "$" },
      "Catch": [ { "ErrorEquals": ["States.ALL"], "Next": "ReleaseHold" } ],
      "Next": "CreditPayee"
    },
    "CreditPayee": {
      "Type": "Task", "Resource": "arn:aws:states:::lambda:invoke",
      "Parameters": { "FunctionName": "credit-payee", "Payload.$": "$" },
      "Catch": [ { "ErrorEquals": ["States.ALL"], "Next": "ReverseDebit" } ],
      "Next": "Confirm"
    },
    "Confirm":      { "Type": "Task", "Resource": "arn:aws:states:::events:putEvents", "End": true },
    "ReverseDebit": { "Type": "Task", "Resource": "arn:aws:states:::lambda:invoke", "Next": "ReleaseHold" },
    "ReleaseHold":  { "Type": "Task", "Resource": "arn:aws:states:::lambda:invoke", "Next": "Fail" },
    "Fail":         { "Type": "Fail" }
  }
}

Idempotency is enforced at the only place it can be, which is the first write. Before any work begins, the ingestion layer attempts to claim the transaction with a conditional write keyed on the idempotency key. If the claim succeeds, this is the first time the request has been seen and processing proceeds. If the claim fails because the key already exists, the request is a retry, and the core returns the stored result of the original rather than doing the work again. The whole guarantee rests on this one atomic operation.

# claim the transaction exactly once; a retry hits the condition and is rejected
table.put_item(
    Item={"pk": idempotency_key, "status": "ACCEPTED", "result": None,
          "ttl": now + RETENTION_SECONDS},
    ConditionExpression="attribute_not_exists(pk)",
)
# ConditionalCheckFailedException  means already seen:
#   read the stored record and return its result, do not reprocess

Across two regions

The core runs in two regions. Idempotency keys replicate through DynamoDB global tables, the ledger replicates through Aurora Global Database with a recovery point objective near zero, and Amazon Route 53 with the Application Recovery Controller directs traffic and supports a controlled failover. The combination of replicated keys and a replicated ledger is what makes the failover safe. A request that was in flight when the primary region failed can be retried against the standby and will be recognized as already seen, so it is never applied a second time.

RESILIENT TRANSACTIONS · MULTI REGION Idempotency and the ledger survive a region loss Amazon Route 53 · Application Recovery Controller controlled regional failover Region ca-central-1 (active) Region ca-west-1 (standby) API and processing active and ready DynamoDB global tables idempotency keys, replicated Aurora Global Database ledger, sub second replication EventBridge event bus, regional Processes transactions. API and processing active and ready DynamoDB global tables idempotency keys, replicated Aurora Global Database ledger, sub second replication EventBridge event bus, regional Warm standby, promoted on failover. global tables Aurora Global Networking Compute Database Integration akanjilal.dev
Multi region. Idempotency keys and the ledger both replicate, so a failover neither loses a transaction nor processes one twice.

How the data replicates, and why nothing is lost

Zero data loss is a property of the data layer, so it is worth being precise about how each piece of state crosses the region boundary and what guarantee that gives. There are three kinds of state, and each replicates in the way that suits it.

The idempotency keys live in a DynamoDB global table, which replicates every write to the second region within a second or two, in both directions. This is the piece that makes a failover safe rather than dangerous. A transaction accepted in the primary region just before it failed has already had its key replicated, so when the caller retries against the standby, the conditional claim fails exactly as it would have in the primary, and the transaction is recognized as already seen rather than applied a second time.

The ledger, which is the system of record, lives in an Amazon Aurora Global Database. Aurora replicates at the storage layer, typically with under a second of lag and a recovery point objective measured in single digit seconds, and a healthy secondary can be promoted to a full read and write primary in about a minute. Writes go to one region at a time, which avoids the risk of two regions disagreeing about a balance, and the standby is kept warm and current rather than cold. For the strongest durability the immutable archive of the ledger is written to Amazon S3 under Object Lock and replicated across regions, so even the catastrophic loss of a database leaves an independent, tamper proof copy of every movement.

Traffic is steered by Amazon Route 53 with the Application Recovery Controller, whose routing controls turn a failover into a deliberate, rehearsed switch rather than a guess made under pressure. A regional failover then follows a short, practiced runbook.

  1. Confirm the primary is genuinely unhealthy and stop new work from entering it.
  2. Promote the Aurora secondary in the standby region to primary.
  3. Flip the Route 53 routing control so the entry points resolve to the standby.
  4. Let the standby processors drain the replicated queue. The idempotency keys are already present, so any in flight retries settle exactly once.
  5. Confirm the ledger and the idempotency table agree, then bring the original region back up as the new standby.

Because the keys and the ledger both crossed the boundary before any failure, the two outcomes that matter most are both closed off. A transaction in flight is never lost, because it was either not yet accepted, in which case the caller retries cleanly, or already accepted and replicated, in which case the standby recognizes it. And a transaction is never applied twice, because the replicated idempotency key rejects the duplicate on whichever region serves the retry. That is what zero data loss means here in practice, stated as two failure modes that cannot occur rather than as a headline figure.

The deployment architecture

Everything above describes behavior. This is where it physically lives. Each region is a single Virtual Private Cloud spread across three availability zones and divided into four subnet tiers, attached to the rest of the organization through AWS Cloud WAN, and able to reach the external payment scheme only from an isolated connector. The second region is the same definition with the region as a parameter, not a hand built copy.

Deployment view, one region (the second region is identical) Authenticated callers, via AWS Cloud WAN Region Virtual Private Cloud, three availability zones Ingress subnets, private Ingress Gateway authenticate, rate limit, claim the idempotency key Application subnets, private. Amazon EKS with Fargate behind a mutual authentication mesh Saga Orchestrator Posting Engine Event Publisher Worker fleet AWS Step Functions drives the saga. Workers drain the Work Queue, on Amazon SQS, and scale on its depth. Data subnets, private, no route to the internet Idempotency Store Ledger Balance Cache Signing DynamoDB global table, Aurora Global Database, ElastiCache, AWS CloudHSM. Reached through interface endpoints. Egress and inspection subnets Scheme Connector, isolated outbound only, signs messages with AWS CloudHSM External payment scheme and partner banks via AWS PrivateLink, with a Direct Connect fallback
One region. Four private subnet tiers inside the Virtual Private Cloud, the core services on Amazon EKS with Fargate behind a mutually authenticated mesh, and the only path to the external scheme through an isolated connector. The second region is identical. The decision services live in adjacent accounts reached over AWS Cloud WAN.

The subnet tiers separate concerns so that a fault or a compromise in one does not become a fault in another.

TierWhat runs thereReachability
IngressThe Ingress Gateway and an internal load balancer.Reachable only from the organization network over AWS Cloud WAN, never from the public internet.
ApplicationThe core domain services on Amazon EKS with Fargate, behind a mesh that mutually authenticates every service to service call.East to west traffic only, inside the mesh.
DataThe ledger, the idempotency store, the balance cache, the signing cluster, and the interface endpoints for the regional services.No route to the public internet at all.
Egress and inspectionThe isolated Scheme Connector and centralized outbound inspection.The only tier permitted to reach outside the Virtual Private Cloud, and only to the scheme.

Each named component has a clear home and a clear runtime.

ComponentTierRuns on
Ingress GatewayIngressAmazon EKS with Fargate, behind an internal load balancer
Saga OrchestratorApplicationAWS Step Functions, driven by Amazon EKS workers
Posting EngineApplicationAmazon EKS with Fargate
Event PublisherApplicationAmazon EKS with Fargate, writing to Amazon EventBridge
Work QueueApplicationAmazon SQS, reached through an interface endpoint
Idempotency StoreDataAmazon DynamoDB global table
LedgerDataAmazon Aurora Global Database
Balance CacheDataAmazon ElastiCache, fronting the Aurora read replicas
SigningDataAWS CloudHSM
Scheme ConnectorEgress and inspectionAmazon EKS with Fargate, AWS PrivateLink to the scheme with a Direct Connect fallback

The tiers say where things sit. The next view says how they talk, component by component, and what travels on each link.

Components and data flow, one region Authenticated caller Ingress Gatewayvalidate, authenticate, rate limit Work QueueAmazon SQS, ordered, dead letter Worker and Saga OrchestratorAWS Step Functions, compensations Posting Engine Event Publisher Event busAmazon EventBridge request enqueue accepted work poll, in transaction id order reserve, debit, credit on commit settled event Decision services, parallelRisk, Screening, Limits, Account Directory Idempotency StoreAmazon DynamoDB global table LedgerAmazon Aurora Global Database Balance CacheAmazon ElastiCache Event consumersNotification, Reconciliation, Analytics Scheme Connector, isolatedsigns with AWS CloudHSM External payment scheme synchronous fan out claim key, conditional write append, system of record update projection fan out outbound instruction AWS PrivateLink
A closer view of the components and what flows between them. The synchronous path, from the caller through acceptance, is deliberately short. Everything after the Work Queue is asynchronous. The Idempotency Store and the Ledger both replicate to the second region, which is what makes the failover safe.

One transaction, end to end

  1. An authenticated caller reaches the Ingress Gateway over AWS Cloud WAN. The gateway validates the request and asks the Idempotency Store to claim it with a conditional write. A duplicate stops here and returns the stored result of the original.
  2. The gateway calls the Risk Decision, Screening, Limits, and Account Directory services in parallel, each with a short deadline. Any deny, and any timeout, ends the transaction with a clear reason. This is the only synchronous fan out, and it is what the acceptance latency is spent on.
  3. On a clean decision the gateway places the work on the Work Queue and returns accepted to the caller. The acceptance path is complete, well inside the objective of a 99th percentile under 250 milliseconds.
  4. A worker in the application tier starts the Saga Orchestrator, which reserves funds, debits the payer, and credits the payee through the Posting Engine, each step idempotent and each with a compensation.
  5. The Posting Engine appends every movement to the Ledger and updates the Balance Cache for fast reads. The ledger is the system of record.
  6. The Event Publisher emits a settled event. The Notification, Reconciliation, and Analytics services react on their own time, and the Scheme Connector carries the instruction outward over the isolated path, signing it inside the hardware security module.

Scale, delivery, and key custody

The worker fleet scales on the depth of the Work Queue rather than on a fixed size, which lets the core hold a sustained rate of about 2,000 transactions per second and absorb peaks near 8,000 by letting the queue grow and draining it as workers scale out. Capacity follows demand rather than being provisioned for a peak that rarely arrives.

The whole core is defined in AWS Cloud Development Kit stacks and delivered through a pipeline that runs the tests, deploys to the standby region first, runs a synthetic transaction from end to end, and only then promotes the primary, with a blue green cutover so that a bad release is reversed in seconds rather than recovered from over hours. The core sits in the production segment of the landing zone described elsewhere in these architectures and inherits its account isolation, its centralized inspection, and its guardrails.

Operations that move money are signed inside AWS CloudHSM, so the keys that authorize a movement never leave the hardware security module. Every store is encrypted at rest, every call between services is mutually authenticated inside the mesh, and the components that touch payment data sit inside a clearly drawn compliance boundary, which keeps the scope of the relevant standard small and auditable. Every component runs with the least privilege it needs and nothing more.

The full build sheet

The view below is deliberately literal. It names every network boundary, the address ranges, the security groups, the subnets, the compute namespaces, the data stores, and the managed services, so that someone could take it and stand the environment up. One region is shown. The second region is identical for production, with the address range moved from 10.20.0.0/16 to 10.21.0.0/16. The decision services named earlier sit in their own accounts and are reached over AWS Cloud WAN, so they are not redrawn here.

Full component architecture, one region: ca-central-1 The second region, ca-west-1, is identical for production. Replace 10.20.0.0/16 with 10.21.0.0/16. Amazon Route 53 public and private hosted zones, DNS health checks, Application Recovery Controller AWS Cloud WAN core network, VPC attachment 10.20.0.0/16 reaches callers and the decision accounts AWS Direct Connect and VPN private path to the payment scheme carries the PrivateLink and the backup route Production VPC, 10.20.0.0/16, availability zones ca-central-1 a, b, c Ingress tier security group sg-ingress, network ACL nacl-ingress. Subnets 10.20.0.0/20 (a), 10.20.16.0/20 (b), 10.20.32.0/20 (c). Not internet facing. AWS WAFmanaged and custom rule groups Application Load Balancer (internal)connection termination, health checks Reachable only over Cloud WANauthenticated service callers Application tier security group sg-app. Subnets 10.20.64.0/20 (a), 10.20.80.0/20 (b), 10.20.96.0/20 (c). Amazon EKS, Fargate profiles across the three app subnets, App Mesh with mutual TLS namespace: ingressIngress Gateway pods namespace: coreSaga workers, Posting Engine,Event Publisher namespace: connectorsscheme client sidecars namespace: platformmesh control plane, log and trace agents Amazon ECS (Fargate)reconciliation and netting batch service AWS Lambdaevent glue and scheduled tasks AWS Step Functionstransaction saga state machine Data tier security group sg-data, no route to the internet. Subnets 10.20.128.0/20 (a), 10.20.144.0/20 (b), 10.20.160.0/20 (c). Amazon AuroraGlobal Database, the Ledgerwriter and two readers per AZ Amazon ElastiCacheRedis, the Balance Cachereplicas across AZs Amazon MSK (Kafka)three brokers, one per AZevent stream to analytics AWS CloudHSMsigning clusterhigh availability across AZs Interface endpoints (PrivateLink)SQS, EventBridge, ECR, KMS, Secrets Manager, STS, CloudWatch, Step Functions Gateway endpointsAmazon S3 and Amazon DynamoDB, via route tables Regional and account services AWS managed, not in a subnet, reached only through the endpoints above Amazon DynamoDBglobal table, Idempotency Store Amazon S3ledger archive, Object Lock Amazon SQSWork Queue and dead letter Amazon EventBridgedomain event bus Amazon ECRsigned container images per service AWS KMScustomer managed keys, envelope encryption AWS Secrets Managerservice credentials, rotation Egress and inspection tier security group sg-egress. Subnets 10.20.192.0/20 (a), 10.20.208.0/20 (b), 10.20.224.0/20 (c). AWS Network Firewallegress inspection and filtering NAT gatewaysone per AZ, controlled outbound Scheme Connector (isolated)dedicated Fargate profile, signs via CloudHSM to the external scheme over PrivateLink, Direct Connect fallback External payment scheme and partner banks
A build ready view of one region. Every Virtual Private Cloud boundary, address range, security group, subnet, namespace, data store, and managed service is named. The second region is identical, with 10.20.0.0/16 replaced by 10.21.0.0/16.

A few components on the sheet did not need naming in the narrative above. Amazon ECR holds the signed container images for every service. Amazon MSK carries the high volume event stream that the analytics and reconciliation consumers read, while Amazon EventBridge routes the lower volume domain events. Amazon ECS runs the scheduled reconciliation and netting job, which suits a batch runtime better than the always on services on Amazon EKS.

The six pillars, made concrete

Because this workload is judged on all six pillars of the Well Architected Framework, it is worth stating exactly how each one is met rather than claiming it in passing.

  • Operational excellence. The whole core is defined in infrastructure as code and delivered through the standby first, blue green pipeline, so a change is rehearsed in the second region before it touches the first. A single transaction identifier threads through the Ingress Gateway, the Work Queue, the saga, the Ledger, and the events, so any one transaction can be traced from end to end, and the same identifier keys the metrics and alarms that page a human before a customer notices.
  • Security. Entry is authenticated and rate limited at the Ingress Gateway, every call between services inside the mesh is mutually authenticated, and the data subnets have no route to the public internet. The keys that authorize a movement never leave AWS CloudHSM, every store is encrypted at rest, and the core inherits the account isolation and centralized inspection of the landing zone production segment. The only way out is the isolated Scheme Connector over AWS PrivateLink.
  • Reliability. Every component runs across three availability zones, so the loss of one is handled with no action. Idempotency makes every retry safe, the saga prevents a half moved transaction, and the rehearsed regional failover, backed by replicated idempotency keys and a replicated ledger, recovers from the loss of a whole region within minutes and without double processing.
  • Performance efficiency. The synchronous path does almost nothing, so acceptance stays inside the 99th percentile target of 250 milliseconds even under load. The Work Queue absorbs a surge while the worker fleet scales on its depth, and the Balance Cache keeps hot reads off the ledger, which together hold a sustained rate of about 2,000 transactions per second and absorb peaks near 8,000.
  • Cost optimization. Compute runs on Amazon EKS with Fargate and AWS Lambda and follows demand rather than a provisioned peak, so the bill tracks real work. The second region is kept warm rather than fully scaled, which meets the recovery objective at a fraction of the cost of a pair that is fully active in both regions.
  • Sustainability. The same elasticity is the sustainability story. Capacity scaled to actual load draws less power than capacity provisioned for a peak that rarely arrives, and the managed and serverless components share their underlying hardware across many tenants rather than sitting idle.

This core is the kind of backbone that the other reference architectures publish their events to and rely on for anything that moves value.

References

  1. Amazon Web Services, the Well Architected Framework.https://aws.amazon.com/architecture/well-architected/
  2. Amazon Web Services, the saga pattern.https://docs.aws.amazon.com/prescriptive-guidance/latest/cloud-design-patterns/saga.html
  3. Amazon Web Services, the idempotency pattern.https://docs.aws.amazon.com/prescriptive-guidance/latest/cloud-design-patterns/idempotency.html
  4. Amazon Web Services, AWS Step Functions.https://docs.aws.amazon.com/step-functions/latest/dg/welcome.html
  5. Amazon Web Services, Amazon DynamoDB global tables.https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GlobalTables.html
  6. Amazon Web Services, Amazon Aurora Global Database.https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-global-database.html
  7. Amazon Web Services, Amazon EventBridge.https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is.html
  8. Amazon Web Services, Amazon Elastic Kubernetes Service with Fargate.https://docs.aws.amazon.com/eks/latest/userguide/fargate.html
  9. Amazon Web Services, AWS Cloud WAN.https://docs.aws.amazon.com/network-manager/latest/cloudwan/what-is-cloudwan.html
  10. Amazon Web Services, AWS PrivateLink.https://docs.aws.amazon.com/vpc/latest/privatelink/what-is-privatelink.html
  11. Amazon Web Services, AWS CloudHSM.https://docs.aws.amazon.com/cloudhsm/latest/userguide/introduction.html
  12. Amazon Web Services, Amazon ElastiCache.https://docs.aws.amazon.com/AmazonElastiCache/latest/dg/WhatIs.html