Here's how we run retrospectives across a ~500 person R&D org at GitLab :
Here's how we estimate work on GitLab's Growth Engineering team:
• We use a Fibonacci scale of 1, 2, 3, 5, 8, 13.
• 1 is the simplest possible change.
• 13 is a significant change with many unknowns.
• We estimate high if we can't decide on the weight of an issue.
• If an issue has many unknowns, we break it into separate spike and implementation issues.
• Anything over 5 can likely be broken down into a smaller iterations.
• Estimates provide us with a baseline level of predictability.
• We optimize for velocity rather than predictability. We aim for 70% predictability.
• Estimates can be adjusted and revised any time.
More details here: https://about.gitlab.com/handbook/engineering/development/growth/#estimation
Here's how we prioritize work on GitLab's R&D teams:
• Security, Data-loss, and Availability issues come above all feature work.
• SLAs/SLOs are set based on Severity / Priority (S/P).
• S1/P1s are resolved in a few hours.
• S4/P4s are resolved in 1-2 milestones.
• Next are Regressions, Customer Commitments, Availability and Performance Optimizations
• After that are Analytics, UX Improvements, ARR Drivers, Dogfooding, Features / Tech Debt.
• To address Tech Debt, some teams carve out 20% of each milestone to pay off debt.
• To prioritize Features, we recommend using the RICE framework to score based on Reach, Impact, Confidence, Effort.
More details here: https://about.gitlab.com/handbook/product/product-processes/#prioritization
Organizations design systems that mirror their own communication structure.
Source: Wikipedia
Similar to iteration, you improve things as needed. You likely don't need VueJS/ReactJS right from the start. You also probably don't need Kubernetes right from the start. Start with boring solutions and only add complexity as needed.
There are many different directions you can go with a techstack. My preference when choosing technologies is to:
- Simple Boring Solutions: Simple solutions allow you to move quickly. Boring solutions means you focus on using proven technologies rather than something shiny and new that's un-tested.
- Quick Iterations: Iteration speed always wins. Building quickly gives you a path towards better functionality. If you take on too much complexity at the beginning you'll never get started.
- Progressive Enhancement: Start with simple technologies and swap out certain components as it requires more functionality. You can get very far with progressive enhancement. Eventually a tipping point may be reached where it's inefficient to continue work with the simple technology and it makes more sense to fully make the transition to a more complex technology -- make this jump later when needed, not from the start. A good example of this is to never start with micro-services -- always start with a monolith then slowly break out services as needed.
What this means in practice is:
- Keeping your codebase simple so that a single engineer can fully understand it.
- Aiming for a single codebase that works across all platforms (web, ios, android).
- Standardized design system for a uniform UX and efficient design process.
Category | Stack |
---|---|
Infra | Digital Ocean, Ubuntu, Nginx |
Web Backend | Rails, Postgres, Redis, Sidekiq |
Web Frontend | HAML, Boostrap, JQuery, Hotwire, Turbo, Stimulus, ViewComponent (when needed) |
Web Frontend Heavy Client-side Interaction | VueJS, Webpack |
iOS Client | Swift, Turbo |
Android Client | Kotlin, Turbo |
- | Rails + jQuery | Rails + Hotwire | Rails + VueJS | Rails + ReactJS | RailsAPI + NodeJS / VueJS + Ionic / Capacitor | RailsAPI + NextJS / ReactJS + Ionic / Capacitor | Rails API + NodeJS / ReactJS + ReactNative |
---|---|---|---|---|---|---|---|
Backend | Rails | Rails | Rails | Rails | Rails API | Rails API | Rails API |
Web Frontend | Rails, jQuery | Rails, jQuery, Hotwire / Turbo / Stimulus | Rails, VueJS | Rails, ReactJS | NuxtJS / VueJS | NextJS / ReactJS | NextJS / ReactJS |
Mobile Frontend | Cordova | Strada / Hotwire / Turbo / Stimulus | Cordova | Cordova | Ionic / Capacitor | Ionic / Capacitor | ReactNative |
Number of codebases | One + Mobile Wrappers | One + Mobile Wrappers | One + Mobile Wrappers | One + Mobile Wrappers | Two + Mobile Wrappers | Two + Mobile Wrappers | Three |
Native or Hybrid | Hybrid | Hybrid | Hybrid | Hybrid | Hybrid | Hybrid | Native |
SEO Friendly (SSR) | Yes | Yes | Yes using Webpacker | Yes using Webpacker | Yes using NuxtJS | Yes using NextJS | Yes using NextJS |
Community Support | 7 | 5 | 6 | 7 | 6 | 7 | 8 |
Simplicity | 8 | 7 | 5 | 5 | 4 | 4 | 3 |
UX | 4 | 6 | 7 | 7 | 7 | 7 | 8 |
Performance | 4 | 6 | 7 | 7 | 7 | 7 | 8 |
Notes | Able to incrementally swap VueJS/ReactJS components in when needed | Able to incrementally swap VueJS/ReactJS components in when needed |
Sources
- Vue.js And SEO: How To Optimize Reactive Websites For Search Engines And Bots
- Developing mobile applications with apache cordova
- Quora: Which hybrid Framework has more future Ionic React or Meteor
- RailsConf 2016 - Turbolinks 5: I Can’t Believe It’s Not Native! by Sam Stephenson
- Hacker News readers as Progressive Web Apps
In a world with AI pair programmers, memorizing programming syntax isn't important. Instead, focus on understanding the complexities of software that AI doesn't understand yet, such as system architecture.