Skip to main content
RESTful Principles
CHAPTER 28 Beginner

REST API Performance Optimization

Updated: May 13, 2026
5 min read

# CHAPTER 28

REST API Performance Optimization

1. Introduction

A perfectly functioning API is useless if it takes 5 seconds to load. In the modern web, users expect instant responses. If your API is slow, mobile apps feel sluggish and users leave. In Chapter 28, we will explore the critical techniques required to optimize a REST API. We will cover database query optimization, payload compression, and the magic of HTTP caching.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Identify common bottlenecks that slow down PHP REST APIs.
  • Optimize MySQL queries (Indexing and N+1 queries).
  • Implement GZIP/Brotli compression to reduce JSON payload sizes.
  • Understand and implement HTTP Caching headers (Cache-Control, ETag).
  • Implement Server-Side caching using Redis/Memcached.

3. Beginner-Friendly Explanation

Imagine a library (your database) and a librarian (your API).
  1. 1. Database Optimization: If you ask the librarian for all books by "Smith", and the books aren't sorted, they have to check every single book in the building (Full Table Scan). If the books are indexed alphabetically, they find them instantly.
  1. 2. Payload Compression: If you request 100 books, the librarian packs them tightly in a vacuum-sealed bag (GZIP) so they are easier to carry to your car.
  1. 3. Caching: If 50 people ask the librarian for the same daily newspaper, the librarian keeps a copy on the front desk (Cache) instead of walking to the back room 50 times.

4. Real-World Examples

  • Caching: An e-commerce API has a /categories endpoint. Categories rarely change. By caching this data, the API can serve 10,000 requests per second with zero database lookups.
  • Compression: A /users endpoint returns a 1MB JSON string. By enabling GZIP, that string is compressed to 100KB before being sent over the network, making it 10x faster to download on a mobile phone.

5. Detailed Code Examples

Let's look at HTTP Caching. You can tell the client's browser/app to store the data locally for a specific amount of time.
php
1234567891011121314151617181920212223242526272829
<?php
// Endpoint: GET /api/categories

// 1. Tell the client to cache this response for 3600 seconds (1 hour)
header(&#039;Cache-Control: max-age=3600, public');

// 2. We can also use an ETag (a hash of the data)
$data = [
    ["id" => 1, "name" => "Electronics"],
    ["id" => 2, "name" => "Clothing"]
];
$jsonOutput = json_encode($data);
$eTag = md5($jsonOutput);

header("ETag: \"$eTag\"");

// 3. Check if the client sent an ETag in their request header
$clientETag = $_SERVER[&#039;HTTP_IF_NONE_MATCH'] ?? '';

// If the client's hash matches our current hash, the data HAS NOT CHANGED!
if ($clientETag === "\"$eTag\"") {
    // Return a 304 Not Modified. The server sends NO body data!
    http_response_code(304);
    exit;
}

// Otherwise, send the full data
echo $jsonOutput;
?>

6. Request/Response Examples

When using ETags, the second request is blazing fast because no data is downloaded.

Client Request 1: GET /categories *(Downloads 500KB of JSON)*

Client Request 2 (5 minutes later): GET /categories If-None-Match: "eTagHash123" Response: 304 Not Modified *(Downloads 0KB. The app instantly uses the data it saved 5 minutes ago!)*

7. HTTP Examples

Server configuration is critical for performance. You don't need PHP to compress JSON; Apache/Nginx can do it automatically. In an Apache .htaccess file, adding this turns on GZIP for your API:
apache
123
<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE application/json
</IfModule>

8. JSON Examples

When returning massive JSON arrays, omit unnecessary data. If the mobile app only needs the user's id and name for a list view, do not execute SELECT *. Select only what is needed.

Bad (100KB payload): [{"id": 1, "name": "John", "bio": "long text...", "createdat": "...", "avatar": "..."}]

Optimized (10KB payload): [{"id": 1, "name": "John"}]

9. Best Practices

  • Database Indexes: This is the #1 fix for slow APIs. Ensure columns used in WHERE or ORDER BY clauses (like userid or created_at) have indexes in MySQL.
  • Solve the N+1 Problem: If you fetch 50 articles, and then run a separate SQL query inside a loop to fetch the author for *each* article, you are running 51 queries! Use SQL JOINs to fetch all data in a single query.
  • Use Redis for Data Caching: Instead of querying MySQL for the top 10 articles on every request, query MySQL once, save the JSON string in Redis (RAM), and serve subsequent requests directly from Redis. It is 100x faster.

10. Common Mistakes

  • Caching User Data: Be extremely careful with caching. Never use Cache-Control: public on an endpoint like /profile, or an intermediary proxy server might cache User A's private data and accidentally serve it to User B! Use Cache-Control: private for user-specific data.
  • Over-fetching: Returning a massive JSON object with 50 keys when the frontend only displays 3 of them.

11. Mini Exercises

  1. 1. What does the HTTP Status Code 304 Not Modified mean for an API response?
*(Answer: It tells the client that the data on the server hasn't changed, so the client should just use the JSON it already has saved in its local cache).*

12. Coding Challenges

Challenge 1: Write a PHP snippet that executes a SQL JOIN to get a list of "Orders" alongside the "User's Name" in a single query, avoiding the N+1 problem.

13. MCQs with Answers

Question 1

What is the N+1 query problem?

Question 2

How does GZIP compression improve API performance?

Q3. If data is highly dynamic and changes every second, should you use Cache-Control: max-age=3600? A) Yes, caching is always good. B) No, because clients will see outdated data for an hour. *Answer: B*

14. Interview Questions

  • Q: Explain how ETags and the 304 Not Modified status code improve mobile app performance.
  • Q: What is the N+1 query problem, and how do you resolve it in a relational database?
  • Q: When should you use Server-Side caching (Redis) vs Client-Side caching (HTTP Cache-Control)?

15. FAQs

Q: Is JSON faster than XML? A: Yes, significantly. JSON uses fewer characters (no closing tags like </name>), meaning the payload size is smaller and faster to download. Browsers and modern languages also parse JSON into native objects much faster than XML.

16. Summary

In Chapter 28, we focused on speed. We learned that the fastest database query is the one you don't have to make, emphasizing the use of Redis and HTTP Caching (Cache-Control, ETags). We also highlighted the importance of SQL Indexes, avoiding N+1 queries using JOINs, and enabling GZIP compression to minimize the physical size of our JSON payloads.

17. Next Chapter Recommendation

You have mastered every single aspect of REST API design, security, and performance. It is time for the final exam. Proceed to Chapter 29: Building a Complete RESTful Project API to build a production-ready application from scratch.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·