Software Architecture
What are the key principles for architecting systems that enable innovation and are performant?
Refer to System Design Primer
System Design
Context
Best Practices
Intent
- How can minimize the cognitive load for developers to understand this code
- How can I optimize data flow.
Checklist
- Focus on data flow and locality:
- Modern programming paradigms often hide data flow and locality, which are crucial for performance.
- Systems should be designed with data flow in mind from the start.
- Locality is critical for high-performance computing.
- Resource planning and allocation:
- Pre-allocate resources (memory, cores) at job startup rather than relying on dynamic allocation.
- Be explicit about resource requirements and limitations.
- Avoid using features like malloc that pretend resources are infinite.
- Use a tile architecture:
- Assign specific tasks to dedicated cores or "tiles".
- This allows for specialization, efficient caching, and deterministic performance.
- Provides natural security boundaries between components.
- Rethink abstraction layers:
- Many modern APIs and operating systems hide important low-level details.
- Create abstractions that allow developers to express locality and data flow without needing to understand all low-level details.
- Optimize for real-world constraints:
- Consider physical limitations like the speed of light.
- Design systems with concurrency budgets in mind (e.g., number of instruction pointers available).
- Encourage proper resource management:
- Provide developers with tools and abstractions that naturally lead to good resource allocation practices.
- Avoid relying on the operating system or language runtime to magically handle resource management.
- Focus on reliability and determinism:
- Design systems to be hyper-deterministic and reliable.
- This is crucial for financial applications that require quick, consistent responses.
- Plan for scale from the beginning:
- For systems like Solana, think in terms of millions of transactions per second and huge numbers of accounts.
- Design for quick recovery from outages.
- Rethink networking protocols:
- Existing protocols like QUIC may not be optimal for validator needs.
- Consider designing purpose-built protocols for high-performance blockchain systems.
- Address implicit behaviors:
- Spend time identifying and specifying all implicit behaviors in the system.
- This is crucial for creating a reliable and consistent implementation across different clients.