Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save ShabbirHasan1/3d4853c6e5db452c3e70b0d525a7ead5 to your computer and use it in GitHub Desktop.

Select an option

Save ShabbirHasan1/3d4853c6e5db452c3e70b0d525a7ead5 to your computer and use it in GitHub Desktop.
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