8 lessons

Performance & Observability

The API-shaped levers: payload size, compression, request count, caching. Request IDs, metrics without high-cardinality labels, logs that never contain tokens, and contract tests.

RequirementConsumersResource ModelStyleContractValidationAuthorizationErrorsIdempotencyPaginationVersioningObservabilityEvolutionTrade-offs

Every lesson below names the consumers, the design question and the guarantee before recommending anything. Recommendations come with what they cost, when not to use them, and how they evolve.

API Performance: The Levers You Actually Own
▶ lab

Most API latency is decided by the contract, not the code: how many round trips a task needs, how many bytes each carries, and how often a request can be skipped entirely. The levers are payload, compression, request count, caching, serialization and field selection.

Q · Which parts of this API's latency are contract decisions, and which lever pays back the most for the consumers who feel it?
Payload Size: 20KB, 200KB, 5MB
▶ lab

Payload cost is paid four times — transfer, serialization, memory, client parse — and it scales with every caller. A 20KB response is a non-event, 200KB is a tax on every mobile render, and 5MB is an architecture mistake wearing a JSON costume.

Q · What does each response size cost across the four places it is paid, and where should the contract cap it?
Compression: Cheaper Bytes, Not Fewer

gzip or brotli shrinks JSON 5–10× for a CPU price paid on every request. The trade inverts on small payloads, already-compressed data and CPU-bound services — and the negotiation headers are contract clauses, not transport trivia.

Q · For this endpoint's payload sizes, consumers and traffic, does trading CPU for bandwidth pay — and what does the contract promise about negotiation?
Request IDs: The Contract's Correlation Clause

One opaque id, minted at the edge, propagated through every hop, returned in every response — especially errors. It is the difference between "can you send a screenshot?" and finding the exact failing request in one query.

Q · When a consumer reports one failed call, can both sides find that exact request across every hop it touched?
API Metrics: Rate, Errors, Duration, Sizes

Four signals per endpoint — request rate, error rate by class, duration percentiles, payload sizes — labeled by route template, method and status class. The craft is in the labels: one high-cardinality label like user_id can melt the metrics system that was supposed to watch everything else.

Q · Can you answer "is this endpoint healthy, for whom, and compared to what we promised?" from metrics alone — without grepping logs?
API Logging Without Leaking

One structured line per request: operation, status, duration, request id, principal, safe context. The hard part is the discipline of absence — no tokens, no passwords, no full bodies — because logs are the widest-read, longest-retained copy of your traffic.

Q · Does every request leave exactly one useful, queryable record — and is it impossible for that record to contain a credential?
Testing the Contract, Not Just the Code

Unit tests prove the handler works; contract tests prove the promises hold; compatibility tests prove yesterday's consumers survive tomorrow's deploy. An API test suite is organized around the guarantees, and the cheapest test that catches each broken guarantee wins.

Q · Which promise does each test protect — and would this suite catch a change that breaks a consumer before the consumer does?
The Gateway as Policy Boundary

Authentication verification, rate limits, size caps, request IDs, TLS, routing and version steering can live at the gateway — one enforcement point instead of N reimplementations. The discipline is knowing which contract clauses belong at the edge, and remembering that gateway-generated responses are part of your contract too.

Q · Which clauses of this contract should be enforced once at the edge, which must stay in the services — and do the gateway's own responses honor the contract?