WordPress REST API and WPGraphQL can both expose WordPress data to headless websites, mobile apps, automation systems, static-site generators and external services.
The WordPress REST API is built into WordPress core and exposes resource-oriented HTTP endpoints. WPGraphQL is an additional open-source WordPress plugin that exposes an extendable GraphQL schema and endpoint.
Neither is universally faster, more secure, or better for headless WordPress.
The right choice depends on:
- Content relationships.
- Client requirements.
- Authentication.
- Authorization.
- Caching.
- Payload shape.
- Backend execution cost.
- Developer tooling.
- Operational complexity.
This article is based on current WordPress 7.1.x REST API and Application Password documentation plus current WPGraphQL security, authentication, query, mutation and caching documentation. It is not a controlled Digital Bhatti REST-vs-WPGraphQL benchmark. The equivalent-request examples below are a reproducible methodology; performance conclusions require measured runs on the actual WordPress stack.
Last verified: September 24, 2026. WordPress, WPGraphQL, authentication integrations, frontend frameworks and API behavior can change; recheck current documentation before production implementation.
WordPress: 7.1.2 is the current release verified here. It was published September 22, 2026 as a security release.
WPGraphQL: WordPress.org currently lists 2.23.1. That release includes a media-item authorization security fix; keep WPGraphQL and related extensions updated and regression-test schema/auth behavior after changes.
Compatibility note: the plugin directory currently says WordPress 6.0+ / PHP 7.4+ and “Tested up to 7.0.6.” That metadata does not prove WordPress 7.1.2 is incompatible, but it is a reason to stage-test the exact WordPress, WPGraphQL and extension versions you plan to deploy.
Match the API to the Data Shape, Cache Model and Client Workflow
WordPress REST is built into core and works naturally for resource-oriented endpoints and many integrations. WPGraphQL adds a typed schema and flexible nested queries that can fit relationship-heavy frontends. Compare equivalent requests, authentication, caching and backend execution before choosing on performance grounds.
Choose the Data Requirement Before Choosing REST or GraphQL
If a client needs a straightforward list of posts, a core REST endpoint may be sufficient. If a headless page needs deeply related content with different field selections across several interfaces, WPGraphQL may produce a cleaner client data model. Measure the complete request path instead of selecting an API because of generic performance claims.
1. WordPress REST API vs WPGraphQL at a Glance
| Area | WordPress REST API | WPGraphQL |
|---|---|---|
| Availability | WordPress core | Additional WordPress plugin |
| API model | Resource-oriented HTTP endpoints | Typed GraphQL schema |
| Field selection | Supports field reduction with _fields |
Client selects fields in query |
| Related data | Links and _embed where supported |
Nested relationships through schema |
| Schema tooling | Route discovery and endpoint schemas | Strong typed-schema tooling |
| Additional dependency | No additional API plugin needed | WPGraphQL must be installed and maintained |
| Common fit | Automation, straightforward integrations, resource APIs | Complex headless interfaces and related content graphs |
2. Equivalent REST and WPGraphQL Requests for the Same Page
A fair comparison starts with one identical business requirement. This guide uses:
REST request
WordPress REST can combine _fields and _embed so the response is narrowed while supported related resources are embedded:
GET /wp-json/wp/v2/posts?per_page=20&status=publish&_embed=author,wp:featuredmedia,wp:term&_fields=id,link,title,_links,_embedded
The client reads the post URL/title directly and normalizes author, featured-media and taxonomy data from _embedded. WordPress requires _links and _embedded to remain in _fields when those embedded relationships are needed.
WPGraphQL query
query EquivalentPosts($first: Int!) {
posts(first: $first, where: { status: PUBLISH }) {
nodes {
databaseId
uri
title
author {
node {
name
}
}
featuredImage {
node {
sourceUrl
}
}
categories {
nodes {
name
}
}
}
}
}
Variables:
{
"first": 20
}
These examples are functionally comparable, not byte-for-byte identical. REST and GraphQL serialize relationships differently, and custom themes/plugins can alter the data model. Verify that both outputs contain the same business information before timing them.
3. What Is the WordPress REST API?
The WordPress REST API provides HTTP endpoints for interacting with WordPress resources.
Common core routes include:
/wp-json/wp/v2/posts
/wp-json/wp/v2/pages
/wp-json/wp/v2/media
/wp-json/wp/v2/categories
/wp-json/wp/v2/tags
/wp-json/wp/v2/users
A remote application capable of making HTTP requests can use the API when the requested endpoint and permissions allow it.
4. WordPress REST Uses a Resource-Oriented Model
For example:
GET /wp-json/wp/v2/posts/42
requests a specific post resource.
A collection request:
GET /wp-json/wp/v2/posts
returns a paginated collection.
5. REST Can Create and Update Content
An authenticated user with the required WordPress capabilities can create or modify content through supported endpoints.
Conceptually:
POST /wp-json/wp/v2/posts
{
"title": "API-created article",
"status": "draft"
}
Authentication does not automatically grant authorization. The WordPress user still needs the capability required for the operation.
6. Public REST Data Is Not Automatically a Vulnerability
Public WordPress content is intentionally accessible through many REST endpoints.
If a published article is already available to every visitor, exposing its public title and content as JSON is not by itself evidence of a security breach.
The important security question is:
Can an unauthenticated or insufficiently privileged requester access information or perform actions they should not be allowed to access?
7. Do Not Disable the Entire REST API as Generic Hardening
Modern WordPress functionality can rely on REST APIs.
Global blocking can interfere with:
- Block Editor features.
- Plugin interfaces.
- Custom administrative applications.
- Mobile clients.
- Headless websites.
- External integrations.
Restrict sensitive functionality based on actual authorization requirements instead of treating the existence of /wp-json/ as a vulnerability.
For application-level hardening, use the WordPress Security Hardening Guide.
8. REST Authentication: Cookie + Nonce
For requests made within a logged-in WordPress browser session, cookie authentication is the standard built-in model.
REST requests also use a nonce for CSRF protection.
The nonce can be passed using:
X-WP-Nonce: <nonce>
The user must still have the appropriate WordPress capability.
9. Application Passwords for Remote Integrations
WordPress has included Application Passwords since WordPress 5.6. They are separate, revocable credentials associated with a WordPress user and can be individually created or revoked without changing that user's normal login password.
WordPress supports them for remote HTTPS authentication, commonly via HTTP Basic Authentication.
They are useful for:
- Server-to-server integrations.
- Automation scripts.
- External publishing tools.
- CI/CD processes.
- Headless services that need authenticated WordPress access.
Do not place Application Passwords in browser-delivered JavaScript.
A server-to-server REST verification example is:
curl --user "USERNAME:APPLICATION_PASSWORD" https://example.com/wp-json/wp/v2/users/me
Use HTTPS. Create a separate Application Password per integration where practical, store it as a secret, and revoke it when that integration no longer needs access.
10. Application Passwords Are Not Your WordPress Login Password
An Application Password is generated separately for an application or integration.
This is useful because individual application credentials can be revoked without changing the user's normal WordPress account password.
Create separate credentials for separate integrations where practical so revocation and auditing are easier.
11. REST Can Select Fields With _fields
A common oversimplification is that REST always returns a large fixed object while only GraphQL can request selected fields.
WordPress REST supports the global _fields parameter.
For example:
/wp-json/wp/v2/posts?_fields=id,slug,title
This can reduce response fields when a client needs only a subset of the resource.
WordPress documentation also notes that _fields can avoid generating unneeded response fields, reducing response size and potentially skipping internal work for fields the client did not request. Nested properties are supported too.
That means “GraphQL can select fields but REST cannot” is not an accurate WordPress comparison. The stronger distinction is that GraphQL makes arbitrary client-defined field selection part of the query language, whereas REST narrows a predefined resource representation.
12. REST Can Embed Related Resources
WordPress REST also supports linked-resource embedding through _embed where the relationship is embeddable.
For example:
/wp-json/wp/v2/posts?_embed=author,wp:term
This can reduce additional requests for related content such as authors or taxonomy terms.
When combining _embed with _fields, include the relevant _links and _embedded fields so the embedded data is not filtered out.
GraphQL still provides a more general nested query model, but “REST always requires one request per relationship” is not accurate for WordPress.
13. REST Collection Pagination
Large content collections should be paginated.
WordPress REST supports parameters such as:
?page=2
?per_page=20
?offset=40
Current core REST documentation caps per_page at 100 records.
Collection responses also provide headers including:
X-WP-TotalX-WP-TotalPages
Use pagination rather than attempting to fetch an entire large content inventory in one response.
14. What Is GraphQL?
GraphQL itself is a query language and runtime model for APIs. It is not built into WordPress core. In the WordPress ecosystem, WPGraphQL is the plugin that implements a GraphQL schema and endpoint for WordPress data.
GraphQL APIs expose a typed schema consisting of types, fields, queries, relationships, and mutations.
The client describes the shape of the data it wants.
For example:
query {
posts {
nodes {
id
title
}
}
}
15. WPGraphQL Adds GraphQL to WordPress
WordPress core does not currently expose GraphQL as its built-in primary content API.
WPGraphQL is a separate free, open-source WordPress plugin that adds an extendable GraphQL schema and API.
At this article's verification date, WordPress.org lists WPGraphQL 2.23.1. Its changelog includes a security fix tightening updateMediaItem authorization. A September advisory also patched authenticated createMediaItem SSRF in 2.22.3. Keep the plugin current rather than treating the API layer as “set and forget.”
This distinction matters operationally because WPGraphQL becomes another application component that must be:
- Installed.
- Updated.
- Tested.
- Considered during compatibility changes.
16. GraphQL's Strongest Advantage Is Often Data Composition
Suppose a page needs:
- Post title.
- Author name.
- Featured image.
- Categories.
- Related custom fields.
A GraphQL query can request those connected fields in one structured document when the relationships exist in the schema.
That can make frontend data requirements easier to express.
17. Client-Selected Fields
A listing component might request:
post {
title
uri
}
while the full article view might request:
post {
title
content
date
author {
node {
name
}
}
}
This lets each client component define its required data shape.
18. GraphQL Introspection Needs Current WPGraphQL Context
GraphQL supports schema introspection as a general capability, but do not state that every public WPGraphQL endpoint automatically exposes its complete schema.
Current WPGraphQL security documentation states that public schema introspection is disabled by default.
Administrators can enable it when their development workflow requires it.
This is an important correction to older tutorials that assume public introspection is always available.
19. WPGraphQL Still Supports Schema-Aware Developer Tooling
WPGraphQL provides schema-oriented development tooling for authenticated development workflows.
This can improve:
- Query discovery.
- Type information.
- Validation.
- Autocompletion.
- Frontend type generation.
This developer experience is one of GraphQL's strongest advantages for complex headless applications.
20. WPGraphQL Authentication Builds on WordPress
WPGraphQL authentication builds on WordPress authentication context and compatible authentication methods or plugins rather than replacing WordPress's user/capability system.
Current WPGraphQL documentation describes approaches including:
- Cookie authentication + nonce for appropriate logged-in browser contexts.
- WordPress Application Passwords.
- JWT through an appropriate authentication plugin.
- Other supported WordPress authentication integrations.
For server-to-server and automated integrations, Application Passwords provide a built-in WordPress starting point. Current WPGraphQL documentation recommends Application Passwords for server-to-server use cases.
The same WordPress Application Password can authenticate an appropriate WPGraphQL request over HTTPS:
curl --user "USERNAME:APPLICATION_PASSWORD" -H 'Content-Type: application/json' --data '{"query":"query { viewer { databaseId name } }"}' https://example.com/graphql
Use a user account with only the capabilities the integration actually needs. Authentication identifies the WordPress user; authorization/capability checks still decide which fields or mutations can succeed.
21. Authentication and Authorization Are Different
Authentication answers:
“Who is making this request?”
Authorization answers:
“What is this user allowed to read or change?”
Both REST and WPGraphQL rely on WordPress's permissions and capability model for protected operations.
22. WPGraphQL Protects Private Fields and Mutations
Current WPGraphQL documentation describes field-level access controls and capability checks.
For example:
- Public content can remain publicly queryable.
- Private fields can resolve only for appropriately authenticated users.
- Mutations check WordPress permissions before creating or modifying content.
GraphQL is not inherently an authorization bypass.
Current WPGraphQL security documentation also distinguishes cookie-authenticated requests from requests carrying an Authorization header. Cookie-authenticated requests should carry a valid WordPress nonce; an invalid nonce fails with HTTP 403, while a request with no nonce is treated as a guest/unauthenticated context.
Authentication Identifies the User; Authorization Still Decides the Action
For both REST and WPGraphQL, valid credentials do not imply permission to every resource or mutation. Preserve WordPress capability checks, expose only the fields/actions the client needs, and keep privileged credentials on trusted server-side components.
23. Neither REST Nor GraphQL Is Inherently “More Secure”
Security depends on implementation.
Review:
- Authentication.
- Authorization.
- Capabilities.
- Public vs private fields.
- Custom endpoints.
- Custom resolvers.
- Rate limits.
- Query limits.
- Secret handling.
Choosing GraphQL instead of REST does not automatically make a site safer, and choosing REST does not automatically reduce the attack surface enough to replace access-control review.
24. Over-Fetching: Use More Precise Language
GraphQL can reduce unnecessary response fields because the client specifies the fields it needs.
But WordPress REST can also reduce response size using _fields.
Therefore the accurate comparison is:
GraphQL makes client-defined response shapes a central part of its query model, while WordPress REST provides resource responses that can also be narrowed with supported parameters.
25. Under-Fetching Is Also Nuanced
A REST application may need several related resource requests.
For example:
GET post
GET author
GET media
GET categories
However, WordPress REST _embed can combine supported related resources into a response.
GraphQL can express more complex nested data relationships through one query when the schema supports them.
26. One GraphQL Request Does Not Mean One Backend Query
This is one of the most important performance distinctions:
1 HTTP GraphQL Request
≠
1 Database Query
Each requested field can trigger resolver logic, WordPress object access, plugin code, database work, and cache lookups.
HTTP request count is therefore not a complete performance benchmark.
27. GraphQL Query Size Needs Limits
A flexible query system must still protect the backend from unreasonable requests.
Current WPGraphQL documentation states that connection queries are limited to 100 nodes by default unless the limit is explicitly changed.
Do not raise query limits simply because a frontend wants to download thousands of posts in one operation.
Instead use:
- Pagination.
- Reasonable query shapes.
- Caching.
- Build-time batching.
28. Large REST Collections Need Limits Too
The same principle applies to REST.
WordPress caps normal per_page collection requests at 100.
If you need a full content export, fetch pages incrementally rather than turning an interactive API request into an unbounded database export.
29. REST Caching Is Often Straightforward at the HTTP Layer
A public resource can map to a distinct URL such as:
GET /wp-json/wp/v2/posts/42
This can make conventional HTTP/CDN cache keys easier to reason about for public read-heavy endpoints because the resource identity and query parameters live in the URL.
That does not mean WordPress core automatically provides an optimal edge-cache policy for every REST response. Cacheability still depends on response headers, authentication, cookies, proxy/CDN rules and invalidation design.
Authenticated and personalized responses need more careful treatment and should not be dropped into a shared cache merely because the HTTP method is GET.
30. WPGraphQL Caching Uses a Different Model
GraphQL caching is not limited to one approach. WPGraphQL supports GET for read-only queries and POST for queries and mutations:
- GET queries can participate in normal CDN/reverse-proxy caching when the cache key includes the query and variables correctly; URL-length limits still apply.
- POST queries are common for GraphQL clients but do not benefit from simple URL-only network caching in the same way.
- Mutations require POST.
WPGraphQL can also use application caching, persistent object caching, client normalized caches and specialized cache layers such as WPGraphQL Smart Cache.
The important comparison is not “REST caches, GraphQL does not.” It is that REST resource URLs often map naturally to conventional HTTP caches, while GraphQL caching depends more heavily on how queries are transported and keyed.
Persisted-query strategies can also make GraphQL requests more cache-friendly and operationally controlled, but they add implementation complexity and should be evaluated against the needs of the actual frontend.
WPGraphQL Smart Cache can add network- and object-cache strategies, but it is an additional component. Its documented network-cache path uses public GraphQL GET requests and requires compatible hosting/cache infrastructure capable of tagging and purging responses. The current documentation lists a default network-cache max age of 600 seconds, but host behavior can differ.
Its object-cache mode can cache unauthenticated GraphQL query results for both GET and POST requests using a persistent object cache (or transients as fallback). Do not assume a normal WordPress page cache automatically understands GraphQL POST responses or invalidates them correctly.
31. WordPress Object Caching Can Help Both
REST and WPGraphQL ultimately execute inside WordPress.
A persistent object cache may reduce repeated database work where requests repeatedly access cacheable WordPress objects.
Continue with the Redis vs Memcached Object Caching Guide.
32. Validate Cache Keys and Invalidation, Not Just “HIT”
A cache test must prove that different requests do not collapse onto the same cached document and that content changes invalidate the right response.
For REST, vary a real resource/query parameter such as:
/wp-json/wp/v2/posts?per_page=10&page=1&_fields=id,title
/wp-json/wp/v2/posts?per_page=10&page=2&_fields=id,title
Verify the cache layer distinguishes the two URLs and that publishing/updating content produces the invalidation behavior your frontend expects.
For WPGraphQL GET caching, the cache key must distinguish the GraphQL query and variables. WPGraphQL Smart Cache additionally uses query-derived cache tags for invalidation on compatible hosts. A “HIT” header alone is not enough if different variable sets or content updates can return stale/wrong data.
Never share-cache authenticated preview, draft or user-specific API responses unless the cache is explicitly designed to partition and protect that identity/context.
33. API Requests Still Consume PHP Capacity
On a PHP-FPM stack, REST and GraphQL requests still consume PHP worker capacity.
A headless frontend generating many simultaneous uncached requests can contribute to:
- Worker saturation.
- Queueing.
- Higher TTFB.
- 502/504 failures under pressure.
Use the PHP-FPM Tuning Guide for worker-capacity diagnosis.
34. Headless WordPress Architecture
In a headless architecture, WordPress primarily manages content while another application renders the public frontend.
WordPress CMS
↓
REST / WPGraphQL
↓
Frontend Application
↓
Browser
This can provide significant frontend flexibility, but it also creates another application and deployment layer.
35. Headless Does Not Automatically Mean Faster
A headless site can still be slow because of:
- Slow WordPress APIs.
- Uncached server rendering.
- Large JavaScript bundles.
- Slow image delivery.
- Excess client-side hydration.
- Weak cache invalidation.
A well-cached conventional WordPress page can outperform a poorly designed headless application.
For regression control on the frontend layer, use the Web Performance Budgets & Regression Monitoring Guide.
36. Static Generation Changes the API Load Pattern
A statically generated frontend can fetch WordPress content during builds rather than during every visitor request.
This can reduce runtime WordPress API traffic for mostly static sites.
But it introduces new concerns:
- Build duration.
- Preview workflows.
- Content-change triggers.
- Incremental regeneration.
- Cache invalidation.
37. Server-Side Rendering Puts the API in the Request Path
In server-side rendering, frontend servers may fetch WordPress during page generation.
The chain becomes:
Visitor
↓
Frontend Server
↓
WordPress API
↓
Database / Cache
↓
Frontend HTML
↓
Visitor
WordPress API latency can therefore contribute directly to page TTFB.
Use the TTFB Optimization Guide for backend response-time diagnosis.
38. Core Web Vitals Depend on the Final Frontend
REST vs GraphQL does not automatically determine:
- LCP.
- INP.
- CLS.
The frontend can still have:
- Oversized hero images.
- Render-blocking resources.
- Large JavaScript bundles.
- Poor font loading.
- Layout instability.
Use the Core Web Vitals Guide to diagnose the actual browser bottleneck.
39. Preview and Draft Content Need an Authenticated Path
Headless editorial workflows often need to preview draft, private or scheduled content before publication.
Design this separately from the public content path:
- Authenticate the preview request.
- Preserve WordPress capability checks.
- Keep preview tokens or Application Passwords server-side.
- Avoid exposing draft/private fields to anonymous clients.
- Test cache bypass behavior so draft content is not accidentally served publicly.
Both REST and WPGraphQL can participate in preview workflows, but the frontend must deliberately handle authentication, authorization and caching.
Recent WPGraphQL 2.x releases also added request-level preview context support, but that does not remove the need for authentication/capability checks or private-cache isolation. Test the exact preview implementation used by your frontend.
40. Custom Post Types Need Explicit API Design
Do not assume every custom post type automatically appears in either API exactly as your frontend needs it.
Review:
- REST exposure.
- GraphQL exposure.
- Capabilities.
- Visibility.
- Schema names.
- Relationships.
41. Custom Fields Need the Same Review
Headless sites often depend heavily on custom fields.
Before selecting REST or GraphQL, verify how your WordPress plugins expose:
- Simple scalar fields.
- Media.
- Relationships.
- Repeaters.
- Flexible layouts.
- Taxonomy references.
The best API model depends partly on the actual content model.
Extension security matters too. For example, WPGraphQL for ACF patched a September 2026 issue in version 3.0.0 involving PHP-registered ACF Options Pages being exposed without an explicit GraphQL opt-in. If your schema depends on ACF or another extension, track and test that extension separately from WPGraphQL core.
42. WooCommerce Adds Another Compatibility Layer
For headless WooCommerce, do not assume that choosing REST or WPGraphQL automatically gives complete coverage of products, carts, checkout, customers, orders and extensions.
Evaluate:
- Which WooCommerce APIs or GraphQL extensions expose the data you need.
- Authenticated customer/session behavior.
- Cart and checkout flows.
- Plugin/extension compatibility.
- Webhook/event integrations.
- Cache invalidation when inventory or pricing changes.
For back-office workflow integration, the WooCommerce Multichannel Automation Guide covers REST API, webhook, inventory and order-sync architecture.
43. CORS Is Not an Authentication Mechanism
A headless application can run on another origin from WordPress and therefore require deliberate cross-origin configuration.
Do not solve every integration problem by adding:
Access-Control-Allow-Origin: *
without understanding whether credentials or protected operations are involved.
CORS controls browser cross-origin behavior; it does not replace WordPress authentication or authorization.
44. Never Put Privileged Secrets in Frontend JavaScript
A browser bundle can be downloaded and inspected.
Never expose:
- WordPress Application Passwords.
- Administrator credentials.
- Private API keys.
- Database passwords.
- Server tokens.
If a privileged WordPress request is required, route it through an appropriate trusted server-side component.
45. Add Abuse Controls Around Public APIs
Public APIs need operational controls regardless of whether they use REST or GraphQL.
Depending on the architecture, consider:
- Rate limiting at the CDN, reverse proxy or application layer.
- Query-depth/complexity controls for GraphQL.
- Reasonable pagination limits.
- Authentication throttling.
- Request logging and anomaly monitoring.
- Origin/CORS rules appropriate to browser clients.
For WordPress security controls outside the API layer, see the Website Security Checklist.
46. REST Is Usually the Simpler Starting Point
Start with WordPress REST when:
- Core routes already expose what you need.
- The application performs straightforward CRUD-style operations.
- You are integrating automation systems.
- You want to minimize extra WordPress dependencies.
- Conventional HTTP resource caching is useful.
47. WPGraphQL Is Strong When Relationships Dominate
Evaluate WPGraphQL when:
- The frontend assembles many connected content types.
- Different clients need different field selections.
- A typed schema improves development workflow.
- The team benefits from GraphQL tooling and generated types.
- The application already uses GraphQL extensively.
48. You Can Use REST and GraphQL Together
A WordPress site does not need architectural purity.
For example:
Headless Frontend → WPGraphQL
n8n Automation → WordPress REST API
WordPress Admin → Core WordPress APIs
Choose the most appropriate interface for each integration.
49. n8n and WordPress Usually Fit REST Naturally
For workflow automation such as:
- Creating draft posts.
- Updating metadata.
- Retrieving content.
- Triggering publishing workflows.
the core WordPress REST API plus an appropriate authentication method is often a straightforward starting point.
For automation architecture, use the Web Automation Guide.
If the API is being used behind an AI assistant or automated support workflow, keep authentication and privileged WordPress actions server-side; the Automated AI Chatbot Guide covers that trust boundary.
For n8n deployment, use the Self-Hosted n8n Docker Guide.
50. Measure Equivalent Payloads Before Discussing Performance
For the 20-post requirement above, measure both APIs under the same environment and cache state. Do not compare a full REST resource against a minimal GraphQL selection or vice versa.
REST example:
curl --compressed -sS -o rest.json -w 'REST status=%{http_code} transfer=%{size_download} time=%{time_total}
' 'https://example.com/wp-json/wp/v2/posts?per_page=20&status=publish&_embed=author,wp:featuredmedia,wp:term&_fields=id,link,title,_links,_embedded'
wc -c rest.json
For WPGraphQL, save the equivalent query/variables as a JSON request body, then:
curl --compressed -sS -H 'Content-Type: application/json' --data @graphql-request.json -o graphql.json -w 'GraphQL status=%{http_code} transfer=%{size_download} time=%{time_total}
' https://example.com/graphql
wc -c graphql.json
size_download records transfer bytes reported by curl for that request, while wc -c records the saved response-body size. Keep compression, network path and cache state consistent. If the API returns headers/metadata or JSON shapes that are not semantically equivalent, normalize the requirement before interpreting the numbers.
Run repeated cold-cache and warm-cache samples separately. Report a median and a tail statistic such as p95 rather than selecting the single fastest request.
51. API Performance Needs Representative Testing
Do not benchmark:
one REST request against one unrelated GraphQL query
and declare a winner.
A meaningful comparison should use the same business requirement and measure:
- Payload size.
- HTTP request count.
- PHP execution time.
- Database activity.
- Cache behavior.
- Server response time.
- Network latency.
- Frontend processing.
52. Example Fair Benchmark Methodology (If You Test It)
If you later test this for Digital Bhatti, use one identical content requirement.
For example:
Retrieve 20 posts with title, URL, author name, category names and featured image URL.
Then compare:
| Metric | REST | GraphQL |
|---|---|---|
| Cold-cache response time | Measure | Measure |
| Warm-cache response time | Measure | Measure |
| Transferred bytes | Measure | Measure |
| Decoded JSON body bytes | Measure | Measure |
| HTTP request count for the business requirement | Measure | Measure |
| Database queries | Measure | Measure |
| PHP memory | Measure | Measure |
Do not fill this table with invented measurements. Record WordPress version, WPGraphQL version, PHP/database versions, active plugins/theme, object cache, HTTP/edge cache, test location, TLS/network path, query/request text, number of repetitions and whether each sample was cold or warm.
53. REST vs GraphQL Decision Matrix
| Requirement | Likely Starting Point |
|---|---|
| Simple posts/pages integration | WordPress REST API |
| n8n or external automation | WordPress REST API |
| Complex nested headless content | Evaluate WPGraphQL |
| Typed schema/tooling important | WPGraphQL |
| Fewest additional plugins | WordPress REST API |
| Different frontend clients need different data shapes | WPGraphQL worth evaluating |
| Simple CDN cache by resource URL | REST often simpler |
| Static-generation content site | Either; choose by data model and build workflow |
| Authenticated editorial preview | Either; design auth/caching carefully |
| Mobile app with varied related data | WPGraphQL worth evaluating |
| Internal CRUD/admin integration | REST often simpler |
| Headless WooCommerce | Evaluate API/extension coverage before choosing |
54. Headless WordPress Evaluation Workflow
- Define the actual frontend requirements.
- Map posts, pages, taxonomies and custom fields.
- Identify required relationships.
- Separate public and authenticated data.
- Define one identical business data requirement.
- Prototype the equivalent REST request.
- Prototype the equivalent WPGraphQL query.
- Verify both responses contain semantically equivalent data.
- Design pagination.
- Design caching and invalidation.
- Verify cache keys distinguish query parameters/GraphQL variables.
- Measure backend execution.
- Measure transferred and decoded payload size separately.
- Test authorization.
- Test preview/editor workflows.
- Load-test representative production queries.
- Monitor API latency after launch.
55. Common REST vs GraphQL Mistakes
- “GraphQL is always faster”: unsupported without workload-specific measurement.
- Comparing non-equivalent requests: both APIs must return the same business data before response time or payload size means anything.
- “REST always over-fetches”: WordPress REST supports
_fields. - “REST always needs many requests”: WordPress REST supports
_embedfor supported relationships. - “One GraphQL request means one DB query”: resolver execution can involve substantial backend work.
- “GraphQL introspection is always public”: current WPGraphQL disables public introspection by default.
- Disabling the entire REST API for security: can break legitimate WordPress functionality.
- Exposing Application Passwords in JavaScript: browser-delivered secrets are not secrets.
- Using permissive CORS as an authentication fix: CORS and authorization solve different problems.
- Fetching thousands of items in one request: paginate both APIs.
- Ignoring PHP worker capacity: headless API traffic still consumes backend resources.
- Assuming headless automatically improves CWV: the final frontend still determines browser performance.
- Treating GET as automatically cache-safe: shared caching still depends on headers, identity, cookies, variables/query parameters and invalidation.
- Putting Application Passwords in frontend code: keep privileged credentials on trusted server-side components.
- Running stale WPGraphQL/extensions: API plugins and schema extensions receive security fixes too.
- Changing the schema without client testing: API changes can break frontend applications.
56. Related Digital Bhatti Guides
- WordPress security: WordPress Security Hardening.
- Website security architecture: Website Security Checklist.
- WooCommerce API automation: WooCommerce Multichannel Automation.
- AI workflow trust boundary: Automated AI Chatbot.
- Performance regression control: Web Performance Budgets.
- n8n integration: Self-Hosted n8n with Docker.
- Object caching: Redis vs Memcached.
- PHP capacity: PHP-FPM Tuning.
- Server latency: TTFB Optimization.
- Frontend performance: Core Web Vitals.
WordPress REST API vs GraphQL Checklist
- Record the current WordPress, WPGraphQL and relevant extension versions.
- Start with the application's data requirements.
- Build equivalent REST and WPGraphQL requests before benchmarking.
- Remember that REST is built into WordPress core.
- Remember that WPGraphQL is an additional plugin/API layer.
- Use REST
_fieldswhen only selected fields are needed. - Use REST
_embedwhen supported related resources are needed. - Paginate REST collections.
- Paginate GraphQL connections.
- Do not allow unnecessarily large queries.
- Use cookie + nonce authentication in appropriate WordPress browser contexts.
- Consider Application Passwords for suitable HTTPS server-to-server integrations.
- Keep privileged credentials out of browser JavaScript.
- Preserve WordPress capability checks.
- Do not disable the complete REST API blindly.
- Remember that public WPGraphQL introspection is currently disabled by default.
- Do not assume one GraphQL request equals less server work.
- Design caching according to the API model.
- Verify cache keys and invalidation with changed parameters/variables and content updates.
- Measure transferred bytes, decoded JSON size, request count, PHP and database work separately.
- Test authenticated and unauthenticated access separately.
- Review custom post type and custom-field exposure.
- Test schema changes against clients.
- Do not assume headless architecture improves performance automatically.
Secure WordPress Before Exposing Authenticated API Operations
After choosing REST or WPGraphQL, review administrator accounts, Application Passwords, REST permissions, XML-RPC, plugins, themes and WordPress configuration as a separate security layer.
Open WordPress Security Guide →Frequently Asked Questions
Can WPGraphQL queries use GET requests?
Yes. WPGraphQL supports GET for queries, which can participate in CDN or reverse-proxy caching when the cache key includes the query correctly. POST is still required for mutations and is also commonly used for queries.
What is the default WPGraphQL connection limit?
Current WPGraphQL documentation states that connection queries are limited to 100 nodes by default. Use cursor-based pagination rather than raising the limit simply to fetch very large datasets in one request.
Is GraphQL itself a WordPress plugin?
No. GraphQL is a query language/runtime model for APIs. WPGraphQL is the WordPress plugin that implements a GraphQL schema and endpoint for WordPress data.
Is GraphQL faster than the WordPress REST API?
Not universally. GraphQL can reduce unnecessary response fields and make related data easier to request, but complex GraphQL queries can still require significant resolver, PHP and database work. Benchmark the same business requirement on the actual stack.
Is the WordPress REST API part of WordPress core?
Yes. WordPress core includes the REST API and standard endpoints for posts, pages, media, taxonomies, users and other resources.
Is GraphQL built into WordPress core?
No. WPGraphQL is an additional open-source WordPress plugin that adds a GraphQL schema and API.
Does WordPress REST always over-fetch?
No. WordPress REST supports the _fields parameter, which lets clients request a subset of response fields.
Can WordPress REST include related content?
Yes. Supported relationships can be embedded using the _embed parameter, which can reduce additional requests for resources such as authors or taxonomy terms.
How many posts can WordPress REST return per page?
Current WordPress REST documentation caps the normal per_page parameter at 100 records. Larger collections should be retrieved through pagination.
Is WPGraphQL schema introspection publicly enabled by default?
No. Current WPGraphQL documentation states that public schema introspection is disabled by default. Administrators can enable it when required.
Does WPGraphQL respect WordPress permissions?
Yes. Current WPGraphQL documentation describes authorization based on WordPress users, capabilities and field-level access controls. Protected mutations and private fields require appropriate permission.
Should I disable the WordPress REST API for security?
Usually not globally. WordPress core features, plugins and integrations can depend on REST. Restrict sensitive operations through authentication, capabilities and endpoint-specific controls instead.
What should I use for remote REST authentication?
For suitable server-to-server integrations, WordPress Application Passwords provide a built-in option and should be used over HTTPS. Other authentication methods can be added when the architecture requires them.
Can WPGraphQL use WordPress Application Passwords?
Yes. Current WPGraphQL documentation lists WordPress Application Passwords as an option for remote and server-to-server authentication. Exact behavior can depend on the surrounding authentication setup, so test the integration and keep credentials server-side.
Which API is better for n8n?
The WordPress REST API is often the simpler starting point for n8n workflows that create, retrieve or update standard WordPress resources. WPGraphQL can still be used when a workflow benefits from its query model.
Which API is better for headless WordPress?
REST is often sufficient for straightforward resource-oriented applications. WPGraphQL becomes especially useful when the frontend has complex relationships, multiple data shapes or strong typed-schema tooling requirements.
Can REST and GraphQL be used together?
Yes. A headless frontend can use WPGraphQL while automation scripts use the WordPress REST API. There is no requirement to use only one interface across every integration.
Does headless WordPress automatically improve Core Web Vitals?
No. Core Web Vitals still depend on the final frontend's server response, JavaScript, CSS, images, fonts and layout behavior.
What WordPress and WPGraphQL versions were current for this update?
This article was verified on September 24, 2026 against WordPress 7.1.2 and the WordPress.org WPGraphQL listing for 2.23.1. Check current release notes before deploying because both core and the plugin can receive security and compatibility updates.
Can REST and WPGraphQL use the same WordPress Application Password?
Yes, for an appropriate WordPress user/integration. Application Passwords are WordPress credentials and can authenticate supported server-to-server REST or WPGraphQL requests over HTTPS. The user's WordPress capabilities still limit what the request may read or change.
How should I compare REST and GraphQL response size?
First make the business requirement equivalent, then measure both transferred bytes and decoded JSON body size under the same compression and cache conditions. A smaller response does not automatically mean lower PHP, resolver or database cost.
Is a GraphQL GET request automatically cached?
No. GET makes URL-based caching possible, but actual caching depends on response headers and the CDN/reverse-proxy implementation. WPGraphQL Smart Cache adds query tagging and invalidation for compatible network-cache environments; it is not automatic on every host.
Abdul Shakoor
Founder of Digital Bhatti, an independent technical publication focused on web hosting and infrastructure, WordPress, technical SEO, web performance and automation.
This guide is documentation-led. It does not claim a Digital Bhatti REST-vs-WPGraphQL latency, payload, database-query or scalability benchmark unless the exact requests, environment, raw runs and cache state are explicitly published.