First, identify what the common operations are for this system. This might sound like a no-brainer, but it's important to remember to start with the expected system behaviors before diving into the design.
Among the common operations, identify which ones need to be fast. Is it read, write, or search? For the same set of expected system operations, optimization could drastically change the design. A read-heavy system versus a write-heavy system will be very different.
Address how to keep the data fresh and consistent. In complex systems, data consistency is a key issue to address. For example, how the database handles atomicity is the core of database design.
Think through what will be the upcoming changes. Requirements always change. A good system design incorporates future changes and makes the design forward-compatible.
Componentize the system so that each can iterate on its own. Once a system is put in place, each component is developed and iterated separately. Therefore, it’s important to design it in such way at the beginning.