Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 50

Handling Rollbacks: Designing for Failed Optimistic Updates

Recommended resources

Introduction

Welcome to the next lesson in our module on data flow and freshness. In our previous session, we designed alert patterns for when data is significantly delayed. You learned how to use tiered alerts to manage user attention and maintain trust when expected data doesn't arrive on time.

This lesson tackles the flip side of that problem. We've previously discussed optimistic updates—a powerful UX pattern where we update the UI before the server confirms an action, making the app feel instantaneous. But what happens when our optimism is misplaced and the server request fails?

Today, our learning outcome is to design the user experience for handling rolled-back data after an optimistic update fails. This is a critical skill for an architect, as it involves designing for failure with grace. A system that can recover smoothly from errors is far more robust and trustworthy than one that only functions under perfect conditions.


1. The Anatomy of an Optimistic Failure

Let's quickly revisit the optimistic UI pattern. Instead of making the user wait for a server roundtrip, we assume the action will succeed and update the interface immediately.

Traditional vs. Optimistic UI for a 'Like' Button
This diagram contrasts a traditional UI flow, which waits for server confirmation, with an optimistic UI flow, which updates the interface instantly and handles the server communication in the background. Our focus today is on that "API Request Fails" branch.

The challenge arises when the server communication fails for any number of reasons—a network error, a server issue, or invalid data (e.g., trying to comment on a deleted post). The UI has already shown a success state, but the system's true state hasn't changed. This creates a discrepancy that we, as designers, must resolve.

A silent failure, where the UI simply reverts to its previous state with no explanation, is confusing and feels like a bug. To see why, watch the first part of this short video.

STOP showing loading states and START using optimistic UI

The video 'STOP showing loading states and START using optimistic UI' demonstrates how a silent rollback can be a poor user experience.

Watch from the timestamp 03:39 to 04:30. Notice how the new to-do item just disappears when the action fails. The presenter notes that this 'feels buggy' and that the user gets no feedback.

Our job is to design a user experience that avoids this buggy feeling by explicitly managing the failure and guiding the user through it.


2. The Core Pattern: Revert, Inform, and Empower

The foundation of a good rollback experience is the "Revert and Inform" pattern. However, for a truly excellent user experience, we should add a third component: "Empower."

  1. Revert: The UI state must be rolled back to reflect the reality of the system. The "liked" heart becomes un-liked; the new comment disappears from the list.
  2. Inform: The user must be clearly notified that the action failed and, if possible, why. This turns a confusing moment into an understandable one.
  3. Empower: The user should be given clear, actionable choices on how to proceed. This restores their sense of control.

One of the most classic examples of this pattern in action is the iMessage "Not Delivered" alert.

iMessage Delivery Failure and Recovery Options
This iMessage failure notification is a perfect real-world example of the Revert, Inform, and Empower pattern. The message state is reverted to 'Not Delivered' (Revert), the user is explicitly told what happened (Inform), and they are given clear options to recover ('Try Again', 'Send as Text Message') or move on ('Cancel') (Empower).

To solidify your understanding of this core pattern, let's look at a clear explanation.

Optimistic UI Updates in React (Simple Guide)

The article 'Optimistic UI Updates in React' provides a simple but effective summary of handling failures gracefully. It introduces the 'Rollback Pattern' and the importance of user feedback.

Please read the section 'Handling Failures Gracefully,' focusing on the 'Rollback Pattern' and 'User Feedback on Errors.' This section codifies the principles we've just discussed.


3. Key Principles for Designing Rollback Experiences

With the core "Revert, Inform, Empower" pattern in mind, let's break down the specific design principles you need to apply when creating a rollback UX.

Principle 1: Preserve User Input and Effort

This is paramount. If a user spends time composing a message or filling out a form, and the submission fails, their work must not be lost. Losing user input is a major violation of trust and a source of intense frustration.

A good rollback design will automatically restore the user's input, allowing them to easily retry the action.

Frontend System Design Essentials: Optimistic updates

The video 'Frontend System Design Essentials' includes a great demonstration of a rollback that preserves user input. Watch how the comment editor re-appears with the original text after the optimistic update fails.

Please watch from 13:25 to 15:53. Pay close attention to what happens at 14:20. The system not only rolls back the UI but also re-opens the form and re-populates it with the user's original text, making it easy to retry.

Principle 2: Tailor the Feedback to the Context

