Last updated: July 31, 2026
By Kris Drouet, Engineering Executive, in partnership with KORE1
Mortgage tech API architecture survives volume spikes when four patterns hold: asynchronous intake, per-vendor bulkheads, a separated read path, and replayable writes with deliberate load shedding. Rate moves are not gradual. Volume arrives in days, not quarters, and the parts of your stack you do not control are usually the parts that fail first.
In the week ending September 12, 2025, the average 30-year fixed rate on conforming balances fell ten basis points. From 6.49 percent to 6.39 percent. Ten.
The Mortgage Bankers Association’s Weekly Applications Survey put the refinance index up 58 percent from the prior week. Refinance share of total applications went from 48.8 percent to 59.8 percent in seven days. That is not a growth curve. That is a step function, triggered by a number nobody at your company controls, on a day nobody at your company picked.
I have spent 25 years building software in regulated industries, most of it in mortgage tech, and I have been on call for several of those step functions. The first one surprised me. The systems that fell over were not the ones with the most traffic. They were the ones where a single synchronous call to somebody else’s API sat on the critical path of something a borrower was waiting on. Traffic was never really the problem. Coupling to a dependency with its own capacity limits was the problem, and volume just made it visible.
This piece is the load-side companion to my integration decoupling playbook. That one covers how to untangle a coupled topology in general. This one is narrower, and I think more urgent for anyone running a lending platform right now. Four architectural patterns that actually hold when volume triples in a week, and what each one costs you.

What Mortgage Tech API Architecture Actually Has to Survive
Mortgage tech API architecture is the set of integration boundaries between your loan origination system, your third-party vendor APIs, and your borrower-facing applications. It is judged almost entirely on how it behaves when demand moves faster than your capacity planning cycle. Steady state is easy. Everything is designed for steady state.
Look at what a single loan actually touches. Credit through a reseller like Xactus or CoreLogic Credco. Automated underwriting through Desktop Underwriter or Loan Product Advisor. Pricing through Optimal Blue or the ICE Product and Pricing Engine. Verification of income and employment. Flood, title, appraisal, e-sign, disclosure delivery, MERS registration. Then the loan origination system itself, which for a large share of the industry means Encompass. Twenty-plus integration points, and you own maybe two of them.
That ratio is the whole story. Your architecture is mostly a plan for other people’s systems.
Pattern 1: Accept Fast, Process Behind It
The first pattern is the one that pays for itself fastest, and it is also the one teams skip because it feels like extra machinery for a problem they do not have yet.
When a borrower submits an application, or a loan officer requests a rate lock, or fifty documents hit an upload endpoint at once, the request should do two things and stop. Validate enough to know it is real. Write it somewhere durable. Then return.
Everything after that runs behind the acknowledgment. Credit pull, AUS submission, document classification, notification fan-out, none of it belongs inside the request the user is waiting on. Microsoft’s architecture guidance calls this queue-based load leveling, and the framing I like from it is that the queue is not a performance optimization. It is a shock absorber. Load arrives at whatever rate the world decides. Work drains at whatever rate your system can actually sustain. The buffer between those two numbers is the only thing standing between a spike and an outage.
During the September 2025 window, the teams I know who had this in place saw their intake latency stay flat while their queue depth went up by an order of magnitude and drained over the following few hours. Borrowers got a confirmation in under a second. The work happened. It just happened slightly later than usual, and nobody outside engineering noticed.
What it costs you is honesty in the product. A receipt is not a decision. If your interface implies the credit pull already ran, you have traded an outage for a lie, and the second one is worse.
Pattern 2: Bulkhead Every Vendor and Treat Their Quota as Your Ceiling
Now the one that actually separates teams that have lived through a spike from teams that have only planned for one.
Read this number carefully, because it reframes the entire capacity conversation. Encompass Developer Connect enforces a concurrency limit, and per ICE’s own published developer documentation, “the default limit of 30 is set for each lender environment.” Thirty simultaneous calls. Exceed it and you get HTTP 429. ICE returns X-Concurrency-Limit-Limit and X-Concurrency-Limit-Remaining headers on every response so you can see exactly how close you are.
Thirty. Across every integration you have, every partner-initiated call, every background job, every retry storm your own code generates when things start timing out. That is the ceiling.
You can autoscale your services to a hundred instances. It will not help. It will hurt, because a hundred instances hammering a thirty-call ceiling produces a 429 flood, which produces retries, which consume the same ceiling, which produces more 429s. That is the retry death spiral, and I have watched it take down a pipeline in under four minutes.
The pattern is the bulkhead, borrowed from ship design. Isolated compartments. One floods, the rest do not.
In practice that means four things. A dedicated connection pool and worker budget per vendor, so a slow appraisal API cannot starve the threads your pricing calls need. A client-side token bucket metered against the vendor’s published limit, so you throttle yourself before they throttle you. A circuit breaker that opens on sustained failure and stops sending traffic into a system that is already down. And retries with exponential backoff plus jitter, which the Amazon Builders’ Library explains better than I can: without jitter, every client retries in lockstep and you have built a synchronized attack on your own vendor.
One design note that saves real money. Read those concurrency headers and act on them. Most teams log them. The good ones feed X-Concurrency-Limit-Remaining into the scheduler and slow the low-priority queue down before the ceiling gets close. Your capacity plan is not your own. Write code that knows that.
Pattern 3: Split the Read Path, Then Decide What Is Allowed to Be Stale
Rate drops do not just create applications. They create looking. Constant looking.
Loan officers refresh pricing. Borrowers refresh status. Managers refresh the pipeline dashboard, usually the heaviest query in the system, usually every ninety seconds, usually all at once because they are all reacting to the same headline. Reads outrun writes badly during a spike, and the ugly part is that read traffic and write traffic are competing for the same database at the exact moment writes matter most.
Separating them is standard. Command and Query Responsibility Segregation, or CQRS, in its formal version, precomputed read models and a cache in its practical one. Pipeline views get materialized on write instead of assembled on read. Dashboards hit a replica. Status lookups hit Redis. None of this is novel and most engineering teams can implement it in a sprint or two.
The mortgage-specific part is not the mechanism. It is the judgment call underneath it, and this is where I have seen smart teams get it wrong.
Every cached read needs an explicit staleness budget, and in lending those budgets are not a performance preference. Some of them are legal. A pipeline dashboard can be ninety seconds behind and nobody is harmed. A locked price cannot be stale by even one second, because the lock is a commitment rather than a display value, and a stale read of it is a mispriced loan that somebody in secondary marketing gets to explain later. A disclosure timestamp cannot be stale, because a deadline computed from a cached clock is a compliance finding waiting to happen. I wrote about how that class of mistake actually lands in what mortgage tech engineering leaders learn the hard way about compliance.
So write the budget down. Field by field, in the code, next to the cache configuration. Not in a wiki. The engineer who caches a lock expiry at 2 a.m. during a surge is not going to read your wiki.

