Are you not on the product team, but looking for information on how to get in contact with or provide information/ask questions to product managers? Please see our How to Engage guide.
The document below talks about how we do product at GitLab, not about what. For the what, see Product Direction.
If you are a product manager looking to learn everything about being a PM at GitLab, this document is broken into the following sections:
Other important sub-pages of this one that are relevant include:
The direction for the GitLab product is spelled out on the Direction page. This document provides lessons and heuristics on how to design changes and new features. Our iterative process is demonstrated in a blog post.
From development teams to marketing organizations, everyone needs to collaborate on digital content. Content should be open to suggestions by a wide number of potential contributors. Open contribution can be achieved by using a mergeable file format and distributed version control. The mission of GitLab is to allow everyone to collaborate on all digital content so people can cooperate effectively and achieve better results, faster.
Ideas flow through many stages before they are realized. An idea originates in a chat discussion, an issue is created, it is planned in a sprint, coded in an IDE, committed to version control, tested by CI, code reviewed, deployed, monitored, and documented. Stitching together all these stages of the DevOps lifecycle can be done in many different ways. You can have a marketplace of proprietary apps from different suppliers or use a suite of products developed in isolation.
We only ship in a Minimally Viable Product (MVP) style. We call it Minimum Viable Change (MVC), because our business model is focused on adding additional value to our integrated product suite, instead of building separate, new products.
MVC means we start by delivering the smallest possible solution that offers value to our users. To avoid feature bloat, we rely on user research to validate whether our idea addresses a market need in a desirable way. This approach sets us up to expend the smallest possible amount of effort to build new capabilities, while learning more about how to best add additional functionality over time.
While an MVC may not have the robust functionality of a fully developed feature, it should still address fundamental user needs through a bug-free and highly usable experience. The minimally viable change should not be a broken feature.
Advantages of an MVC approach:
An MVC approach is a byproduct of our spirit of iteration. Even when not pursuing an MVC, we will encourage iteration in our own development process. That means we break problems down as small as possible, use throughput as a performance indicator, and focus on reduced cycle time. Thinking iteratively is not always intuitive, and breaking certain topics or projects down can be challenging. Here's a helpful video from our CEO with guidance on how to think more iteratively.
Just because something is not invented here doesn't mean it doesn't have a perfect home within our solution. GitLab is an Open Core product and is part of the broader ecosystem of Open Source tools in the market. Every day there are new innovative tools out there that solve real-world customer problems; we should not be afraid of embedding these tools into our own products in order to solve those same problems for our customers too. Leveraging existing technology allows us to get to market much more quickly, to contribute to Open Source (and help strengthen Open Source as a whole), and allows us to focus our own people on making GitLab itself better. Building professional relationships with these tool creators also is a positive for GitLab since they may have important user perspectives around your categories.
We have achieved many successes following this approach:
There are also many more examples throughout the company where this has been successful. As a product manager you should be monitoring the world of Open Source as it relates to your area to see where new innovative tools are being developed, and not be afraid of integrating those. One thing to keep in mind, integrating could be anything from a blog post describing how the tool works together with GitLab all the way up to bundling it inside of our own installation, and this can evolve iteratively.
As an application development tool, we understand the natural inclination to create an array of buttons to press and knobs to turn.
We believe however that more options are not necessarily better, and that our users are better served by an application with reduced complexity yet still contains the features they need.
We admire other convention over configuration tools like Ruby on Rails (that doctrine of which perfectly describes the value of integrated systems), Ember, and Heroku, and strive to offer the same advantages for a continuous delivery of software.
Furthermore, Ruby on Rails has been of massive influence to the Ruby community. Uplifting it, and making it more powerful and useful than ever before, for many more usecases. We want GitLab to be to Kubernetes, what Rails is to Ruby.
You should prefer choices that are well thought out and based on current best practices. Avoid unnecessary configuration. Avoid configuration to support fragile workflows.
When considering adding new configuration, we follow the following principles:
Product Managers at GitLab are frequently confronted with the choice of whether to add new configurations or not. These can frequently be times where an outside perspective is important. That's why we've created the option to request a New Config Review.
Here's an example of how to consider whether to add new configuration. Let's say you are proposing we add a checkbox or two radio boxes in a feature dialog box. Think carefully about what users really want. Most of the time, you'll find you really only need one solution, so remove the other option. When two possible choices really are necessary, the best or most common one should be the default, and the other one should be available. If the non-default choices are significantly less common, then consider taking them out of the main workflow for making decisions, by putting them behind an Advanced configuration tab, for example.
Avoiding configurations is not always possible. When we have no choice, the secondary priority is to configure something in the GitLab interface.
A configuration should only appear in a file (
gitlab.yml) as a last resort.
gitlab.ymlis the configuration file used by the Rails application. This is where the domain is configured. Other configurations should be moved to the UI as much as possible and no new configurations should be added here.
gitlab.rbis the configuration file for Omnibus-GitLab. It acts not only as an abstraction of the configuration of
gitlab.ymlfor GitLab-Rails, but also as the source for all configurations for services included and managed within the Omnibus-GitLab. Newly introduced services probably need to be configured here.
When you have to add a new configuration, make sure that the features and services are on by default. Only add a configuration line to either of these configuration files if the feature or service cannot be fully disabled from the admin UI.
Within each stage, the learning curve must be at least comparable to our best-in-class competitors, with clear, cohesive workflows, a highly usable interface, and comprehensive documentation. Our product must have an easy UX that accommodates all users.
Many crazy, over-ambitious ideas sound like they are impossible just because no one else is doing them.
Since we have amazing engineers and a culture of shipping minimally viable changes, we are able to do a lot more 'impossible' things than others.
That's why we're shipping merge conflict resolution, why we shipped built-in CI before anyone else, why we built a better static pages solution, and why we're able to compete.
Here at GitLab, we are an ambitious company and this means we aim for big things with every release. The reality of taking chances and planning aspirationally means that we won't always be able to deliver everything that we wanted to try in every release, and similar to our OKRs, we believe this is a good thing. We don't want to shy away from challenging ourselves and always want to keep a sense of urgency, and aiming for more helps us do that. Also see the importance of velocity
We arrived at our preference for ambitious planning after measuring our velocity and finding that our velocity was unchanged whether we scheduled ambitiously or scheduled for providing slack.
Doing something simple in GitLab should BE simple and require no human cpu-cycles to do so. Things that are simple now should still be simple two years from now, ten years from now, and onwards.
This sounds obvious, but messing with flow is easily done. In most cases, flow is disrupted by adding another action, or another click.
For instance: You want users to be made aware of the rules of a project. Your proposal is a little popup that shows the rules before they create an issue. This means that every time that someone creates an issue they need to click once before resuming their normal action. This is unacceptable. A better solution is to add a link to the issue that points the user to this.
It's very hard to maintain flow with a lot of configurations and options. In cases where you want to enforce a certain behavior, the most obvious step may be to add another step or action. This can be avoided by making the action work in parallel (like a link in the issue), encouraging rather than enforcing certain behaviors.
Also, we don't want users to be able to construct workflows that break GitLab or make it work in unpredictable ways.
Feature discoverability is important for allowing new and existing users to access old and new features, thereby increasing the value for them. It also allows GitLab to get as much feedback as possible, as fast as possible, in order to quickly iterate.
However, UI that purports to increase discoverability, but that is not carefully designed and implemented, may actually harm the overall experience by constantly shoving unwanted images and text in the face of the user. The end result is that the user loses trust in GitLab, and they no longer take the time to carefully parse text and other UI elements in the future. Even worse, they might leave GitLab because of this degraded experience. The following are a few illustrative examples and best practices.
Think of this: Your co-worker is hard at work in front of their computer, and you suddenly tap their shoulder or yell at them to tell them about some new cool widget. You better have a good reason for that: that widget better be awesome.
Back to the analogy: Your co-worker said they don't care about that new cool widget. Never, ever, ever, bring it up again. They told you they don't care, and you need to respect that.
Leveraging navigation is an effective design paradigm to introduce a user to a new feature or area of GitLab.
If at the current moment they don't want to be disturbed, they can just ignore it because it is only a slight visual disturbance (as compared to a banner which takes up more screen real estate).
If dismissed once, it stays dismissed forever, for that user, across all clients that the user can access GitLab with.
Back to the analogy. We're not going to bother our co-worker with 5 different cool new widgets at the same time.
Shipping only MVCs can result in a large set of loosely connected pieces that don't necessarily combine into a single, great user experience.
An obvious solution to this would be to plan out the future in detail, creating a long-term detailed plan. However, this is unwanted as it can restrict your flexibility and ability to respond to changing needs or feedback.
Flow One offers an alternative. You draw out a workflow consisting of MVCs (that can be shipped individually). The workflow should only cover a specific, narrow use-case, and nothing more.
This means you:
Flow One should cover the first iteration of a particular workflow. After this, individual MVCs can be introduced to expand the use-cases or loosen the assumptions (e.g. from a feature that can only be used if you're using feature branches, to one that works for other git strategies).
See our thoughts on breadth over depth on our strategy page. While we prioritize breadth over depth, Product Managers should not lose sight of maturing each product category, with the ultimate goal of each category moving into a lovable state. A good rule of thumb to consider when planning product improvements, is that over time, approximately 70% of engineering effort should be allocated on breadth, and 30% on depth.
Using data to learn from our users is important. Our users are spread across GitLab.com and self-managed instances, so we have to focus our efforts on learning and providing benefit to both when we decide to collect more data, or build and use additional analytics tools. If we do this, we can help make the rest of the company successful as well. This means that we should:
Per GitLab Stewardship, we will not introduce artificial limits in Core. Artificial means arbitrarily setting a small number (such as: 1) as a limit on a given GitLab object category, that would incur no additional effort or cost had we chosen a larger number. The additional effort includes product, design, and engineering effort to create the feature in the first place, and to maintain it over time.
For example, GitLab Core has the issue board feature in every project. In GitLab EE, each project supports multiple boards. This does not mean that Core has an artificial limit of one board per project, because there is additional effort to manage multiple boards such as supporting the navigation interface, and all the associated engineering work.
We're discussing enforced workflows in this issue.
Enforced workflows should be avoided in GitLab. For example, there are three issue
In Progress (as of 10.2), and
Closed), and any issue should be
allowed to transition from one state to any other state
without workflow restrictions. (Roles and permissions is a separate concern.)
A comment on Hacker News perfectly details what can go wrong when enforcing workflows:
"The down side for the true end-users, those who actually use the software day-to-day, is that most business processes are awful. If your experience is the hellish existence that I see strolled about on threads where JIRA comes up …:
But that comment also specifies the advantage:
"JIRA's most powerful feature is that it affords for mapping businesses processes onto software. This is incredibly compelling to enterprise customers. Software that enforces workflows, procedures and requirements can be an incredible lever and JIRA's price point makes build vs buy decisions an absolute no-brainer."
We should ensure that GitLab makes it easy to help with enterprise workflows:
Small primitives are building blocks in GitLab. They are an abstraction not at the technical level, but truly at the product level. Small primitives can be combined, built-upon further, and otherwise leveraged to create new functionality in GitLab. For example, the label lists in issue boards use the smaller primitive of labels.
They are especially powerful because they usually take less effort and provide higher leverage than you would get from a more "complete" but standalone feature. Think of how simple Unix command line utilities can be chained together to do really complicated things, much easier (and certainly more flexibly) than you could have done with a dedicated tool.
When iterating on GitLab, strongly consider using small primitives instead of creating new abstractions, especially when considering MVC features that will provide the foundations for further improvements. To do this you can start with easy to apply concepts that meet the needs of intermediate to advanced users; from here document the usage clearly and be sure to think about discoverability. The UX can very often be refactored or enhanced later when there's a demonstrated need for refinement, onboarding for less sophisticated users, or other new abstractions needed that were identified through real-world usage.
Closed source software vendors commonly depend on plugins and marketplaces because:
Because GitLab is an open core product, third parties can add functionality directly to GitLab. Adding directly to the GitLab codebase (as opposed to building a plugin) may mean more work for them and will limit the ways in which they can charge for that functionality.
However, for users of GitLab, this has significant advantages:
And for developers of GitLab including the third parties, this has significant advantages as well:
Overall, we believe that this approach creates the best possible experience for both the users of and the contributors to GitLab, and to that end we encourage people to contribute functionality to GitLab directly.
If adding code directly to GitLab isn't an option, we encourage third-parties to integrate through our APIs.
Note: GitLab does support plugins that respond to system hooks, which tie directly to application events and are primarily used for administrative purposes such as auditing, logging, and other administrative tasks.
While our big, hairy, audacious goal spans all development processes, personas, and use-cases, there are primary targets in each one of these venues. When considering prioritization we should first aim to provide complete maturity for developers building cloud native applications in a modern way prior to moving to other development methodologies, personas, and application types.
When developing features to compete with existing competitors, make sure to solve problems for modern development teams first, and then see what's missing for legacy teams. e.g. For project management, make great project management capabilities for teams doing conversational development, lean, or even agile development before doing Scaled Agile Framework (SAFe) or waterfall.
It's important that modern first does not mean non-modern never. It means that we should first learn how teams are using the feature in a modern way, and then see what's missing. The modern way provides the path forward, and then we can add customizability or the path to modern for teams who are not quite there yet.
Our strategy includes going after a lot of new personas, going from developers to operations, security, product managers, designers, etc. But when developing features in these new areas, it's important to remember to start with the developer. If we can make security great for developers and then great for security professionals, we'll be much more successful.
Development teams deploy to tons of different platforms, from bare metal to cloud VMs to cloud-native Kubernetes clusters. We build features for cloud-native first, and then support the rest. This allows us to focus on where development is going, and deliver solutions that every company aspires to use eventually, even if they're not ready to today.
By focusing on next-generation development flows, personas, and use cases - we build features and experiences where our initial users are in the relatively small population of early adopters. While we might build experiences to support them today, we presume there will always be a much larger population of future users of these experiences. Therefore, we optimize GitLab to support the larger number of current and future adopters of next-generation principles - those who are beginning to operate in the workflow (modern), team setup (developer first), or application architectures (cloud native) we support. We focus our investment in the most modern workflows that will best support those current adopters. This will come at the cost of sustained investment in initial workflows for early adopters.
For example - we first provided an application log experience based on direct scraping of logs via kubectl. After adding support for installing Elasticsearch to your Kubernetes cluster, we should not continue to invest in the kubectl log view as we'd recommend newcomers to use Elasticsearch.
We believe that a single application for the DevOps lifecycle based on convention over configuration offers a superior user experience. The advantage can be quoted from the Wikipedia page for convention over configuration: "decrease the number of decisions that developers need to make, gaining simplicity, and not necessarily losing flexibility". In GitLab you only have to specify unconventional aspects of your workflow. The happy path is frictionless from planning to monitoring.
We're doubling down on our product for concurrent DevOps which brings the entire lifecycle into one application and lets everyone contribute. We are leaning into what our customers have told us they love: our single application strategy, our pace of iteration, and our deep focus on users.
Consider opportunities to take advantage of this unique attribute in early iterations. Integrating features with different parts of the application can increase the adoption of early iterations. Other advantages:
Although not every feature needs to be integrated with other parts of the application, you should consider if there are unique or powerful benefits for integrating the feature more deeply in the second or third iteration.
GitLab.com runs GitLab Enterprise Edition.
To keep our code easy to maintain and to make sure everyone reaps the benefits of all our efforts, we will not separate GitLab.com codebase from the Enterprise Edition codebase.
To avoid complexity, GitLab.com tiers and GitLab self-managed tiers strive to match 1:1.
Since we are not able to give admin access and do not yet have full feature parity between self-managed instances and GitLab.com, we avoid saying that there is a one to one match between subscription levels and tiers in marketing materials. This has been a source of confusion in the past for customers.
GitLab.com subscriptions work on a namespace basis, which can mean:
This means that group-level features are only available on the group namespace.
Public projects get Gold for free. Public groups do not get Gold for free. Because:
Admittedly, this is complex and can be confusing for product managers when implementing features. Ideas to simplify this are welcome (but note that making personal namespaces equal to groups is not one of them, as that introduces other issues).
Keep in mind that the CEO is the DRI for pricing and tiers. This includes any changes that directly impacts how we charge customers under our licensing model, such as a change to how we handle active users. Please review the entirety of the stewardship and pricing pages before making any determinations of which tier a given feature should go in.
When making a decision on the tier for a new feature, please refer to the pricing page for guidance. Be sure to consider documenting your rationale for the decision in the issue description, including a reference to our stewardship page when appropriate.
Please indicate the applicable tier for an issue by applying the label associated with the tier (e.g.
GitLab Starter) and the
Enterprise Edition label for features targeting a paid tier. Ensure this is defined before feature development begins.
Should you have any questions when making this decision, do not hesitate to collaborate with your manager, product leadership, or the CEO in the issue for clarification.
To propose bringing a feature to a lower tier, follow the process on the CEO pricing page.
If you are considering launching a paid feature, or changing any other aspect of pricing, follow this process:
Once a final determination has been made, consider making the confidential issue non-confidential. Ensure product marketing has a related website page for the feature and price. Ensure documentation is updated to accurately portray all facets of the feature. Consider a blog post to outline the feature.
All Starter, Premium, and Ultimate features must:
Occasionally we need to test large, complex features before we are confident that we'll be able to scale, support and maintain them as they are. In this case we have the option to release them as Alpha or Beta versions.
In general, we should avoid releasing Alpha or Beta versions of features. A minimally viable change should be viable and therefore should not need a pre-release. That said, if there is a situation where we have no valid alternative, the definitions of each stage is below.
It's never acceptable to make changes that risk any damage to existing production data accessed by our users.
Similar to Beta, but only available to selected users.
Passed the Production Readiness Review for GitLab.com, which means that it is:
Deprecating features follows a particular pattern.
Use the language
Removed to specify the state
of a feature that is going to be or is removed.
Features that are deprecated or removed should be:
Naming new features or renaming existing features is notoriously hard and sensitive to many opinions.
The bar for renaming existing features is extremely high, especially for long-time features with a lot of usage. Some valid but not exclusive reasons are:
Use this section as guidance for using existing features and developing new ones.
/admin. Outside of that, admins are the same as the highest possible permission (owner).
To keep the permissions system clear and consistent we should improve our roles to match common flows instead of introducing more and more permission configurations on each resource, if at all possible.
For big instances with many users, having one role for creating projects, doing code review and managing teams may be insufficient. So, in the long term, we want our permission system to explicitly cover the next roles:
All the above can be achieved by iteratively improving existing roles and maybe adding one more.
Also see our Secure Team engineering handbook.
Traditionally, applications only reveal valuable information about usage and performance to administrators. However, most GitLab instances only have a handful of admins and they might not sign in very often. This means interesting data is rarely seen, even though it can help to motivate teams to learn from other teams, identify issues or simply make people in the organisation aware of adoption.
To this end, performance data and usage statistics should be available to all users by default. It's equally important that this can be optionally restricted to admins-only, as laws in some countries require this, such as Germany.
GitLab is developed in English, but supports the contribution of other languages.
GitLab will always default to English. We will not infer the language / location / nationality of the user and change the language based on that. You can't safely infer user preferences from their system settings either. Technical users are used to this, usually writing software in English, even though their language in the office is different.
Fast applications are better applications. Everything from the core user experience, to building integrations and using the API is better if every query is quick, and every page loads fast. When you're building new features, performance has to be top of mind.
We must strive to make every single page fast. That means it's not acceptable for new pages to add to performance debt. When they ship, they should be fast.
You must account for all cases, from someone with a single object, to thousands of objects.
Read the handbook page relating to performance of GitLab.com, and note the Speed Index target shown there (read it thoroughly if you need a detailed overview of performance). Then:
You must prioritize improvements according to their impact (per the availability & performance priority labels). Pages that are visited often should be prioritized over pages that rarely have any visitors. However, if page load time approaches 4 seconds or more, they are considered no longer usable and should be fixed at the earliest opportunity.
The ability to monitor, visualize and improve upon cycle time (or: time to value) is fundamental to GitLab's product. A shorter cycle time will allow you to:
When we're adding new capabilities to GitLab, we tend to focus on things that will reduce the cycle time for our customers. This is why we choose convention over configuration and why we focus on automating the entire software development lifecycle.
All friction of setting up a new project and building the pipeline of tools you need to ship any kind of software should disappear when using GitLab.
We understand that not everyone will use GitLab for everything all the time, especially when first adopting GitLab. We want you to use more of GitLab because you love that part of GitLab. GitLab plays well with others, even when you use only one part of GitLab it should be a great experience.
GitLab ships with built-in integrations to many popular applications. We aspire to have the world's best integrations for Slack, JIRA, and Jenkins.
Many other applications integrate with GitLab, and we are open to adding new integrations to our technology partners page. New integrations with GitLab can vary in richness and complexity; from a simple webhook, and all the way to a Project Service.
GitLab welcomes and supports new integrations to be created to extend collaborations with other products. GitLab plays well with others by providing APIs for nearly anything you can do within GitLab. GitLab can be a provider of authentication for external applications.
There is some natural tension between GitLab being a single-application for the entire DevOps lifecycle, and our support for better user experience via integration with existing DevOps tools. We'll prioritize first our efforts to improve the single-application experience, second to enable a rich ecosystem of partners, and third to improve integration with the broader ecosystem to other tools. GitLab is open-source so this should not prohibit contributors adding integrations for anything that they are missing - as long as it fits with GitLab product vision.
If you don't have time to contribute and are a customer we'll gladly work with you to design the API addition or integration you need.
In pursuit of our product vision of becoming a complete platform for the entire DevOps lifecycle, delivered as a single application, GitLab will inevitably compete for user and business with other DevOps tools technologies and vendors. For clarity, GitLab publicly competes with other vendors only in categories where our product is lovable (in our maturity model). We may at times name these competitors publicly.
For all other categories, GitLab will highlight examples of tools that have functionally similar features to the features GitLab is developing, but we will not name them as explicit competitors. This does not mean that we will not be trying to acquire users or business based on those categories, but it does mean that we will not refer to those other vendors as 'competitors', as our goal is to pursue our product vision (not to specifically win against other tools or vendors where we are not yet lovable).
This is the Product handbook. If you (a Product team member, a GitLab team-member, or anyone else) see any typos or small copywriting errors here, consider correcting them with a merge request and merging it yourself (provided you have merge permissions to this repository), and mentioning a Product team member afterward as a courtesy so that we can thank you, since we have a bias for action and trust your judgement. If you have a larger change (or don't have merge permissions), create a merge request and mention any Product team member for further review so that we can incorporate your change (if it makes sense) as soon as possible. Please don't assign anybody to the merge request.