All posts
Developers·· 8 min read

Building a Real-Time Cash Flow API: Architecture Deep Dive (2026)

Batch-and-cache cash-flow analytics are dead. Every modern fintech product — Safe to Spend, overdraft prediction, underwriting — needs sub-50ms answers. Here's the architecture we run in production.

By AtlasForge Engineering

Why batch pipelines aren't good enough anymore

Traditional cash-flow analytics ran overnight. Bank transactions posted during the day, an ETL job ran at 2 AM, and by morning users saw yesterday's insights.

That's no longer good enough. In 2026, products need to answer:

  • Safe to Spend after a $47 lunch: what's my new number?
  • Overdraft prediction: will this transaction push me negative?
  • Underwriting decision: is this user's income stable enough for a loan?

All three require sub-500ms end-to-end latency — from bank event to user-facing answer.

The architecture in one diagram (verbally)

Bank → Aggregator webhook → Kafka topic → Stream processor → Derived cache → API → User

Every layer serves a specific purpose. Let's walk through them.

Layer 1 — Ingestion (webhooks + polling)

Two ingest paths:

Push (webhooks): Plaid, MX, and (increasingly) direct-1033 APIs emit webhooks when new transactions post. Sub-500ms from bank → your infra.

Pull (polling): For banks that don't yet expose webhooks, poll every 60–120 seconds. Higher cost, higher latency, but necessary for tail coverage.

Store raw events unmodified in an immutable append-only store (S3 + Kafka is the standard combo). Never mutate them.

Layer 2 — Stream processing

Kafka topics feed a stream processor. Options in 2026:

  • Kafka Streams — mature, JVM, sharp learning curve
  • Apache Flink — lower-level, most flexible, JVM-heavy
  • Materialize / RisingWave — SQL over streams, easier ramp
  • Bytewax — Python-native

The stream processor does incremental cash-flow math. Given a new $47 debit, it updates:

  • Available balance
  • Upcoming-bills forecast
  • Subscription detection
  • Safe to Spend value
  • Financial health score

All in ~10–30ms per event. No re-reading historical data.

Layer 3 — Derived cache

The output of the stream processor lands in a low-latency store (Redis, DynamoDB with DAX, or Materialize). The API layer never queries the raw transaction store — it only reads the derived cache.

This is the single most important architectural decision: decouple ingestion from query serving. It lets you scale reads independently of writes, and it lets you rebuild derived data (via replay) without downtime.

Layer 4 — API layer

FastAPI (Python), Go, or Node handles user-facing requests. Because the heavy lifting is precomputed in the cache, most endpoints are 5–30ms:

GET /api/v1/users/:id/safe-to-spend
→ Redis lookup: user_id → precomputed value
→ Return {amount: 342.16, currency: "USD", as_of: "2026-02-27T14:02:15Z"}

Total end-to-end latency (bank event → user seeing new number): 60–200ms in the good path.

The nasty parts

1. Ordering. Bank webhooks don't always arrive in transaction-time order. Your stream processor must handle out-of-order events. Idempotent updates + versioned records are non-negotiable.

2. Corrections. Banks post transactions, then post corrections (fee refund, chargeback). Your derived state must handle deletes/updates without corrupting the running total.

3. Reconciliation. Once a day, re-fetch the full account state from the aggregator. Compare to your derived cache. Delta > 1% → alert. This is your safety net.

4. Replay. Every derived data point must be reproducible from the raw event stream. If you find a bug in the stream processor, you replay the last 30 days of events into a fresh cache. This is only possible if raw events are immutable and stored durably.

5. Multi-region. Financial data is regulated. If you serve US and EU customers, you need regional Kafka clusters, regional caches, and no cross-region data leaks. Add complexity accordingly.

The AtlasForge implementation

Our platform exposes the entire pipeline as an API. Partners send us aggregator webhooks; we return normalized Safe to Spend numbers, cash-flow projections, and subscription detections. Median API latency: 42ms. p99: 180ms.

The architecture behind that: multi-region Redis + Materialize, ingestion via Kafka, incremental compute via bytewax pipelines, API layer in FastAPI. See the Developer Docs for API reference and sample code.

Related reading:

Ready to build on AtlasForge?

Get sandbox API keys in 60 seconds — or install the Safe to Spend app.