Pattern 4: Replayable Writes, and Load You Shed on Purpose
The fourth pattern is about what happens after something fails. Because during a spike, something fails. Something always does. That is not pessimism. It is arithmetic.
Two halves to this one.
First, every write that crosses a service or vendor boundary carries an idempotency key, and every consumer is safe to run twice. This sounds like hygiene. Under load it is survival, because the only safe response to an ambiguous timeout is to retry, and the only safe retry is one that cannot double-charge a borrower or double-submit to an automated underwriting engine. The Amazon Builders’ Library has a good piece on making retries safe with idempotent APIs, and the operational payoff is simple. Failed messages land in a dead-letter queue with enough context to replay them. Then you replay. A spike that costs you four hours is a bad afternoon. A spike that loses a disclosure event is a regulatory problem, and those two outcomes are separated entirely by whether you built replay.
Second half, and this is the one that requires a decision nobody wants to make in the moment. Decide in advance what you will drop.
Google’s SRE book is blunt about it in the chapter on handling overload: a system that does not shed load gracefully will shed it disgracefully. Every request slows down, every timeout fires, and instead of a degraded system you get a dead one. So tier your work. Loan-critical path first, meaning intake, pricing, credit, disclosures. Analytics refreshes, marketing sync, nightly recalculations, non-urgent notifications, all of that gets paused when queue depth crosses a threshold you set on a calm day.
Write the tiers down while nothing is on fire. At 11 a.m. on a rate-drop Wednesday, nobody is making a good prioritization decision.
The Four Patterns Side by Side
| Pattern | What it protects | What it costs | Where it bites in mortgage |
|---|---|---|---|
| Async intake | Borrower-facing response time | Eventual consistency, and UI copy that has to be honest about it | Application submit, rate-lock request, bulk document upload |
| Vendor bulkheads | One slow vendor taking down everything else | Per-vendor config, quota tracking, real observability | LOS concurrency limits, credit resellers, AUS, pricing engines |
| Read-path separation | Write capacity when everyone is refreshing | A staleness budget per field, and the discipline to honor it | Pipeline dashboards, pricing views, borrower status pages |
| Replay plus load shedding | Data loss and compliance exposure during failure | Idempotency keys everywhere, plus a tiering decision made in advance | Disclosure events, AUS resubmits, payment and fee writes |
Notice what all four have in common. Each one takes a dependency you do not control and puts a boundary around it. A queue, a quota, a cache, or a retry log. That is the actual pattern under the patterns, and it is why these four survive spikes that architecture diagrams with more boxes do not.
Which One to Build First
If you are staring at all four and your next rate move is a Fed meeting away, build them in this order.
Bulkheads first. Always. They are the cheapest, they need no data model changes, and they address the failure mode that actually takes you down, which is one vendor’s ceiling becoming your outage. A team can ship per-vendor pools, a circuit breaker, and backoff with jitter in about two weeks.
Async intake second, but only on the endpoints a human is waiting on. Do not convert your whole system. Convert application submit, lock requests, and document upload, then stop and measure.
Read-path separation third, and start with your single heaviest query. It is the pipeline dashboard. It is always the pipeline dashboard.
Idempotency and replay fourth in sequence, first in priority for anything touching money or a disclosure. Yes, that is a contradiction. Do it anyway, because retrofitting idempotency across a mature lending system is genuinely painful, nobody outside engineering will ever understand why it took a quarter, and you are not getting budget for it as a standalone project. Attach it to the other three as you go.
One thing to skip: do not start with a broker migration. Adopting Kafka is the right call for a lot of teams, and I have led that project and measured a 45 percent reduction in downstream processing latency out of it. But that is a quarter of work, minimum. Bulkheads are two weeks. Ship the two weeks first. As build vs buy calls go, the broker itself is easy. You buy it. The real spend is the event model you have to design either way.
The Hiring Problem Sitting Under All Four
Here is the part that does not show up in an architecture review.
All four of these patterns are well documented. The Microsoft and AWS pages I linked above are free, they are good, and any senior engineer can read them in an afternoon. So why do lending platforms keep going down on rate-drop Wednesdays?
Because knowing the pattern and knowing which vendor lies to you are different skills. Very different.
An engineer who has shipped inside a loan flow knows that AUS latency is not a constant, that it degrades when everyone submits at once, and that “we will just retry” is a plan that generates duplicate submissions. They know which fields are legally allowed to be cached. They know the LOS has a concurrency ceiling before they read the docs, because they hit it at 2 a.m. once and still remember the incident. That knowledge is not in a book. It is scar tissue, and it takes roughly one refinance cycle to grow.
This is a real constraint on hiring. The overlap between engineers who can design an event-driven system under the hood and engineers who understand what a lock, a disclosure, and an AUS resubmit actually mean is small, and every lender competes for the same people. It is the crossover KORE1 has spent two decades staffing for, across more than 30 U.S. metros, with a 92 percent twelve-month retention rate on placements. If you are building this team, the roles that matter are usually a mix of API and integration architects and engineers with real distributed systems and event-driven architecture experience.
There is also a timing problem worth naming. Hardening happens between spikes, which means the work is bursty by nature, and a permanent headcount request for a two-month bulkhead project is a hard sell to a CFO who just watched rates move against the plan. Several of the better-run lending teams I know solve this with contract engineering capacity for the hardening window and keep the permanent roles for the people who own the event model long term. Either way, the fastest way to find out whether your pipeline has those people is to talk to a recruiter who staffs fintech engineering teams before the next rate move, not during it.
What Engineering Leaders Ask Me About Volume Spikes
How much headroom should we actually design for?
Three times your normal peak, sustained for a week, is the planning number I use for lending platforms. The September 2025 refinance surge ran 58 percent above the prior week in the MBA survey, and internal peaks run hotter than industry indexes because your marketing fires at the same moment. Design for three times, then verify you degrade cleanly at ten, because the ceiling you cannot autoscale past is your vendor’s, not yours.
Can we just autoscale our way through this?
No, and autoscaling without bulkheads usually makes a spike worse. More instances calling a vendor with a fixed concurrency limit generate more 429s, which generate more retries, which consume the same limit. You scale into a wall and then hit it harder. Scale your own compute after you have put a metered boundary in front of every dependency you do not own.
Our LOS vendor says they can raise our limits. Is that the fix?
It helps and it is worth doing, but it moves the ceiling rather than removing it. Higher concurrency still runs out, usually at the least convenient moment, and a raised limit does nothing about the vendor having a bad day. Ask for the increase, then build as though you did not get it. Every quota you depend on should have a client-side meter in front of it.
We are mid-migration off the Encompass SDK. Does that change the priority order?
It raises it. A migration to REST APIs is exactly when concurrency behavior changes underneath you and old assumptions quietly stop being true. Build bulkheads and metering as part of the migration rather than after, because you are already touching that code. I broke down the timeline and cost side of that project in the real cost of an Encompass integration.
How do we prove any of this worked before the next spike?
Run a game day. Pick a Thursday, load-test intake at three times peak against vendor sandboxes, and force a 429 storm on purpose to watch what your retry logic actually does. Most teams discover their backoff has no jitter and their circuit breaker was never wired to anything. Better to find that in a controlled test than during a rate move you did not schedule.
The Short Version
Volume spikes in mortgage tech are not a scaling problem in the way that phrase usually gets used. Nobody is running out of CPU. What runs out is somebody else’s concurrency budget, and what breaks is the assumption that a call to another company’s API will return when you need it to.
Queue the intake. Bulkhead the vendors. Split the reads and write down what is allowed to be stale. Make everything replayable and decide in advance what you will drop. Four patterns. None of them exotic, all of them boring, and boring is the point, because the next rate move is not going to wait for your roadmap.
If you are working through this in your own stack and want to compare notes, connect with me on LinkedIn. I answer.

