PUT vs PATCH: The Ultimate Guide to HTTP Update Semantics

In the world of RESTful services and modern APIs, two verbs dominate the landscape when you need to modify resources: PUT and PATCH. Developers often wrestle with which to choose, how they behave, and what guarantees they offer in real-world applications. This guide delves into the nuances of PUT vs PATCH, clarifying their semantics, practical use cases, and the design considerations that help teams build robust, maintainable APIs. Whether you’re designing a brand-new endpoint or refactoring an existing one, understanding PUT vs PATCH will save you time, reduce bugs, and improve the experience for both developers and users.
PUT vs PATCH: Core Differences in Semantics
At a high level, PUT and PATCH are both ways to send updates to a resource, but they represent different approaches to updating that resource. The key distinction is about replacement versus modification:
- PUT is typically interpreted as a complete replacement of the resource. You send the full representation of the resource, and the server replaces the existing resource with that representation. If the resource does not exist, a well-designed API may create it.
- PATCH is designed for partial updates. You send only the changes you want to apply, rather than the entire resource. PATCH is often used when the resource is large but only a small subset of fields needs to change.
In practice, PUT is expected to be idempotent. Repeating the same PUT request should yield the same result as a single PUT, because you are supplying the full, final state each time. PATCH, however, is not guaranteed to be idempotent by definition; it depends on the patch document and how the server applies it. If a patch operation is applied multiple times, the final state may or may not be the same, depending on the patch format and the operations used.
PUT vs PATCH: The Historical and Standards Context
The ideas behind PUT and PATCH have evolved through web standards and practical API design. PUT originated as a method to replace a resource in its entirety, a simple, unambiguous operation. PATCH emerged as a way to express small, incremental changes without resending the whole resource, which can be more efficient for large objects or bandwidth-constrained environments.
In formal terms, PUT is defined in a way that emphasises idempotence and completeness. PATCH is defined as a mechanism to apply a set of changes to a resource. RFC 5789 formalises PATCH as a method for making partial updates, while separate patch formats—such as JSON Patch (RFC 6902) or JSON Merge Patch (RFC 7386)—provide concrete ways to describe those updates. In everyday API work, teams often choose between these two approaches based on the desired workflow, performance considerations, and client capabilities.
When to Use PUT vs PATCH: Practical Guidelines
Choosing between PUT and PATCH should be guided by the nature of the update and the API’s design philosophy. Here are practical guidelines to help you decide which method fits best in common scenarios.
Use PUT for Full Resource Replacement
Opt for PUT when the client has a complete representation of the resource and intends to replace the existing one with that exact representation. This is particularly appropriate for small, well-defined resources or when your API prefers a simple, predictable update model. A typical pattern is to accept the full resource payload, validate it, and then store it as the new version of the resource. If fields are omitted, some APIs opt to treat missing fields as null or defaults; others require the client to supply all fields explicitly.
Use PATCH for Partial Updates
Choose PATCH when you only need to modify specific fields. For example, if a user updates a single email address or a status flag, PATCH allows you to send just those changes. This reduces the payload size and can simplify client logic when resources are large or frequently updated in isolated ways. However, you should decide which patch format you will support (for instance, JSON Patch versus JSON Merge Patch) and ensure the server correctly interprets the document.
Common Patch Formats: JSON Patch vs JSON Merge Patch
When implementing PATCH, you must define how the patch document describes changes. The two prevalent formats are JSON Patch and JSON Merge Patch, each with its own semantics and complexity.
JSON Patch (RFC 6902)
JSON Patch expresses a sequence of operations to apply to a JSON document, such as add, remove, replace, move, copy, and test. This format gives you precise control over a series of changes, which can be powerful but adds complexity to parsing and applying the patch. It is well-suited for complex edits where you need to perform multiple operations atomically, if your backend supports it.
JSON Merge Patch (RFC 7386)
JSON Merge Patch provides a simpler approach: you submit a JSON document that represents the subset of fields to modify. Any field present in the patch overwrites the corresponding field in the target resource, while missing fields are left untouched. This format is easier to implement and often adequate for standard partial updates, making it a popular choice for many APIs.
Idempotence, Concurrency, and Conflict Handling
Idempotence and concurrency are important considerations when adopting PUT vs PATCH. With PUT, idempotence is the norm: repeated identical requests should yield the same final state. This makes client retries straightforward and predictable. PATCH, by contrast, can be more complex to reason about, especially in concurrent environments where multiple clients attempt to modify the same resource simultaneously. Implementations should consider:
- Optimistic concurrency controls, such as ETag and If-M-None-Match headers, to detect conflicting updates.
- Versioning or sequence guarantees to help clients reason about the order of changes.
- Clear error responses (409 Conflict or 412 Precondition Failed) when a patch cannot be applied due to business rules or conflicts.
When designing API endpoints, documenting the exact behavior for repeated PATCH requests is essential. Ambiguity here often leads to subtle bugs in client applications.
PUT vs PATCH in Resource Lifecycle: Scenarios and Examples
Concrete examples illustrate the differences more clearly. Below are representative scenarios that show how PUT and PATCH behave in common workflows.
Example: Replacing a User Resource with PUT
Assume a user resource at /users/42 with the following representation:
{
"id": 42,
"username": "jbloggs",
"email": "[email protected]",
"name": "Joe Bloggs",
"roles": ["user"]
}
A PUT request to /users/42 with a new full representation replaces the resource entirely. If the client omits a field, the server’s behaviour depends on the API contract. In a strict full-replacement model, omitted fields may be set to defaults or removed, depending on the design.
Example: Partially Updating a User with PATCH
To update only the email address and the display name, a PATCH request might include:
{
"email": "[email protected]",
"name": "Joe N. Bloggs"
}
The server applies only these changes to the existing resource. Other fields remain untouched, assuming the patch format supports partial updates without removing unspecified fields.
Security, Validation, and Error Handling
Security and data integrity are crucial when choosing between PUT and PATCH. Both methods should be guarded by authentication and authorisation checks. Validation should occur before any update is applied, and meaningful error messages help clients correct mistakes without guesswork.
- Validate the incoming payload against the resource schema before applying updates.
- Return appropriate HTTP status codes: 200 OK or 204 No Content for successful PUT/PATCH, 400 Bad Request for invalid payloads, 401 Unauthorized for unauthenticated requests, 403 Forbidden for insufficient permissions, and 409 Conflict for concurrency issues.
- Handle content negotiation and content-type negotiation consistently, especially when supporting multiple patch formats (e.g., application/json-patch+json or application/merge-patch+json).
Caching, Identities, and Idempotence Nuances
Caching behaviour can influence how clients interact with PUT and PATCH. While GET responses are often cached with ETags or Last-Modified headers, updates themselves may trigger cache invalidation. Consider:
- Invalidate cached representations of a resource after a successful PUT or PATCH to ensure clients see the latest state.
- Use ETag/If-Match headers to prevent lost updates in high-concurrency scenarios, particularly with PATCH where partial updates occur.
- Document how downstream caches should react to PUT and PATCH operations to avoid stale data.
Versioning and Compatibility Strategies
As your API evolves, maintaining compatibility with existing clients becomes important. Some teams adopt strict versioning to prevent breaking changes, while others prefer a more evolutionary approach with well-documented deprecation paths. Consider these strategies when implementing PUT vs PATCH:
- Document the exact semantics of PUT and PATCH in each endpoint’s contract, including whether PUT requires a full resource and whether PATCH supports specific patch formats.
- Provide clear migration guides if you decide to alter how an endpoint behaves. For instance, moving from a PATCH-based workflow to a more predictable PUT-based replacement might require client-side changes and server-side validation rules.
- Version endpoints or offer a compatibility layer to support both methods during a transition period, reducing client disruption.
Best Practices for Designing PUT and PATCH Endpoints
To help you implement PUT vs PATCH cleanly and consistently, here are a set of best practices that many successful APIs follow:
- Be explicit in your API design about when to use each method. If you offer both, ensure the documentation provides concrete examples and edge-case scenarios.
- Prefer PUT when clients need a straightforward replacement workflow with clear expectations about the final state.
- Prefer PATCH for incremental updates where bandwidth and performance matter, and when partial updates are common in your domain.
- Choose a patch format that matches your backend capabilities and client requirements. JSON Merge Patch is often easier for simple updates, while JSON Patch enables more complex changes.
- Avoid ambiguous update semantics. If a patch could remove fields inadvertently, implement safeguards or provide explicit guidance in the API contract.
Advanced Considerations: Idempotence, Safety, and Semantics
Beyond the basic differences, you’ll encounter deeper considerations when engineering PUT vs PATCH endpoints:
: Prioritise idempotence for operations that are likely to be retried due to network issues. PUT’s idempotence is a strong guarantee; PATCH requires careful design to maintain it where desired. : Both PUT and PATCH are not typically classified as safe operations (unlike GET), because they modify server state. Plan for appropriate auditing, logging, and user notifications where applicable. : If you implement PATCH with JSON Patch, design your patches so repeated application does not produce unintended side-effects. Consider constraints or atomicity where necessary.
Common Pitfalls and Anti-Patterns in PUT vs PATCH
Even experienced teams stumble into familiar traps when dealing with update semantics. Here are several frequent issues to avoid:
- Using PATCH for full replacements without sending a complete representation, causing partial updates to inadvertently overwrite data with defaults.
- Assuming PATCH is always faster or lighter; depending on payload size and server processing, the difference can be marginal.
- Mixing semantics in a single endpoint, for example allowing PATCH to replace the entire resource under certain conditions. Consistency is valuable for client developers.
- Failing to document accepted patch formats or the exact interpretation of fields in a PATCH document, leading to inconsistent client implementations.
Putting It All Together: A Design Example
Suppose you are designing an API for a task management application. You have a resource at /tasks/{id} with fields such as title, description, status, dueDate, and assignee. The API design might look like this:
- PUT /tasks/{id}: Replace the entire task resource with a complete payload, for example, a new title, description, status, due date, and assignee. If the task did not exist, you may choose to create it with the provided data.
- PATCH /tasks/{id}: Apply partial updates. A payload might only modify the status and dueDate, leaving the other fields untouched.
When implementing PATCH, you might decide to support JSON Merge Patch for straightforward updates and optionally JSON Patch for more complex modifications. Make sure to document which patch formats you accept and provide examples in your API reference. This clarity reduces confusion and helps clients implement the correct update flow without unnecessary round-trips.
Developer Experience and Client Considerations
From a client developer’s perspective, PUT vs PATCH can significantly influence the implementation strategy. Consider the following:
- Client libraries: If you provide SDKs, document how each method should be used, including sample payloads, expected status codes, and how errors are surfaced.
- Error handling: For PATCH, it can be helpful to return detailed validation errors for individual fields so clients can repair only the problematic parts of a patch document.
- Idempotent retries: Because PUT is naturally idempotent, clients can safely retry a failed PUT request. For PATCH, retry strategies should be designed to avoid applying changes twice, or at least to handle partial success correctly.
Conclusion: Selecting PUT vs PATCH With Confidence
In the end, PUT vs PATCH isn’t a clash of one right approach versus another wrong one. It’s about selecting the right tool for the job. PUT shines when you want a clear, full replacement that is easy to reason about and safe to retry. PATCH shines when you need efficient, partial updates and you’re prepared to manage the complexity of the patch document and the potential concurrency challenges.
By documenting your semantics, choosing compatible patch formats, and aligning with your overall API design philosophy, you can make PUT vs PATCH work harmoniously within your service. Readers who understand the distinction and apply these principles consistently will deliver APIs that are predictable, scalable, and pleasant for developers to use.
Final thoughts: Thinking ahead in API design
As APIs evolve, teams sometimes consolidate around a single update approach for simplicity or adopt a mixed model to balance efficiency and clarity. Whatever you decide, ensure that your contract is explicit, your validation robust, and your error handling transparent. With thoughtful application of PUT vs PATCH, you’ll foster better developer experiences, more reliable systems, and clearer evolution paths for your services.