Skip to content

Rate limits & caching

How to read the delivery API efficiently — page sizes, ISR and CDN caching, revalidation webhooks, and backoff.

The delivery API is designed to be read constantly by production front-ends, so the practical question is less "how hard can I hit it" and more "how little do I need to". This page covers the built-in limits, the caching patterns we recommend, and how to keep content fresh without polling.

Request limits

  • Page size: list endpoints cap limit at 100 entries per request. Ask for more and you get 100; page with offset (or cursor parameters where available) to read a full collection.
  • Self-hosted instances: there is no artificial request-per-minute meter in the product — throughput is bounded by your own infrastructure (CPU, Postgres, network). Put a CDN or cache in front rather than sizing the box for peak reads.
  • Managed/hosted setups: the host's platform limits apply (see your plan). The client patterns below keep you comfortably inside any of them.

The @flowcms/client SDK paginates for you and reuses connections. If you are hand-rolling fetch(), reuse one base URL + token and page in a loop rather than firing one request per entry.

Cache at the edge, not in your code

Published content is public and cache-friendly. The three patterns, in order of preference:

  1. Static generation / ISR — build pages from the API and revalidate on a timer (60–300 s works for most sites). This is how flowcms.co itself reads its help center and blog.
  2. CDN in front of the API — for client-side reads, cache GET /api/public/:type responses at your CDN keyed by the full query string. Published content only changes on publish, so even a 60 s TTL removes almost all origin traffic.
  3. HTTP caching — responses are deterministic for a given query; honour Cache-Control and add your own stale-while-revalidate at the edge for smooth refreshes.

Refresh on publish, don't poll

Instead of short cache TTLs everywhere, let the CMS tell you when something changed:

  • Configure a webhook on content.published / content.updated (see Webhooks) pointing at your site's revalidate endpoint.
  • The endpoint purges just the affected surface (a tag, a path, a cache key) — content appears seconds after publish with no rebuild and no polling.

This is the exact pattern this site uses: a Flow CMS webhook hits /api/revalidate with a shared secret, which purges the help, blog or pricing cache tags on demand.

Backoff and retries

Treat the API like any HTTP dependency:

  • Retry idempotent GETs on 429 and 5xx with exponential backoff and jitter (e.g. 0.5 s → 1 s → 2 s, three attempts).
  • Respect Retry-After when present.
  • Fail soft: keep rendering the last cached copy if a refresh fails. Every section of this site degrades to its last snapshot when the CMS is unreachable — that is the behaviour to copy.

Draft/preview reads (with a preview token) are personal and uncacheable — keep them out of your CDN and off hot paths. Only published, public reads belong in the cache.