Forked from kellemar/gist:31b2b0d957e398d0edc9e83a1e65aa10
Created
December 23, 2025 11:44
-
-
Save ShabbirHasan1/3d4853c6e5db452c3e70b0d525a7ead5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ⸻ | |
| Performance Hints for Web Backend APIs & Databases | |
| Adapted from Abseil’s Performance Hints (Jeff Dean & Sanjay Ghemawat) | |
| ⸻ | |
| 1) Think About Performance Early — Especially Hot Paths | |
| Original idea: If you ignore performance early, you get a flat profile with no obvious hotspots. | |
| Web-dev translation: | |
| Don’t optimize only at the end. When building an API service, ask “Will this run on every request?”. | |
| • Code in request handlers, middleware chains, or DB access layers runs per request — those are your hot paths. | |
| • Initialization, config loading, or background jobs matter less per-request. | |
| Actionable clue: | |
| If a function is called for every HTTP request, treat it like performance-sensitive code. | |
| ⸻ | |
| 2) Estimate Cost of Operations in Your Stack | |
| Original idea: Use “back of the envelope” performance estimates of operations. | |
| Web-dev translation: | |
| Quantify costs realistically: | |
| • DB round-trip latency (e.g., 10–30 ms). | |
| • Cache lookup (e.g., 1 ms). | |
| • CPU work vs I/O wait. | |
| These help decide if adding a cache, batching calls, or denormalizing data is worth it. | |
| Example: | |
| If an ORM query takes 25 ms and you do 5 per request → ~125 ms just in DB time. | |
| ⸻ | |
| 3) Profile & Measure Before Changing Things | |
| Original idea: Effective measurement is the #1 tool for performance. | |
| Web-dev translation: | |
| Use real metrics (APM, flamegraphs, latency percentiles) not guesswork. | |
| • Do you have slow db indexes or N+1 queries? | |
| • Do GC pauses spike under load? | |
| • Are API bottlenecks CPU, I/O, or network bound? | |
| Measure before and after changes to know impact. | |
| ⸻ | |
| 4) Avoid Microbenchmarks That Don’t Reflect Production | |
| Original idea: Benchmarks can mislead if they don’t represent real conditions. | |
| Web-dev translation: | |
| Local tests of tiny functions aren’t enough: | |
| • A fast loop in dev doesn’t mean your service scales under load. | |
| • Synthetic tests that don’t replicate real request patterns can give false confidence. | |
| Always test load under realistic request mixes. | |
| ⸻ | |
| 5) Choose Better Algorithms & Data Structures Early | |
| Original idea: Major gains often come from algorithmic improvement — big wins outweigh micro-optimizations. | |
| Web-dev translation: | |
| Often, the biggest wins aren’t caching micro-seconds: | |
| • Use proper indexes for DB queries. | |
| • Avoid O(N²) DB access patterns (e.g., N+1 queries). | |
| • Batch writes instead of many small writes. | |
| Rule-of-thumb: Fix algorithmic/DB query inefficiencies before micro-tuning code paths. | |
| ⸻ | |
| 6) Reduce Latency & Expensive Ops Across Boundaries | |
| Original idea: Provide bulk APIs to reduce boundary costs. | |
| Web-dev translation: | |
| Crossing system boundaries is expensive (network/DB calls): | |
| • Batch reads: SELECT * FROM items WHERE id IN (…) vs many single reads. | |
| • Combine API calls into one if possible. | |
| • Use paginated endpoints or multi-get endpoints. | |
| Fewer round-trips = significant performance improvements. | |
| ⸻ | |
| 7) Use Efficient Data Access Patterns | |
| Original idea: View types reduce copying; pre-compute or reuse data when possible. | |
| Web-dev translation: | |
| • Keep data shapes minimal in API responses. Strip unnecessary fields. | |
| • Avoid transferring redundant data; let clients request only needed fields (e.g., GraphQL projections or REST sparse fieldsets). | |
| • Cache static or semi-static data instead of recomputing on every request. | |
| ⸻ | |
| 8) Don’t Pay for Thread Safety You Don’t Need | |
| Original idea: Prefer externally synchronized types over internally synchronized ones when possible. | |
| Web-dev translation: | |
| High-contention locks or synchronized caches slow throughput. | |
| • Use concurrent/lock-free caches when under high API load. | |
| • Design services to scale horizontally so each instance handles less contention. | |
| ⸻ | |
| 9) Use Bulk Database & Cache Ops When Possible | |
| Original idea: Provide bulk ops to reduce expensive API boundary crossings. | |
| Web-dev translation: | |
| Always ask: can we batch? | |
| • Multi-row inserts/updates. | |
| • Bulk invalidate cache keys. | |
| • Fetch many keys at once from Redis instead of one at a time. | |
| ⸻ | |
| 10) Consider Real-World Latencies — Not Just CPU Cycles | |
| Original idea: System cost table shows 50ns cache vs ms network vs millions ns disk. | |
| Web-dev translation: | |
| Web apps are dominated by I/O: | |
| CPU: microseconds | |
| DB calls: 10s of milliseconds | |
| Network: 10s–100s ms | |
| Disk I/O: 100s ms–seconds | |
| This means: | |
| • Network & DB matter far more than minor CPU savings. | |
| • Do DB tuning or caching before micro-optimizing code. | |
| ⸻ | |
| 11) Avoid Premature Optimization, But Don’t Ignore It | |
| Original idea: “Premature optimization is the root of all evil… but don’t ignore the critical 3%.” | |
| Web-dev translation: | |
| Focus on clean code and correctness first, but be ready to optimize when metrics show real performance pain. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment