Architecture, Cloud & Beyond

Choosing the Right Granularity for Your APIs: Light vs Heavy API Calls

When designing APIs, one of the most important - and often overlooked - decisions is granularity. Should your API calls be lightweight and specific, fetching or modifying just one thing at a time? Or should they be heavyweight and aggregated, returning a bundle of data or performing multiple operations at once?

Let’s explore how to make that decision thoughtfully, based on performance, maintainability, user experience, and real-world use cases.

What Do We Mean by API Granularity?

Granularity refers to how much work a single API call performs:

  • Fine-grained (lightweight) APIs perform small, specific tasks, e.g., GET /user/123/profile-picture.
  • Coarse-grained (heavyweight) APIs do larger or aggregated tasks, e.g., GET /user/123/dashboard-data (which might include profile, recent activity, and recommendations in one call).

Both approaches have their place. The key is balancing the trade-offs based on your system’s goals.

When to Prefer Lightweight (Fine-Grained) APIs

Use when:

  • You need flexibility for frontend teams to mix and match data.
  • Data is frequently changing, and small pieces need to be refreshed independently.
  • There are strict caching or performance constraints - smaller payloads are faster to transfer.
  • You're building a microservice that should do one thing well and stay loosely coupled.

Risks:

  • Chatty APIs - too many round trips between client and server can degrade performance, especially on high-latency networks.
  • Increased complexity on the client side — clients must now orchestrate multiple API calls.

Example:

GET /products/123

GET /products/123/reviews

GET /products/123/inventory

This gives flexibility but could require three separate round trips.

When to Prefer Heavyweight (Coarse-Grained) APIs

Use when:

  • A client consistently needs multiple data elements together - like a mobile app loading a dashboard.
  • Reducing latency and number of HTTP calls is a priority.
  • You want to encapsulate orchestration logic on the backend rather than exposing it to clients.
  • You're building GraphQL-style endpoints or BFFs (Backend-for-Frontend) - I will discuss this pattern in a separate blog.

Risks:

  • Potential over-fetching - returning data the client doesn’t always need.
  • Tighter coupling - changes to a backend schema may require more coordination across teams.
  • Difficult to cache partial data or maintain modularity.

Example:

GET /dashboard

This could return the user profile, order history, loyalty points, and recommendations in a single response.

How to Decide Granularity: 6 Questions to Ask

  1. What’s the client context?
    Mobile apps with high-latency networks benefit from heavier APIs. Internal systems on fast networks can afford more granular calls.
  1. What’s the usage pattern?
    If clients always need data A and B together, merge them. If they rarely co-occur, keep them separate.
  1. Are you building for reuse or speed?
    Reusable, generic APIs tend to be lightweight. Purpose-specific APIs (e.g., /checkout-summary) can be heavier but optimized.
  1. How often does each piece of data change?
    Granular APIs let you cache and refresh small parts individually.
  1. How will versioning be managed?
    Smaller APIs are easier to evolve independently. Coarse-grained ones may need more careful version control.
  1. Is this API internal or public?
    Public APIs should be stable and consistent — often leading to cleaner, more granular endpoints. Internal APIs can afford more opinionated or aggregated structures.

There’s no one-size-fits-all rule for API granularity. Like many architectural decisions, it's a trade-off — between performance and flexibility, between decoupling and convenience. A good API design is one that reflects real user needs while remaining scalable and maintainable.