As a technical program manager, you are expected to be a capable engineer as well as a manager, and be able to perform at a level equivalent to a practicing engineer in the field. Many program managers, especially senior ones, find fewer opportunities to keep their technical skills sharp. This guide is intended as a refresher and crash course on system design, intended for software program managers.
Understanding system design is critical because it enables the program manager to participate in technical decisions and discussions that affect the program. Program managers without enough technical depth can get lost in these discussions, and this can make it difficult to effectively manage the program.
Clarify and agree on the scope of the system
The first step in any system design discussion is to clarify and agree on the scope of the problem being solved and the solution space available. Scope, timeline, and quality are the three variables available to work with, so it helps to fix one of them early on, and then proceed to work out the others as more information becomes available. You may have to have discussions around trade-offs, especially if you have additional constraints or special requirements for quality or timeline.
High-level architecture (abstract design)
- Each component is a set of interfaces (connections)
- Modules are sets of components
- Map features to modules
- Schema design
- Common Systems
- Application service layer
- Data storage layer
- Web server load balancer
- Services / APIs
- Physical constraints (size, space)
- Time constraints
- Quantity constraints
- Vertical scaling
- Add CPU, RAM
- Horizontal scaling
- Add machines
- Load balancing
System design topics
- Consistency vs. Coherence
- Throughput vs. Latency
Abstraction: Be comfortable with multiple layers of abstraction and be able to design your own abstract architectures and service layers. Know how to refactor and use common design patterns to model and simplify the problem space.
Programming Languages: Be familiar with at least a handful of major programming languages, and be able to discuss the differences and trade-offs between them. Understand type systems, interpreters, compilers, garbage collection, and syntax as they relate to programming languages. Be able to make the case for choosing one language over another for particular project.
Operating Systems: Be familiar with Linux, macOS, Windows. Be comfortable in a shell and writing shell scripts. Understand processes, memory management, threading, input/output, drivers, kernel.
File Systems: Understand storage media and trade off between cost and speed, and cost and durability. Understand file system architectures like ext3.
Databases: Understand and be able to describe the differences and trade-offs between relational (SQL), non-relational (NoSQL), distributed databases and related tools and implementations (postgres, mysql, mongodb, etc).
- Local hardware (CPU, memory, storage)
- Network interfaces (bandwidth, throughput)
- Availability / Reliability
- Content delivery network (CDN)
- Sphinx/Lucene/Solr (Text Search)
- Security (CORS)
- Offline support (progressive enhancement)
- Front-end design topics
- Code: HTML5, CSS, JS, Python
- Style Guide / Pattern Library
- Architecture Diagrams (code flow, tool chain)
- Testing (performance, unit, end-to-end)
- Deployment (source control, dependency management, build system, continuous integration)
- Work breakdown structure (architectural dependencies, critical path)
- T-shirt sizing (S/M/L)