Skip to main content

Improve API Performance

Five techniques I reach for when an API is too slow. The right one depends on where the bottleneck is.

The Five Techniques​


1. Pagination​

Return data in pages instead of all at once.

When I use it: Any list endpoint that could return more than ~50 rows. Default page size I pick: 20 for UI, 100 for bulk export.

Two styles:

  • Offset pagination — simple, but slow on large offsets (OFFSET 10000 scans 10k rows)
  • Cursor pagination — use a stable cursor (e.g., created_at + id), better for infinite scroll and real-time data

2. Async Logging​

Write logs to a lock-free ring buffer in memory, flush to disk on a background thread.

When I use it: High-throughput services where synchronous disk I/O adds measurable latency. Libraries like Zap (Go) do this by default.


3. Caching​

Serve frequently-read data from memory instead of hitting the DB every time.

When I use it: Read-heavy, rarely-changing data — product catalogs, config, user profiles. I set short TTLs (60s–5min) and invalidate on write. Redis is my default.

Gotcha: Don't cache anything user-specific without namespacing the key by user ID.


4. Payload Compression​

Compress response bodies with gzip or Brotli before sending.

When I use it: JSON responses over ~1KB, especially on slower mobile connections. Most frameworks enable this with one line:

  • Express: compression() middleware
  • Go/Gin: gzip.Gzip(gzip.DefaultCompression)
  • Next.js: enabled by default in production

Typical savings: 60–80% on JSON. Not worth it for tiny responses (compression overhead > gains).


5. Connection Pooling​

Reuse existing DB connections instead of opening a new one per request.

When I use it: Always. Opening a TCP connection + TLS + DB auth on every request is expensive (~10–50ms).

Language gotcha: Go/Java share a pool across goroutines/threads within one process. Node.js/PHP/Python spawn multiple processes — each process needs its own pool, which wastes connections. Fix: use a proxy like PgBouncer in front of Postgres to centralize pooling across all processes.


Sources​