Practices
Practices are how we turn principles into action. These are proven approaches that high-performing engineering teams use.
Code Quality
Trunk-Based Development
What: Everyone commits to main branch frequently (at least daily).
Why:
- Reduces merge conflicts
- Enables continuous integration
- Smaller, safer changes
How:
- Use feature flags for unfinished work
- Short-lived feature branches (hours, not days)
- Automated tests gate the merge
Code Review
What: Every change is reviewed by another engineer before merging.
Why:
- Catches bugs early
- Shares knowledge
- Maintains standards
Guidelines:
- Review within 24 hours
- Focus on correctness, not style (automate style)
- Approve when “good enough”, not perfect
- Use review as teaching opportunity
Testing
The Test Pyramid
/\
/ \
/ E2E\ <- Few tests, slow, expensive
/--------\
/Integration\ <- Medium tests, moderate speed
/--------------\
/ Unit Tests \ <- Many tests, fast, cheap
/-------------------Unit Tests (70%):
- Test one function/component in isolation
- Fast (<100ms per test)
- Run on every commit
Integration Tests (20%):
- Test component interactions
- Test with real dependencies (DB, API)
- Run in CI pipeline
E2E Tests (10%):
- Test full user workflows
- Run against staging/production
- Run before major releases
Test-Driven Development (TDD)
Red-Green-Refactor Cycle:
- Red: Write a failing test
- Green: Write minimal code to pass
- Refactor: Clean up while tests pass
When to use: Complex logic, unclear requirements, bug fixes.
CI/CD
Continuous Integration
Practices:
- Commit to main at least daily
- Automated build on every commit
- Automated tests run on every PR
- Fix broken builds immediately
Pipeline Stages:
Build → Unit Test → Integration Test → Security Scan → MergeContinuous Delivery
Practices:
- Keep main branch deployable at all times
- Automated deployment to staging
- One-click deployment to production
- Automated smoke tests post-deploy
Pipeline Stages:
Staging Deploy → Smoke Test → Approval → Production Deploy → VerifyDeployment Patterns
Feature Flags:
- Deploy code without releasing features
- Enable gradually (canary, % rollout)
- Instant rollback if issues
Canary Deployment:
- Deploy to small subset of users
- Monitor metrics
- Gradually increase traffic
- Roll back if anomalies detected
Blue-Green Deployment:
- Two identical environments
- Switch traffic instantly
- Fast rollback (switch back)
Observability
Three Pillars
Logs: Event records
- Structured logging (JSON)
- Correlation IDs across services
- Appropriate log levels
Metrics: Numeric measurements
- Request rate, latency, errors
- Business metrics (orders, revenue)
- System metrics (CPU, memory)
Traces: Request flow
- End-to-end request tracking
- Performance bottlenecks
- Service dependencies
Alerting
Good Alerts:
- Actionable: There is something to do
- Specific: Clear what is wrong
- Timely: Right urgency level
Alert Levels:
- P0: Page immediately (outage)
- P1: Page during business hours (degraded)
- P2: Ticket for next business day (warning)
Security
Secure by Default
Shift Left: Find security issues early
- Dependency scanning in CI
- Static Application Security Testing (SAST)
- Secrets scanning (no secrets in code)
Defense in Depth: Multiple layers of security
- Authentication and authorization
- Input validation
- Encryption at rest and in transit
- Network segmentation
Security Practices
Secrets Management:
- Never commit secrets to git
- Use secret management tools (Vault, AWS Secrets Manager)
- Rotate secrets regularly
- Audit secret access
Dependency Management:
- Scan dependencies for vulnerabilities
- Keep dependencies updated
- Pin versions for reproducibility
- Have an update strategy
Documentation
Documentation Types
README: Getting started
- What is this project
- How to run it
- How to contribute
Architecture Decision Records (ADRs): Why decisions were made
- Context, decision, consequences
- One per significant decision
- Stored in git with code
Runbooks: Operational procedures
- How to handle common issues
- Step-by-step instructions
- Links to relevant dashboards/logs
API Documentation: How to use the service
- OpenAPI/Swagger specs
- Example requests/responses
- Authentication details
Documentation Best Practices
- Write as you go: Do not wait until the end
- Close to code: Docs in the same repo
- Executable docs: Use code snippets that are tested
- Review docs: Treat docs like code (review, version)
Collaboration
Pair Programming
When to use:
- Complex problems
- Knowledge sharing
- Onboarding
Formats:
- Driver-Navigator: One types, one thinks
- Ping-Pong: Switch roles frequently
Mob Programming
Whole team, one keyboard, one problem.
When to use:
- Complex architectural decisions
- Knowledge sharing across team
- Solving sticky problems