Engineering

API Design That Survives 10 Million Users: Principles from the Trenches

AT

Aiir Technologies

Backend Team

8 min read

We have reviewed hundreds of API architectures. The ones that scale to millions of users share common design principles. The ones that collapse share common mistakes. Here are the principles, distilled from real production systems.

Principle 1: Design for the Consumer, Not the Database

The most common API mistake is exposing your database schema as your API. Your users do not care about your normalized tables. They care about completing tasks. Design your API around use cases, not entities.

Bad: GET /users/123 then GET /users/123/orders then GET /orders/456/items — three calls to show one page.

Good: GET /users/123/dashboard — one call that returns everything the consumer needs for that view. Yes, this means your API has some denormalization. That is the point.

Principle 2: Pagination Is Not Optional

Every list endpoint must be paginated from day one. Not "we will add it when we need it." By the time you need it, you have clients depending on the unpaginated response, and adding pagination is a breaking change.

Use cursor-based pagination, not offset-based. Offset pagination breaks when data is inserted or deleted between requests. Cursor pagination is stable, performant, and works correctly with real-time data.

Principle 3: Idempotency Keys for All Mutations

Network requests fail. Clients retry. Without idempotency keys, a retried POST creates a duplicate order, a duplicate payment, a duplicate user. Every write endpoint should accept an idempotency key. If the same key is sent twice, return the original response without re-executing the action.

Stripe does this. Shopify does this. If your payment API does not, you will eventually charge someone twice and learn this lesson the expensive way.

Principle 4: Rate Limiting with Empathy

Rate limit everything. But do it with clear communication. Return 429 Too Many Requests with a Retry-After header telling the client exactly when to try again. Include rate limit headers (X-RateLimit-Remaining, X-RateLimit-Reset) on every response so clients can self-regulate.

Principle 5: Version from Day One

Put the version in the URL: /v1/users. Not in headers. Not in query parameters. In the URL. It is visible, cacheable, and unambiguous. When you release v2, v1 keeps working. Your existing clients do not break. This is non-negotiable.

Principle 6: Errors Are a Feature

Your error responses should be as well-designed as your success responses. Every error needs: a machine-readable error code, a human-readable message, a link to documentation, and the request ID for debugging. {"error": "something went wrong"} is not an error response. It is a cry for help.

The Compound Effect

Each principle seems simple in isolation. Together, they compound into an API that is a pleasure to integrate with, scales predictably, and creates a moat of developer loyalty. The APIs that developers love become the platforms that win.

Ready to Transform Your Business with AI & Technology?

Let's discuss your project. Get a free consultation and discover how we can help you achieve your technology goals.

Free Consultation No Commitment Response within 24hrs