No matter how sure you are that part of an interface will never need to block, you are wrong. Even the simplest task will be expensive or slow for someone, at some point. Design interfaces to deal with asynchronous responses from the start. How did I learn this? I designed a mailbox framework and make the “select mailbox” operation synchronous, almost alone among the 30 or so other functions in the interface, because I was certain it was such a simple operation it would never need to block.
Loading data is expensive; loading unnecessary data is inefficient:
For the sake of simplicity, the “list all mailboxes” operation was implemented in terms of objects already defined by the interface. Specifically, it was defined to return a list of mailboxes, but only a few fields of each mailbox are ever actually used. How did I learn this? Tonight discovered that my implementation of this operation ran over ten thousand times faster if the implementation only returned the required data, instead of whole mailbox objects. Oops.