Not all failures are equal. The intrusiveness of your notification should match the importance of the failed action.

  • Low-Stakes Actions (e.g., liking a photo): A brief, non-blocking notification (like a toast) saying "Couldn't like post" might be sufficient. The UI element (the heart icon) should revert. No further action may be needed.
  • High-Stakes Actions (e.g., submitting a payment, posting a long comment): A more prominent notification is required. This could be a modal dialog or an inline error state on the form itself. This ensures the user acknowledges the failure and can take corrective action.

The decision of whether to persist the optimistic result depends on how much effort the user invested.

Web Developer Playbook: Optimistic UI

The article 'Web Developer Playbook: Optimistic UI' provides a sharp analysis of when and how to persist user data after a failure.

Please read the section 'An Overview of Optimistic UI Problems,' focusing on subsection 1, 'Persisting Optimistic Result.' The author contrasts the experience of a failed comment with a failed 'star' on GitHub to illustrate this point perfectly.

Principle 3: Design for Different Update Types

From a systems architecture perspective, the rollback logic changes depending on whether you're updating a single field or modifying a collection of items. As a designer, you need to understand these differences to create the right experience.

  • Field Updates (e.g., changing a username, editing a description):
    The main challenge is reverting the field to its previous state while preserving the user's failed input. The design often involves showing an error message directly associated with the input field and providing a "Retry" or "Save" button. The article you just read discusses this in its "Field Update with Persistence" section, describing a system that manages three states: the optimistic result, the server's last known state, and the send status (PENDING, SENDING, FAILED). This allows the UI to intelligently disable or enable buttons based on the system's true state.

  • Collection Updates (e.g., adding a comment, deleting a file):
    These are more complex. When adding an item optimistically, it doesn't have a real ID from the server yet. If the creation fails, the item must be removed from the list. If it succeeds, the temporary item needs to be seamlessly replaced with the real one from the server.

    A robust rollback design for collection updates will:

    • Visually distinguish items that are still "pending" or have "failed." For example, a "failed" comment might appear greyed out with a "Retry" button.
    • When an add fails, the item is removed from the list, and the user's input is restored in the comment box.
    • When a delete fails, the item reappears in the list, often with a toast notification explaining the failure. The article "Optimistic UI Updates in React" provides clear code patterns for these scenarios in its "Real World Example: Todo List" section.

4. Your Turn: UX Design Challenge

Imagine you are designing the UI for a project management tool called "TaskFlow."

Your Task:
For each of the following failure scenarios, design the complete rollback user experience.

Describe or sketch:

  1. The optimistic state (what the user sees immediately after their action).
  2. The final failed state (how the UI looks after the rollback).
  3. The full rollback UX, including notification type (toast, modal, inline), UI copy (following the "Clarity, Context, Choice" model), and available user actions.

Scenario A (Field Update):
A user is editing the description of a task. They finish writing a detailed, multi-paragraph description and click "Save." The UI optimistically shows the new description. However, the update fails due to a brief network outage.

Scenario B (Collection Update):
A user adds a new task, "Finalize Q3 report," to a project list. The task optimistically appears at the bottom of the list. The server rejects the request because the project was archived by a team member moments before.



Conclusion

Today, you've learned to design for one of the most challenging moments in user interaction: when the system's optimism fails. By mastering the "Revert, Inform, and Empower" pattern, you can turn a potentially confusing and frustrating bug into a clear, manageable, and even trust-building experience.

Key Takeaways:

  • Rollback is a triad: A good rollback experience must Revert the UI to its true state, Inform the user about the failure, and Empower them with clear choices.
  • Never lose user input: Preserving user effort during a failure is a cornerstone of a trustworthy system.
  • Context is king: The design of your rollback (e.g., a subtle toast vs. a blocking modal) must match the stakes of the action that failed.
  • Architect for failure: Understanding the difference between field and collection updates allows you to design more precise and robust recovery paths.

Next Steps

We have now thoroughly explored the challenges of data flow, from delays and freshness to the complexities of optimistic updates and their failures. You are equipped to design interfaces that are not only responsive but also resilient.

In our next module, we will shift our focus from the mechanics of data to the psychology of interaction. We will begin Module 8: Engineering Trust in AI Systems by exploring the concepts of System 1 (intuitive) and System 2 (deliberate) thinking. This will provide the foundation for understanding how users perceive and decide to trust the outputs of the complex, often probabilistic AI systems you will be architecting.