{"id":330,"date":"2026-02-12T06:38:13","date_gmt":"2026-02-12T06:38:13","guid":{"rendered":"https:\/\/sanny.test\/tutorials\/uncategorized\/performance-optimization-best-practices\/"},"modified":"2026-02-12T06:38:13","modified_gmt":"2026-02-12T06:38:13","slug":"performance-optimization-best-practices","status":"publish","type":"lesson","link":"https:\/\/sanny.dev\/tutorials\/wordpress-rest-api-mastery\/performance-optimization-best-practices\/","title":{"rendered":"Performance Optimization &#038; Best Practices"},"content":{"rendered":"<p>## API Performance Matters<\/p>\n<p>Slow API responses hurt user experience and waste resources. Let&#8217;s optimize.<\/p>\n<p>## Caching Strategies<\/p>\n<p>### Transient Caching<\/p>\n<p>Cache expensive queries:<\/p>\n<p>&#8220;`php<br \/>\nfunction get_popular_posts_api() {<br \/>\n    $cache_key = &#8216;popular_posts_api&#8217;;<br \/>\n    $cached = get_transient($cache_key);<\/p>\n<p>    if ($cached !== false) {<br \/>\n        return $cached;<br \/>\n    }<\/p>\n<p>    \/\/ Expensive query<br \/>\n    $posts = new WP_Query([<br \/>\n        &#8216;posts_per_page&#8217; => 10,<br \/>\n        &#8216;meta_key&#8217;       => &#8216;views_count&#8217;,<br \/>\n        &#8216;orderby&#8217;        => &#8216;meta_value_num&#8217;,<br \/>\n        &#8216;order&#8217;          => &#8216;DESC&#8217;<br \/>\n    ]);<\/p>\n<p>    $data = array_map(function($post) {<br \/>\n        return [<br \/>\n            &#8216;id&#8217;    => $post->ID,<br \/>\n            &#8216;title&#8217; => $post->post_title,<br \/>\n            &#8216;views&#8217; => get_post_meta($post->ID, &#8216;views_count&#8217;, true)<br \/>\n        ];<br \/>\n    }, $posts->posts);<\/p>\n<p>    \/\/ Cache for 1 hour<br \/>\n    set_transient($cache_key, $data, HOUR_IN_SECONDS);<\/p>\n<p>    return $data;<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>### Object Cache<\/p>\n<p>For more persistent caching:<\/p>\n<p>&#8220;`php<br \/>\nfunction get_task_stats() {<br \/>\n    $cache_key = &#8216;task_stats&#8217;;<br \/>\n    $stats = wp_cache_get($cache_key, &#8216;taskmanager&#8217;);<\/p>\n<p>    if ($stats !== false) {<br \/>\n        return $stats;<br \/>\n    }<\/p>\n<p>    global $wpdb;<br \/>\n    $stats = $wpdb->get_results(<br \/>\n        &#8220;SELECT status, COUNT(*) as count<br \/>\n         FROM {$wpdb->prefix}tasks<br \/>\n         GROUP BY status&#8221;<br \/>\n    );<\/p>\n<p>    wp_cache_set($cache_key, $stats, &#8216;taskmanager&#8217;, 300);<\/p>\n<p>    return $stats;<br \/>\n}<\/p>\n<p>\/\/ Invalidate on changes<br \/>\nfunction invalidate_task_cache() {<br \/>\n    wp_cache_delete(&#8216;task_stats&#8217;, &#8216;taskmanager&#8217;);<br \/>\n    delete_transient(&#8216;popular_posts_api&#8217;);<br \/>\n}<br \/>\nadd_action(&#8216;task_created&#8217;, &#8216;invalidate_task_cache&#8217;);<br \/>\nadd_action(&#8216;task_updated&#8217;, &#8216;invalidate_task_cache&#8217;);<br \/>\n&#8220;`<\/p>\n<p>### HTTP Caching Headers<\/p>\n<p>Let browsers and CDNs cache responses:<\/p>\n<p>&#8220;`php<br \/>\nregister_rest_route(&#8216;myplugin\/v1&#8217;, &#8216;\/public-data&#8217;, [<br \/>\n    &#8216;methods&#8217;  => &#8216;GET&#8217;,<br \/>\n    &#8216;callback&#8217; => function() {<br \/>\n        $data = get_public_data();<\/p>\n<p>        $response = new WP_REST_Response($data);<\/p>\n<p>        \/\/ Cache for 5 minutes<br \/>\n        $response->header(&#8216;Cache-Control&#8217;, &#8216;public, max-age=300&#8217;);<\/p>\n<p>        \/\/ ETag for conditional requests<br \/>\n        $etag = md5(serialize($data));<br \/>\n        $response->header(&#8216;ETag&#8217;, $etag);<\/p>\n<p>        return $response;<br \/>\n    },<br \/>\n    &#8216;permission_callback&#8217; => &#8216;__return_true&#8217;<br \/>\n]);<br \/>\n&#8220;`<\/p>\n<p>## Reducing Response Size<\/p>\n<p>### Select Only Needed Fields<\/p>\n<p>&#8220;`php<br \/>\n\/\/ Instead of SELECT *<br \/>\n$tasks = $wpdb->get_results(<br \/>\n    &#8220;SELECT id, title, status FROM {$wpdb->prefix}tasks&#8221;<br \/>\n);<br \/>\n&#8220;`<\/p>\n<p>### Filter Response Data<\/p>\n<p>&#8220;`php<br \/>\nfunction prepare_task_response($task, $context = &#8216;view&#8217;) {<br \/>\n    $data = [<br \/>\n        &#8216;id&#8217;     => $task->id,<br \/>\n        &#8216;title&#8217;  => $task->title,<br \/>\n        &#8216;status&#8217; => $task->status<br \/>\n    ];<\/p>\n<p>    \/\/ Include extra data only when editing<br \/>\n    if ($context === &#8216;edit&#8217;) {<br \/>\n        $data[&#8216;created_at&#8217;] = $task->created_at;<br \/>\n        $data[&#8216;created_by&#8217;] = $task->created_by;<br \/>\n    }<\/p>\n<p>    return $data;<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>### Pagination<\/p>\n<p>Never return unlimited results:<\/p>\n<p>&#8220;`php<br \/>\n&#8216;args&#8217; => [<br \/>\n    &#8216;per_page&#8217; => [<br \/>\n        &#8216;default&#8217; => 10,<br \/>\n        &#8216;maximum&#8217; => 100,  \/\/ Hard limit<br \/>\n        &#8216;minimum&#8217; => 1<br \/>\n    ]<br \/>\n]<br \/>\n&#8220;`<\/p>\n<p>## Query Optimization<\/p>\n<p>### Use Proper Indexes<\/p>\n<p>&#8220;`sql<br \/>\n&#8212; Add indexes for frequently queried columns<br \/>\nALTER TABLE wp_tasks ADD INDEX status_idx (status);<br \/>\nALTER TABLE wp_tasks ADD INDEX created_by_idx (created_by);<br \/>\nALTER TABLE wp_tasks ADD INDEX created_at_idx (created_at);<br \/>\n&#8220;`<\/p>\n<p>### Avoid N+1 Queries<\/p>\n<p>&#8220;`php<br \/>\n\/\/ \u274c Bad: N+1 queries<br \/>\nfunction get_tasks_with_users_bad() {<br \/>\n    $tasks = $wpdb->get_results(&#8220;SELECT * FROM {$wpdb->prefix}tasks&#8221;);<\/p>\n<p>    foreach ($tasks as &#038;$task) {<br \/>\n        \/\/ One query per task!<br \/>\n        $task->user = get_userdata($task->created_by);<br \/>\n    }<\/p>\n<p>    return $tasks;<br \/>\n}<\/p>\n<p>\/\/ \u2705 Good: Single join query<br \/>\nfunction get_tasks_with_users_good() {<br \/>\n    global $wpdb;<\/p>\n<p>    return $wpdb->get_results(&#8221;<br \/>\n        SELECT t.*, u.display_name as user_name, u.user_email<br \/>\n        FROM {$wpdb->prefix}tasks t<br \/>\n        LEFT JOIN {$wpdb->users} u ON t.created_by = u.ID<br \/>\n        ORDER BY t.created_at DESC<br \/>\n        LIMIT 20<br \/>\n    &#8220;);<br \/>\n}<br \/>\n&#8220;`<\/p>\n<p>## Rate Limiting<\/p>\n<p>Prevent abuse:<\/p>\n<p>&#8220;`php<br \/>\nfunction check_rate_limit(WP_REST_Request $request) {<br \/>\n    $user_id = get_current_user_id();<br \/>\n    $ip = $_SERVER[&#8216;REMOTE_ADDR&#8217;];<br \/>\n    $key = &#8220;rate_limit_{$user_id}_{$ip}&#8221;;<\/p>\n<p>    $requests = get_transient($key) ?: 0;<\/p>\n<p>    if ($requests >= 100) {  \/\/ 100 requests per minute<br \/>\n        return new WP_Error(<br \/>\n            &#8216;rate_limited&#8217;,<br \/>\n            &#8216;Too many requests. Please try again later.&#8217;,<br \/>\n            [&#8216;status&#8217; => 429]<br \/>\n        );<br \/>\n    }<\/p>\n<p>    set_transient($key, $requests + 1, MINUTE_IN_SECONDS);<\/p>\n<p>    return true;<br \/>\n}<\/p>\n<p>\/\/ Apply to endpoint<br \/>\nregister_rest_route(&#8216;myplugin\/v1&#8217;, &#8216;\/expensive-operation&#8217;, [<br \/>\n    &#8216;methods&#8217;             => &#8216;POST&#8217;,<br \/>\n    &#8216;callback&#8217;            => &#8216;do_expensive_operation&#8217;,<br \/>\n    &#8216;permission_callback&#8217; => &#8216;check_rate_limit&#8217;<br \/>\n]);<br \/>\n&#8220;`<\/p>\n<p>## Best Practices Summary<\/p>\n<p>| Practice | Why |<br \/>\n|&#8212;&#8212;&#8212;-|&#8212;&#8211;|<br \/>\n| Use proper HTTP methods | Semantic clarity, caching |<br \/>\n| Return appropriate status codes | Client error handling |<br \/>\n| Validate all input | Security |<br \/>\n| Sanitize output | XSS prevention |<br \/>\n| Paginate collections | Performance |<br \/>\n| Version your API | Backward compatibility |<br \/>\n| Document endpoints | Developer experience |<br \/>\n| Use consistent naming | `snake_case` for JSON keys |<\/p>\n<p>## Security Checklist<\/p>\n<p>&#8220;`php<br \/>\n\/\/ \u2705 Always validate &#038; sanitize<br \/>\n$title = sanitize_text_field($request->get_param(&#8216;title&#8217;));<\/p>\n<p>\/\/ \u2705 Use proper capabilities<br \/>\nif (!current_user_can(&#8216;manage_options&#8217;)) {<br \/>\n    return new WP_Error(&#8216;forbidden&#8217;, &#8216;Access denied&#8217;, [&#8216;status&#8217; => 403]);<br \/>\n}<\/p>\n<p>\/\/ \u2705 Verify ownership<br \/>\nif ($task->created_by !== get_current_user_id()) {<br \/>\n    return new WP_Error(&#8216;forbidden&#8217;, &#8216;Not your task&#8217;, [&#8216;status&#8217; => 403]);<br \/>\n}<\/p>\n<p>\/\/ \u2705 Escape output<br \/>\nreturn [<br \/>\n    &#8216;title&#8217; => esc_html($task->title),<br \/>\n    &#8216;url&#8217;   => esc_url($task->url)<br \/>\n];<br \/>\n&#8220;`<\/p>\n<p>## Monitoring<\/p>\n<p>Log slow queries and errors:<\/p>\n<p>&#8220;`php<br \/>\nadd_action(&#8216;rest_request_after_callbacks&#8217;, function($response, $handler, $request) {<br \/>\n    global $wpdb;<\/p>\n<p>    \/\/ Log slow requests<br \/>\n    $time = timer_stop();<br \/>\n    if ($time > 1.0) {  \/\/ Over 1 second<br \/>\n        error_log(sprintf(<br \/>\n            &#8216;Slow REST API: %s %s took %.2fs&#8217;,<br \/>\n            $request->get_method(),<br \/>\n            $request->get_route(),<br \/>\n            $time<br \/>\n        ));<br \/>\n    }<\/p>\n<p>    \/\/ Log DB query count<br \/>\n    if ($wpdb->num_queries > 50) {<br \/>\n        error_log(sprintf(<br \/>\n            &#8216;High query count: %s had %d queries&#8217;,<br \/>\n            $request->get_route(),<br \/>\n            $wpdb->num_queries<br \/>\n        ));<br \/>\n    }<\/p>\n<p>    return $response;<br \/>\n}, 10, 3);<br \/>\n&#8220;`<\/p>\n<p>## Congratulations!<\/p>\n<p>You&#8217;ve completed the WordPress REST API Mastery tutorial!<\/p>\n<p>### What You&#8217;ve Learned<\/p>\n<p>&#8211; \u2705 REST API architecture and endpoints<br \/>\n&#8211; \u2705 Advanced querying with filters and embedding<br \/>\n&#8211; \u2705 Multiple authentication methods<br \/>\n&#8211; \u2705 Create, Update, Delete operations<br \/>\n&#8211; \u2705 Building custom endpoints<br \/>\n&#8211; \u2705 JavaScript frontend integration<br \/>\n&#8211; \u2705 Performance optimization<\/p>\n<p>### Next Steps<\/p>\n<p>1. **Build a headless app** with Next.js or React<br \/>\n2. **Create a mobile app** using React Native<br \/>\n3. **Integrate external services** like CRMs or email platforms<br \/>\n4. **Build custom Gutenberg blocks** that use the API<\/p>\n<div class=\"callout callout-success\">\n<strong>\ud83c\udfaf Tutorial Complete!<\/strong> You&#8217;re now proficient in the WordPress REST API and can build powerful integrations.\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Optimize API performance with caching, reduce response times, and follow REST API best practices.<\/p>\n","protected":false},"featured_media":0,"template":"","meta":[],"tutorial_series":[],"lesson_level":[],"class_list":["post-330","lesson","type-lesson","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.9 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Performance Optimization &amp; Best Practices - Sanny Srivastava<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/sanny.dev\/tutorials\/wordpress-rest-api-mastery\/performance-optimization-best-practices\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Performance Optimization &amp; Best Practices - Sanny Srivastava\" \/>\n<meta property=\"og:description\" content=\"Optimize API performance with caching, reduce response times, and follow REST API best practices.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/sanny.dev\/tutorials\/wordpress-rest-api-mastery\/performance-optimization-best-practices\/\" \/>\n<meta property=\"og:site_name\" content=\"Sanny Srivastava\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/sanny.dev\/tutorials\/wordpress-rest-api-mastery\/performance-optimization-best-practices\/\",\"url\":\"https:\/\/sanny.dev\/tutorials\/wordpress-rest-api-mastery\/performance-optimization-best-practices\/\",\"name\":\"Performance Optimization & Best Practices - Sanny Srivastava\",\"isPartOf\":{\"@id\":\"https:\/\/sanny.dev\/#website\"},\"datePublished\":\"2026-02-12T06:38:13+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/sanny.dev\/tutorials\/wordpress-rest-api-mastery\/performance-optimization-best-practices\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/sanny.dev\/tutorials\/wordpress-rest-api-mastery\/performance-optimization-best-practices\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/sanny.dev\/tutorials\/wordpress-rest-api-mastery\/performance-optimization-best-practices\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/sanny.dev\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Performance Optimization &#038; Best Practices\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/sanny.dev\/#website\",\"url\":\"https:\/\/sanny.dev\/\",\"name\":\"Sanny Srivastava\",\"description\":\"WordPress Full Stack Developer\",\"publisher\":{\"@id\":\"https:\/\/sanny.dev\/#\/schema\/person\/d6ccd6d5b8e689dd0c0e6c52db9de766\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/sanny.dev\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/sanny.dev\/#\/schema\/person\/d6ccd6d5b8e689dd0c0e6c52db9de766\",\"name\":\"raazsrivastava@gmail.com\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/sanny.dev\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/sanny.dev\/wp-content\/uploads\/2023\/12\/pic.jpeg\",\"contentUrl\":\"https:\/\/sanny.dev\/wp-content\/uploads\/2023\/12\/pic.jpeg\",\"width\":380,\"height\":380,\"caption\":\"raazsrivastava@gmail.com\"},\"logo\":{\"@id\":\"https:\/\/sanny.dev\/#\/schema\/person\/image\/\"},\"sameAs\":[\"https:\/\/sanny.dev\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Performance Optimization & Best Practices - Sanny Srivastava","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/sanny.dev\/tutorials\/wordpress-rest-api-mastery\/performance-optimization-best-practices\/","og_locale":"en_US","og_type":"article","og_title":"Performance Optimization & Best Practices - Sanny Srivastava","og_description":"Optimize API performance with caching, reduce response times, and follow REST API best practices.","og_url":"https:\/\/sanny.dev\/tutorials\/wordpress-rest-api-mastery\/performance-optimization-best-practices\/","og_site_name":"Sanny Srivastava","twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/sanny.dev\/tutorials\/wordpress-rest-api-mastery\/performance-optimization-best-practices\/","url":"https:\/\/sanny.dev\/tutorials\/wordpress-rest-api-mastery\/performance-optimization-best-practices\/","name":"Performance Optimization & Best Practices - Sanny Srivastava","isPartOf":{"@id":"https:\/\/sanny.dev\/#website"},"datePublished":"2026-02-12T06:38:13+00:00","breadcrumb":{"@id":"https:\/\/sanny.dev\/tutorials\/wordpress-rest-api-mastery\/performance-optimization-best-practices\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/sanny.dev\/tutorials\/wordpress-rest-api-mastery\/performance-optimization-best-practices\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/sanny.dev\/tutorials\/wordpress-rest-api-mastery\/performance-optimization-best-practices\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/sanny.dev\/"},{"@type":"ListItem","position":2,"name":"Performance Optimization &#038; Best Practices"}]},{"@type":"WebSite","@id":"https:\/\/sanny.dev\/#website","url":"https:\/\/sanny.dev\/","name":"Sanny Srivastava","description":"WordPress Full Stack Developer","publisher":{"@id":"https:\/\/sanny.dev\/#\/schema\/person\/d6ccd6d5b8e689dd0c0e6c52db9de766"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/sanny.dev\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/sanny.dev\/#\/schema\/person\/d6ccd6d5b8e689dd0c0e6c52db9de766","name":"raazsrivastava@gmail.com","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/sanny.dev\/#\/schema\/person\/image\/","url":"https:\/\/sanny.dev\/wp-content\/uploads\/2023\/12\/pic.jpeg","contentUrl":"https:\/\/sanny.dev\/wp-content\/uploads\/2023\/12\/pic.jpeg","width":380,"height":380,"caption":"raazsrivastava@gmail.com"},"logo":{"@id":"https:\/\/sanny.dev\/#\/schema\/person\/image\/"},"sameAs":["https:\/\/sanny.dev"]}]}},"_links":{"self":[{"href":"https:\/\/sanny.dev\/wp-json\/wp\/v2\/lesson\/330","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sanny.dev\/wp-json\/wp\/v2\/lesson"}],"about":[{"href":"https:\/\/sanny.dev\/wp-json\/wp\/v2\/types\/lesson"}],"wp:attachment":[{"href":"https:\/\/sanny.dev\/wp-json\/wp\/v2\/media?parent=330"}],"wp:term":[{"taxonomy":"tutorial_series","embeddable":true,"href":"https:\/\/sanny.dev\/wp-json\/wp\/v2\/tutorial_series?post=330"},{"taxonomy":"lesson_level","embeddable":true,"href":"https:\/\/sanny.dev\/wp-json\/wp\/v2\/lesson_level?post=330"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}