# Architecture Review — Sample

**This is an illustrative example.** The system and figures are invented to show the shape of a
review that produces decisions. Copy the structure; measure your own system.

The review deliberately avoids architectural preference. Every recommendation is supported by
either an incident, a measurement, or a change-history count.

---

## Architecture review — order platform

| | |
|---|---|
| System | Order capture, pricing, fulfilment, invoicing, reporting |
| Age | 6 years, 5 services, one shared database |
| Method | Change history, incident record, load measurement, dependency mapping |
| Prepared for | Engineering leadership |

## 1. How it is actually used

| | |
|---|---|
| Orders per day | 42,000 |
| Peak, as a multiple of median hour | 3.1× |
| Read to write ratio | 40:1 |
| Reporting queries per day | 900 |
| Growth, 12 months | 18% |

**The read-to-write ratio is the most consequential number in this review**, and it was not
known before the review. The system is designed as though writes dominate, and reads —
including every reporting query — go to the same database as order capture.

## 2. Where change concentrates

| Component | Share of code | Share of changes | Incidents |
|---|---|---|---|
| Pricing | 11% | **38%** | 9 |
| Order capture | 19% | 17% | 4 |
| Fulfilment | 24% | 14% | 6 |
| Invoicing | 18% | 21% | 3 |
| Reporting | 28% | 10% | 2 |

Pricing changes constantly — it is where the business expresses itself — and it is the smallest
component. **It is also called synchronously by order capture**, which is section 4.

## 3. Coupling

| Coupling | Type | Cost in the period |
|---|---|---|
| All 5 services → one database | Shared data store | **6 of 24 incidents** |
| Order capture → pricing | Synchronous | 9 incidents, all pricing-caused |
| Invoicing → fulfilment | Synchronous | 2 incidents |
| Fulfilment → carrier API | Synchronous, external | 4 incidents |
| Reporting → the same database | Shared | 3 incidents |

**The shared database is the largest structural finding.** Five services with no business
relationship share a failure domain. Twice this year a reporting query has degraded order
capture; on both occasions the reporting team was unaware of the incident and the order team
had no way to see the cause.

## 4. The pricing coupling

Worth its own section, because it produces the most incidents and the fix is not obvious.

Order capture calls pricing synchronously. Pricing changes most often. **The most frequently
changed component sits inside the availability path of the most business-critical one.**

| | |
|---|---|
| Pricing incidents in 12 months | 9 |
| Of those, causing order capture to fail | **9** |
| Median duration | 14 min |
| Orders lost or delayed | ~3,900 |

The naive fix — make it asynchronous — is wrong. A price is needed to accept an order; there
is no meaningful order without one. This is a genuine coupling and the honest response is to
make it bounded rather than to pretend it is not there.

**Recommended instead:** a timeout with an explicit fallback to the last published price list,
plus a circuit breaker. The fallback is not as good as live pricing and it is much better than
refusing orders. The business rule — how long a stale price may be used, and for which product
categories — is a decision for the commercial team, not for engineering.

## 5. Load

| | Measured | Provisioned for |
|---|---|---|
| Order capture, peak | 340 req/min | 2,000 |
| Pricing, peak | 340 req/min | 400 |
| Reporting, peak | 90 queries/min | shared |
| Database connections at peak | 780 of 800 | 800 |

**The connection pool is the binding constraint and nobody knew.** At peak the system is 20
connections from refusing work, and the largest single consumer is reporting — long-running
queries holding connections while order capture waits.

This also explains an unexplained class of incident: three "slow order capture" reports
correlate exactly with a monthly reporting job.

## 6. What is working

Recorded because a review of only problems produces a rewrite proposal.

- **Service boundaries follow the business.** Order, pricing, fulfilment and invoicing are real
  domains, not layers. This is the hard part and it is right.
- **Order capture is idempotent.** Duplicate submissions are handled correctly, which has
  prevented several incidents from becoming data problems.
- **The carrier integration has a timeout and a queue.** The one external dependency is the
  best-protected boundary in the system.
- **Deployment is per service** and has been for two years.

## 7. Recommendations

1. **Separate reporting from the operational database.** A read replica, with reporting pointed
   at it. Addresses 3 incidents, the connection-pool constraint, and the monthly correlation.
   Roughly two weeks and no application change.
2. **Bound the pricing call** — timeout, fallback to the last published list, circuit breaker.
   Addresses 9 incidents. Needs a commercial decision on stale-price tolerance first.
3. **Give each service its own schema** within the shared instance, as a step toward separate
   stores. Removes accidental cross-service queries, of which the review found 14.
4. **Raise the connection pool and alert at 80%.** A one-line change that removes the current
   silent ceiling.
5. **Do not split pricing into smaller services.** It changes often because the business changes
   often, not because it is too large. Splitting it would distribute a coupling rather than
   remove one.
6. **Do not rewrite fulfilment.** It has 6 incidents and 14% of changes, and every one of the
   incidents traces to the carrier API rather than to the code.

**Deliberately not recommended:** a move to full service isolation with separate databases per
service. Recommendations 1 and 3 capture most of the benefit for a fraction of the work, and
the remainder can be argued when the first two have been measured.

---

## Notes on using this format

**Measure how the system is used before reviewing how it is built.** The 40:1 read-to-write
ratio was unknown, and it reframed the entire review.

**Count incidents per coupling.** It converts "the shared database is bad practice" into "the
shared database caused 6 of 24 incidents", which is a sentence that gets funded.

**Say what not to change.** Two of the six recommendations are refusals, and both are for
components that look like obvious candidates and cost nothing.
