The summary.
KEEP BUSINESS RULES INDEPENDENT OF DELIVERY AND STORAGE
They can then be tested without infrastructure, and infrastructure can be replaced.
Apply layering by need, not dogmatically — layers that only pass calls through add nothing.
ENFORCE CONSTRAINTS IN THE DATABASE
They hold even when application code has a bug. Index what you filter, join and sort by, and use exact decimal types for money.
Store timestamps in one time zone. Mixed zones produce errors nobody diagnoses quickly.
MEASURE BEFORE SCALING
Most scaling work addresses problems that do not exist, and the database is usually the bottleneck.
Horizontal scaling requires statelessness — no session state in process memory, no files written to local disk and read later.
CACHING'S HARD PROBLEM IS INVALIDATION
Prefer expiry, vary it slightly between entries, and ensure the system works correctly when the cache is empty.
A cache with a poor hit rate adds complexity for nothing.
TEST INVALID INPUT, MISSING AUTHENTICATION AND INSUFFICIENT AUTHORISATION
They are the paths most often broken and least often tested. And test queries against a real database.