The document below talks about how we do product at GitLab, not about what. For the what, see Product Direction.

Where to reach product managers

On this page

Who to talk to for what


Please see the Product Categories to know what product manager handles what category.


If you have any product-related questions, comments, input, or otherwise, the product manager is the primary person you should talk to, if creating an issue does not suffice. Otherwise, read this section on how to create an issue.

This includes, but is not limited to features, bugs, and other changes that need more attention, to be prioritized, to be changed, or to be discussed.

Product managers will reach out to stakeholders in making or communicating any decision. The weight of balancing priorities and ensuring we build excellent software is on the product manager and they will need all the input they can to achieve this.

Paid features fall under their respective PM, not under one PM in particular. For instance, Service Desk falls under Victor, because it's part of our Issues.

See our product categories for how to map our product to product managers.

Technical Writing

The Technical Writing team is responsible for:

We are there to assist developers in their documentation writing process by providing copy editing and reviewing services and are not responsible for writing the first draft of documentation for new or updated features.

We will maintain and improve the overall health of documentation e.g. by creating topic index pages, improving organization and creating tutorials.

We manage our documentation tasks for CE and EE on the following issues boards which track labels beginning with docs-:

Planning horizon

  1. Mission: generation
  2. Strategy: lustrum
  3. Vision: year
  4. Milestones: quarter (we have issues assigned to specific release milestone for a rolling 3 months)
  5. Release: month (we try to not change the release that is started)

Inspired by:

How to work as/with product

At GitLab, the PM leads their specialization. That is, the Platform PM decides what is being worked on by the platform team in which release and makes sure this furthers our goals. This includes bugs, features, architectural changes.

The PM can't be expected to parse every single bug, issue that comes by, so they will have to rely heavily on the input of the various stakeholders. To be able to achieve this, both the PM and the stakeholders have to actively work together. It's a two-way street.

In general terms, if you require something to happen with the product or if you need engineering staff for a particular change, you approach a PM. Preferably through creating an issue, the GitLab way and mentioning them there.

In the same vein, PMs are required to ask for feedback from the stakeholder of particular changes. If a change will affect and its maintenance, a PM should proactively reach out to infrastructure engineers to help with the scoping, design and decisions on this change.

It is then up to the PM to weigh all these inputs and decide on a prioritization. It is to be expected that they are best equipped to make this prioritization, keeping in mind all goals of GitLab.

Example: A customer has a feature request

If you hear a feature request from a customer, you should follow the normal procedure: you create an issue and label it correctly. Let's say the customer requests an enhancement to Issues. You know by reading above that you'll have to label this with Discussion and you can mention or reach out to Victor to expedite this if warranted.

A salesperson for an organization asking for a paid-tier feature request shall work with the product manager to arrange conversations to further explore the feature request and desired outcome. The process will be:

Example: Many support requests come in about a bug with CI

Same as before, make sure an issue is made and make your case with Mark on that this is becoming a problem and needs to be fixed. Mark will make sure that this is fixed or resolved in some other way.

Example: I think creating new files is slow

Everything in GitLab should be fast and creating files falls under the repository, so you create an issue and make James aware of it by mentioning it.

James in turn will investigate whether this is a general problem or one specific to, in collaboration with infrastructure and others and schedule any necessary changes for an upcoming release.

Product Process

Introducing changes requires a number of steps, with some overlap, that should be completed in order:

Prioritization: Ahead of kickoff

  1. Proper discovery has been done and requirements for the change are defined
  2. Engineering has been involved in the discovery process (FE, BE, UX, as needed)
  3. Technical architecture has been drafted and is agreed upon
  4. Scoping and splitting up in issues has happened


  1. Design
  2. Backend development
  3. Frontend development
  4. QA and feature assurance
  5. Deploy

QA RCs on staging and elsewhere

After the feature freeze, it's expected of each product manager to test their own features and perform quality assurance to the best of their ability and follow up where necessary.

Product managers can use the staging environment, once the release managers have deployed a release candidate on staging. Release managers should post in the #product channel in Slack that a new release candidate is available. Product managers can also use other environments as needed, such as GitLab provisioned on Kubernetes with GKE.


Goals of Product

Everyone at GitLab is involved with the product. It's the reason why we are working together.

With every release of GitLab, we want to achieve each of the following goals.

  1. Improve GitLab's existing tools.
  2. Achieve our vision of a complete toolset.
  3. Make our product more interesting for our customers through Products and EE exclusive features.

Scope of responsibilities

The product team is responsible for iteration on most of GitLab's products and projects:

This includes the entire stack and all its facets. The product team needs to prioritize and weigh bugs, features, regressions, performance, but also architectural changes and other changes required for ensuring GitLab is excellent.

Product at GitLab

GitLab is designed and developed in a unique way.

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.

Much of our product philosophies are inspired by Ruby on Rails doctrine of 'Rails is omakase'. I highly suggest reading these.


  1. Minimally Viable Change: Work in iterations by implementing only the minimally viable change.
  2. Convention over Configuration: Avoid configuration and make it work out of the box.
  3. Be Ambitious: do things no one else is doing.
  4. Do not mess with Flow: frictionless from planning to monitoring. Avoid adding clicks.

Product Core Values

The Minimally Viable Change

Reduce every change proposal to its very minimally viable form. This allows us to ship almost anything within a single release, get immediate feedback and avoid deep investments in ideas that might not work. Other advantages:

The minimally viable change should not be a broken feature.


Virtually every new feature must be maintained forever. (The standard of sunsetting a feature is very high.) Creating a new feature means that GitLab has to maintain the technical costs of maintenance over time. Making small changes with quick feedback loops reduces the risk of introducing a new feature where the value doesn't justify the long-term costs.

A new feature also adds a tax on the user experience due to additional complexity in the product. Make sure that the benefits accrued to users by that new feature more than cover the tax incurred, accounting for how frequently that the new feature is used by users. In particular, the new feature should satisfy this inequality:

(benefits * frequency) / (tax * (1-frequency)) > 1

Despite its minimal form, the change

Convention over Configuration

Prefer choices that are well thought out, based on current best practices. Avoid unnecessary configuration.

For example, when considering adding a checkbox or two radio boxes, think really hard what users really want. Most of the time, you'll find you really only need one solution, so remove the option. When two possible choices really are necessary, the best or most common one should be default, and the other one should be possible. If the non-default choices are significantly less common, then consider taking them out of the main workflow for making decisions such as putting them behind an Advanced configuration tab.

Every configuration in GitLab multiplies its complexity, which means the application is harder to use, harder to develop, and less friendly to its users.

Making features configurable is easy and lazy. It's a natural reaction to propose a big change to be configurable, as you worry it'll negatively affect certain users. However, by making a feature configurable, you've now created two problems.

Work on solutions that work for everyone, that replace all previous solutions.

Sometimes configuration is inevitable or preferable. GitLab should work perfectly right out of the box for most users. Your configuration can't make that experience worse and should always get out of the way of the user.

Encouraging behavior

Convention also implies that we're encouraging our customers to do things in a certain way. A very concrete example of this is the ability to disable pipelines.We believe that our integrated solution will give a superior user experience and we're motivated to encourage behavior. For this reason, adding a configuration to be able to disable this permanently (be that in template or instance-wide), is something that should be avoided.

Encourage favorable behaviors by limiting configuration.

Default to ON

In addition to encouraging behavior by limiting the ability to toggle features, when introducing new features default to turning things ON if they are configurable at all.

Deciding on configurations

Avoiding configurations is not always possible. When we do have to make this choice, the second order of preference is to configure something in the GitLab interface. Only as a last resort should a configuration appear in file (gitlab.rb or gitlab.yml).

Configuration in file

There are two major configuration files available in GitLab. It should be avoided to add new configurations to either.

When you have to add new configuration, make sure that the features and services are on by default. Only add a configuration line to either of this configuration files if the feature or service cannot be fully disabled from the admin UI.

Convention over configuration is also listed in the CONTRIBUTING file in GitLab's repositories.

Be Ambitious

Many crazy, over-ambitious ideas just sound like they are impossible because no one else is doing them.

Because we have amazing engineers and a culture of shipping a minimally viable change, we are able to do a lot more 'impossible' things than other people.

That's why we're shipping merge conflict resolution, why we shipped built-in CI before anyone else did it, why we built a better static pages solution, and why we're able to compete.


Doing something simple in GitLab should be simple and require no human cpu-cycles to do so. Things that are simple now, should be simple in two and ten years.

This sounds obvious, but messing with Flow is easily done. In most cases, flow is disrupted by adding another action, 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 certain behaviour, the most obvious step is 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 behaviours.

We don't want users to be able to construct workflows that break GitLab or make it work in unpredictable ways.

Discoverability Without Being Annoying

Feature discoverability is important to allow existing and new users to access old and new features, thereby increasing the value for them, and allowing GitLab to get as much feedback as possible, and as soon as possible, in order to quickly iterate.

However, if not carefully designed and implemented, UI that purports to increase discoverability 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, so that 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.

Empty states



Think of this: Your co-worker is hard at work in front of their computer. 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. Your 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 that up again. They told you they don't care. You need to respect that.


Leveraging navigation is an effective design paradigm to introduce a user to a new feature or general area of GitLab.

Back to the analogy. We're not going to bother our co-worker with 5 different cool new widgets at the same time.


Breadth over depth

See our thoughts on breadth over depth on our strategy page.


As this document and the direction page will show you, there are a million things we want to do, so how do we prioritize between them and schedule anything in particular? Roughly speaking, we balance the following priorities:

  1. Security fixes
  2. Data-loss fixes
  3. Regression fixes (things that worked before)
  4. Performance fixes
  5. Technical debt fixes
  6. Other fixes
  7. New features

Any new feature will have to meet the following requirements:

  1. It is technically viable
  2. The technical complexity is acceptable (We want to preserve our ability to make changes quickly in the future so we try to avoid: complex code, complex data structures, and optional settings)
  3. It is orthogonal to other features (prevent overlap with current and future features)
  4. The requirements are clear
  5. It can be achieved within the scheduled milestone (Larger issues should be split up, so that individual steps can be achieved within a single milestone)

New features are prioritized on a couple of dimensions:

Every release of GitLab has to be better than the last. This means that bugs, regressions, security issues, and necessary performance and architecture changes always take up the capacity they require to ensure GitLab remains stable, secure and fast.

We hope to realize our vision, while making sure we're building things that our customers want. In practice this means we aim to ship one or more features that preferably fit within our vision, but also solve problems our customers have. These features bring the product forward, and build value for the largest group of people possible. E.g. issue relationships is a highly requested feature and one that fits neatly within our vision. Everyone will benefit from this.

In practice, it is not always possible to only ship things that strictly fall within our vision. Other changes are prioritized and scheduled based on demand. An example would be a specific form of authentication that is only used in particular organizations. This is not a big win to all our customers, but if it's not too much work, can be very big win to a subset of customers. Demand can also come internally, such as things that'll help achieve goals within the team or specifically drive business goals, such as particular EE features.

We take all priorities in account when planning and schedule larger initiatives across the teams (such as: we're integrating CI: everyone has to contribute to this in some way), but most changes are scheduled at a team-level (make issues faster; add a new way to schedule pipelines).


To make it concrete with an example, the CI/CD team might ask:


We schedule an issue by assigning it a milestone; for more on this see Planning a Future Release.

Naming features

Naming new features or renaming existing features is notoriously hard and sensitive to many opinions.

Factors in picking a name



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:

No enforced workflows

Enforced workflows should be avoided in GitLab. For example, there are three issue states (Open, In Progress (as of 10.2), and Closed), and any issue should be allowed to transition from one state to any other state (including itself) any 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 …:

  1. Your admin(s) set it up once and hasn't bothered to iterate on those workflows.
  2. The business mapped their autonomy stripping processes onto JIRA intentionally. I'd guess that most of your work experience is similar. Process stifled nonsense.

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:


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, 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 that new pages add to performance debt. When they ship, they should be fast.

You must account for cases where someone has thousands of objects or just a single.

Read the handbook page relating to performance of, and the Speed Index targets shown there. Then:

Of course, you must prioritize improvements according to the impact (per the availability & performance priority labels). Pages that are visited often should be prioritized over pages that rarely have any visitors. However, as page load time approaches 4 seconds or above, they are no longer useable and should be fixed at the earliest opportunity.

For a detailed in-depth performance overview, see the engineering performance page.

Alpha, Beta, GA

Occasionally we want to test large, complex features without having the confidence 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.

In general, we should avoid releasing Alpha and Beta versions of features. A minimally viable change should be viable and therefore not need a pre-release. That said, if it comes to be that we have no valid alternative, below the definitions of each stage.

It's never acceptable to make changes that can damage existing production data available to our users.


Closed Beta

Similar to Beta, but only available to selected users.


Generally Available (GA)

Passed the Production Readiness Review for, which means that it is:

Discouraging, deprecating and removing features

Deprecating features (changes) follows a particular pattern. Use the language Discouraged (maintained), Deprecated (not maintained) or Removed to specify the state of a feature that is going to be or is removed.

Features that are discouraged, deprecated or removed should be:

  1. Labelled accordingly in the documentation
  2. Labelled accordingly in the application

Features that are Deprecated or Removed should be removed from marketing pages.

Discouraged (maintained)

Deprecated (no longer maintained)


No artificial limits in Core

Per GitLab Stewardship, we will not introduce artificial limits in Core. Artificial means arbitrarily setting a small number (such as, one) as a limit on a given GitLab object category, that would incur no additional effort 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.

Data-driven work

Using data to learn from our users is important. Our users are across and self-hosted 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:

Single application

As you know, GitLab is a single application, rather than a set of loosely connected compenents. This is a big advantage, read why here.

Working with (customer) feature proposals

When someone requests a particular feature, it is the duty of the PM to investigate and understand the need for this change. This means you focus on what the problem is that the proposed solution tries to change. Doing this allows you often to find that:

  1. An existing solution already exists within GitLab
  2. Or: a better or more elegant solution exists

Do not take a feature request and just implement it. It is your job to find the underlying use case and address that in an elegant way that is orthogonal to existing functionality.

This prevents us from building an overly complex application.

Take this into consideration even when getting feedback or requests from colleagues. As a PM you are ultimately responsible for the quality of the solutions you ship, make sure they're the (first iteration of the) best possible solution.

Security Paradigm

Security is now part of SDLC thanks to our Security Products.

The checks provided (SAST, DAST, etc.) are meant to drive security, and not to enforce it. That's why, even if some vulnerabilities are affecting the application, we should never block users by making the build fail.

The signal we get is not perfect, and security is always about tradeoff. The issues reported by our tools might contain false positives, so instead of notifying the users with a binary report ("affected"/"not affected"), the result of our checks must be more granular, and suggest an order of priority based on various metrics:

Risk assessment will always be part of a human process. Instead of wishful thinking where users will blindly use predefined whitelists, we want them at the center of the process. Our products are "decision support tools", not "decision-making tools".

Just like in incident responses, where there are always too many warnings to follow up with, security reports often include an exhaustive list of every issue found. You can't follow up on everything and need help to prioritize what is the next thing you want to work on.

If a security feature is too complex/hard to use, it will be ignored, or even worse, disabled. For example, when dismissing a vulnerability, if the reason is required, this extra step will add a workload on final users. This information is not necessary to the feature, and we can still improve the Signal-to-noise ratio without it. Security features should not be a burden: imagine if users had to explain why they are marking an email as spam every time!

We should give the people responsible for security an accurate realtime view of where the most pressing security issues are. GitLab should give them visibility and a way to communicate with developers, it should not blindly be turning people away at the gate but it should connect them instead.

Statistics and performance data

Traditionally, applications only surface 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 rarely gets 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, perfomance data and usage statistics should be available to all users by default. It's equally important that this can be restricted to admins-only, as laws in countries such as Germany require this.

Not all instance-data is avaialble yet to all users in GitLab. This issue and the epic above should solve this.

How to work as a PM

If you follow the guidelines above, you won't be writing long, detailed specs for a part of the product for the next year. So how should you be spending your time?

Invest the majority of your time in understanding the problem deeply (say 70%). Then spend 10% of your time writing the spec for only the first iteration and handling comments, while the remaining 20% you work on promoting it.

A problem you understand well will always have a (seemingly) simple or obvious solution. Reduce it to its simplest form (see above) and only ship that.

Once you've shipped your solution, both you and the community will have a much better idea on what can be improved and what should be prioritized for future iterations.

As a PM you're the person that has to kick-off new initiatives. You're not responsible for shipping something on time, but you are responsible for taking action and setting the direction. Be active everywhere, over-communicate and sell the things you think are important to the rest of the team and community.

As a PM, you need to set the bar for engineering; to push engineering and the rest of the company. You almost want engineering to complain about the pace that product is setting. Our default instinct will be to slow down. We can't give in to that.

As a PM you don't own the product: ask other people for feedback and give team members and the community the space to suggest and create without your direct intervention. It's your job to make sure something is decided and planned, not to come up with every idea or change.

Dogfood everything

The best way to understand the pain of the users is to go through what we ask them to do while setting up or using GitLab. As a PM, you should go through every feature, at the minimum the ones you are responsible for. All of them. That includes features that are not in GitLab's UI directly but require server configuration. If you, as a PM, can't understand the documentation or struggle to install something, who else would even bother to do it? Going through this is not only beneficial to understand what the pain points are, it will also tell you what you can enhance, from a better flow to a better documentation.

As a Product function, it is our responsibility to ensure that the entire company is dogfooding.

Example: configuring GitLab

Most of GitLab is configured through the file gitlab.rb. It's tempting to add a new parameter in this file - it's easy, fast to do, and won't require to add a new UI to allow the configuration of this new setting. However, changing this file requires you to reconfigure GitLab. To do that, you have to login to your server and type in commands to reconfigure your instance. Possibly, multiple times if you have more than one server.

This is not something that we can ask our customers to do. Only by using your own product and features, will you realize that some practices should be avoided if you can.

Product Workflow

Almost everything that we do is documented in an issue.

How to submit a new issue

  1. If you have time, the first thing you should do is search both CE and EE projects if a similar issue already exists. We shouldn't create duplicates if we can avoid them.
  2. Identify if the issue is about GitLab Community Edition (CE) or GitLab Enterprise Edition (EE), although this can easily be changed later.
  3. You should clearly state what the current pain point is, what we are trying to solve, what the benefits will be, what it should do, how to accomplish that and the next steps.
  4. The issue's body should be written in a clear way, without ambiguity.
  5. If the body of the issue contains too many paragraphs, it can surely be rewritten to be shorter.
  6. Do not use acronyms or abbreviations. Everyone should be able to jump on the issue and participate without needing a glossary.
  7. Choose which labels are relevant to the issue. If you are unsure about what certain labels are for, head up to the Labels page (CE or EE) and read the descriptions. The contributing doc provides a breakdown of the label types and how they should be applied. on how to choose the right label.
  8. Unless you know what you are doing, do not
    • assign someone to the issue
    • assign a milestone
    • set a due date
    • add weight - weight represents the technical complexity and should be defined by our developers
  9. Mention the different stakeholders in the body of your issue. In most product related issues, we usually mention the product manager, the design, frontend, and backend managers as appropriate. Some teams have experts or liaisons that can be mentioned instead of the managers. Mentioning the people in the body issue will trigger the notification mechanisms chosen by the people who are mentioned - therefore there is no need to notify people in another channel after the issue has been created (Slack, email).

How to use epics

Issues related to an iteration of the same feature should be bundled together into an epic. Epics:


When relevant, you can include a wireframe in your issues in order to illustrate your point. You don't need to include wireframes per se - our UX/design team can help us on that matter. Simply ping them if you need their help. We like Balsamiq for its simplicity and its sketch-y approach. If you don't have inspiration, you can also paste screenshots of similar features in other products.

What is a Meta issue?

Meta is a label assigned to issues that contain a large list of todos. If you are familiar with the Agile methodology, it's similar to an epic. At GitLab we have a short release cycle: the 22nd of every month. In some cases we won't be able to tackle all the tasks of a meta issue in a single release - this is why we centralize all the things that we need to do in a meta issue, then break it down to issues small enough that they will fit into one release. Most of the time, meta issues generate lots of comments and passionate discussions. As a consequence, they always lead to something great.

Meta issues themselves generally should not be assigned to a milestone as the actual work is expressed in sub-issues. Sometimes, if you want the meta issue to show up in our direction page with a given release, you may want add a milestone, but only if you know for sure that all sub-issues will be completed by that milestone. Don't assign a milestone for when you're going to start the meta issue.

Long-lasting issues

A general guideline is that an issue should only span one release. If we know an issue is going to span multiple releases, split it up in multiple issues.

Meta/epic issues are the exception to this rule, but should be kept to a minimum and only serve to guide broader subjects, not a single feature over multiple releases. This to make sure we stick to our values of the minimally viable change.

The above means that feature issues should be closed after a first iteration whenever possible. We'll know more in the future and this keeps remaining issues short and actionable.

In addition, it's almost never a bad idea to throw away an original plan and start fresh. Try to do this more often than you're comfortable. Close the issue and create a new one.

Which issue should you be working on?

When you don't have specific tasks assigned, you should work on issues that are labeled Product work, in both EE and CE projects. These are issues that need our attention the most.

Feature assurance

Before a new features is shipped, the PM should test it out to make sure it effectively solves the original problem. This is not about quality assurance (QA); developers are responsible for the quality of their code. This is about feature assurance (FA). Feature assurance is necessary because sometimes there are misunderstandings between the original issue proposal and the final implementation, sometimes proposals that seem like they would solve the problem actually don't, and sometimes solutions just don't feel as good when implemented.

If you can test out the feature during development, pulling down branches locally (or with a review app!), that's great. But sometimes it's not convenient to test a feature until it's bundled into a release candidate and deployed to If so, make sure to test out features as soon as you can so any new issues can be addressed before final release. Also, take the FA cycle into account when scheduling new milestone work.

Managing Upcoming Releases

Refer to the Product Development Timeline for details on how Product works with UX and Engineering to schedule and work on issues in upcoming releases.

Planning for Future Releases

Product Managers assign milestones to issues to indicate when an issue is likely to be scheduled and worked on. As we consider farther out milestones, the certainty of the scope of their assigned issues and their implementation timelines are increasingly vague. In particular, issues may be moved to another project, disassembled, or merged with other issues over time as they bounce between different milestones.

The milestone of an issue can be changed at any moment. The current assigned milestone reflects the current planning. If the plan changes, the milestone should be updated as soon as possible to reflect that changed plan.

Approximately, closer-to-current-time milestones are assigned to issues that are higher priority. The times also reflect an approximate product roadmap, with further out milestones reflecting increasing uncertainty.

The milestones are:

These assigned milestones should be used as a signal for GitLab stakeholders and collaborators to help them with their own respective workflows.

In addition we have a Backlog milestone. Product Managers assign this milestone to issues that they think make sense in the product, but don't have yet a clear timeline of when it should be worked on. Again, a milestone of an issue can be changed at any moment, including the Backlog milestone.

We make sure to do this ahead of starting to work on a release. Capacity is discussed between the PMs and the engineering managers.

For a detailed timeline, see the product development timeline.

Content of an MVP

We only ship in a Minimally Viable Product mode. Here are some guidelines about it:

When to create or close an issue

You should create an issue if:

You should consider not creating an issue when:

Close issues that are either:

  1. duplicated elsewhere.
  2. no longer relevant due to other reasons.
  3. 'not the next iteration': an iteration on a proposed feature that is unlikely to ship in the next few months.

When closing an issue, leave a comment with why you're closing the issue and link to anything of relevance (the other duplicate, the original feature that this is an iteration on).

The 'not the next iteration' is the most important one to resolve. It is very easy to create a big plan with meta issues and lots of But it is essential that we iterate and ship the minimum viable change. We have to ship the iteration, wait for it to be used, and listen for the feedback. As a product manager you think about the bigger picture when making a proposal to improve the product. The important thing is to not write this down is a bunch of issues. Think of a plan but only record the first step. This we we can preserve the efficiency of our value of iteration. Closing issues whenever possible is an important part of your job and helps to keep a good overview of what is next. Consider using the following template to close the issue:

Closing this because XXX is something we should do first. If that feature is done we can learn from having that being used. If we learn that this is still relevant we can then reopen it. See /handbook/product/#when-to-create-or-close-an-issue for more detail about this policy.

Competition Channel

When someone posts information in the #competition channel that warrants creating an issue and/or a change in features.yml, follow this procedure:

Where should you look when you need help?


Internal and external evangelization

Before shipping a new or updated feature, you are responsible for its evangelization, both internally and externally. When something is released, the following teams need to be aware of it as they will all need to do something about it:

You can promote your work in several ways:

GitLab University

To promote a major new feature internally, you can ask to host a GitLab University, a company wide demo session. This is a great opportunity to make sure every one is on the same page.

Major feature rollout

Major features deserve proper attention from product and marketing. With a proper rollout, we'll have ample marketing opportunities and receive more feedback ahead, during and after the release.

Here is the ideal rollout schedule. For each step, there is the indication about who is responsible for it.

  1. Feature is drafted in an issue (PM)
  2. Feature is planned in an upcoming release (PM)
  3. A feature proposal blog post is made (PM or Dev), where we'll describe
    • What we are planning on doing,
    • How you'll be able to buy it: CE or any EE Editions,
    • Link to the issue,
    • When it'll be available, if possible,
    • Anything else that is interesting to share in order to fuel the discussion.
  4. Feature is implemented, documentation is written (Dev).
  5. Feature should appear on the website (Marketing)
    • For very significant features: Feature page on the website is made and pushed, with the mention "Available from X.X"
    • For other features: Feature should be listed on some page (/comparison, Enterprise page, /features page).
  6. Feature is launched with the release (Marketing)
    • "Available from X.X" is removed
    • Documentation and other resources are linked
    • Pricing page is updated if needed
  7. Feature is highlighted in a blog post (Marketing)
    • This post is linked from the feature page on the website (if applicable)

Communicating product vision

Occasionally, we rally around a product vision, a direction to aim towards, to gain alignment internally and externally. We'll usually start out with a clear, simple concept like going faster from idea to production, or shipping complete DevOps. We happened to announce our first Master Plan as part of our Series B funding announcement, and our second master plan with our Series C announcement. While the first iterations and presentations are great to align the product team and announce the vision to the world, the text and slides only go so far to convey the depth of the vision. So we usually iterate on the vision by fleshing it out in varying stages and communicating it in various ways, usually increasing in fidelity.

For example, we might start with:

The video of the interactive prototype is a good time to reiterate the vision with a blog post.

How and when to reject a feature request

Rejecting a feature request or a merge request is not an easy thing. People can feel quite protective of their ideas. They might have invested a lot of time and energy in writing those ideas. You can be tempted to accept a feature only to avoid hurting the people who thought of it. Worst, if you reject an idea too harshly, you might discourage other people to contribute, which is something we want to avoid.

However, as the number of issues and merge requests grow more and more, we should be diligent about rejecting features we are sure will not do. It's better for everyone: for the product team so we don't maintain a huge backlog of things we will not do anyway, and for the users who won't have to wait for our feedback indefinitely.

Note: it's fine to not respond to issues that we think have potential until they gather momentum.

Feature requests and merge requests can be rejected for the following reasons:

Don't forget to thank the authors for the time and effort taken to submit the feature request/merge request. In all cases and without exception, you should be nice and polite when interacting with users and customers.

Responsibilities and Expectations

As a PM you're expected to:

Customer meetings

It's important to get direct feedback from our customers on things we've built, are building or should be building.

As a PM you should have regular meetings with customers that are using the things you've been working on and with customers that are not - in order to get an idea of why they're not switching to our solution.

Set up a meeting

To setup a customer meeting, identify what you're interested in discovering and prepare appropriately.

You can find information about how customers are using GitLab through sales and Sales and support should also be able to bring you into contact with a customer.

There is no formal internal process to schedule a customer meeting, if that need arises, we can formulate one.

During and after

During the meeting, spend most of your time listening and obtaining information. It's not your job to sell GitLab, but it should be obvious when it's the time to tell more about our products.

After the meeting, make sure all your notes and feedback lands in issues.

Marketing materials

As a PM you're responsible for making sure changes you've shipped are well represented throughout GitLab's documentation and marketing materials. This means that on release, features.yml is updated, documentation is merged and deployed, and any existing content is updated where necessary.

It's not acceptable to do this after the release. GitLab is very complex and features and functions are easily missed, even those that provide significant value to customers (e.g. the many ways you can authenticate with GitLab).

You can recruit the help of the marketing and technical writing team if needed, but it's highly recommend to do small updates yourself. This takes less time and overhead than communicating what needs to be done to someone else.

Release posts

As a PM, you are accountable for adding new features (under your umbrella) to the monthly release post, respecting the guidelines defined on the release posts handbook and its due dates.

Every month, a PM will take the leadership of the release post, being responsible for delivering it in time.

Refer to the release posts handbook to go over all the details.

Communication guidelines for product managers

As a product manager, you're vastly more knowledgeable about GitLab than anyone else. This means that you have the responsibility to always provide a balanced and complete view when discussing anything related to product. Other people won't have the same background and context you might have.

For example, when someone involved in sales asks you about upcoming issues in a particular area, you respond with:

This seems obvious, but a slight misunderstanding can have big consequences: promising a customer that something is done by a certain date vs. indicating that we're working on something and hope to have a first iteration in the near future.

Issue state

When an issue is open, this signals that we're intending or considering implementing that change. It's important to close issues that we're not considering implementing in the near future, so that we avoid creating uncertainty with customers, and colleagues.

When closing an issue for this reason, make sure to update the issue body and leave a comment explaining why the issue is being closed. Issues can be reopened if we change our stance on them.

Working with product marketing (PMM)

Product marketers and managers should be joined at the hip. Just as a feature without documentation should not be considered shipped, benefits of GitLab that we're not actively talking about might as well not exist.

Product marketers rely on product managers to be guided to what is important and high impact. As a general advise, you can:

Permissions in GitLab

Use this section as guidance for using existing and developing new features.

  1. Admin-only features can only be found in /admin. Outside of that, admins see the same as the highest possible permission (owner).
  2. Guests are not active contributors in private projects. They can only see, and leave comments and issues.
  3. Reporters are read-only contributors: they can't write to the repository, but can to issues.
  4. Developers are direct contributors, and have access to everything to go from idea to production, unless anything has been explicitly restricted (e.g. through branch protection).
  5. Masters are super-developers: they are able to push to master, deploy to production. This role is often held by maintainers and engineering managers.
  6. Owners are essentially group-admins. They can give access to groups and have destructive capabilities.

To keep 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.

For big instances with many users, having one role for creating projects, doing code review and managing team can be insufficient. So, in long term, we want our permission system to explicitly cover next roles:

  1. An owner. A role with destructive and workflow enforcing permissions.
  2. A manager. A role to keep a project running, add new team members etc.
  3. A highest development role to do code review, approve contributions, and other development related tasks.

All above can be achieved by iteratively improving existing roles and maybe adding one more.

Documentation on permissions


GitLab is developed in English, but supports contributions 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. Especially technical users are used to e.g. writing software in English, even though their language in the office is different.

Talking about Paid-only decisions

When talking about why a certain change goes into a Paid tier instead of Core, mention the stewardship paragraph in the about page directly and link to it.


Our stewardship of the open source project that is GitLab Community Edition is incredibly important. We are expected to act as good stewards and have to earn that right, this is documented on the stewardship page.

If you want to make any changes to this page, create a merge request and assign it to the CEO.

What goes in what version

Adopting DevOps is a journey in which most organizations follow a typical pattern going from Adopting to Scaling to Optimizing the DevOps lifecycle. Our product versions attempt to align with this journey.

The Simplified Maturity Model provides additional insight into how specific features align with organizations at different stages in their DevOps evolution.

Deciding on whether something should be a Ultimate, Premium, or Starter can be hard. Bringing something down the tiers (e.g. Premium to Starter) is easier than the other way around.

Starter, Premium, and Ultimate requirements

All Starter, Premium, and Ultimate features should:

Pricing plans

For more information about how we think about pricing, please see the pricing page in the handbook.

Designing features for paid tiers

To make it possible to ship a feature for paid tiers, ideally the code is completely separate. I.e. the frontend and backend of the feature only exist in the gitlab-ee project. However, this is not always possible.

In cases where it's preferable to have the backend code live in the gitlab-ce repository, it's acceptable to only ship the frontend for the feature in EE. In practice this makes the feature paid-only.

Bringing features to lower tiers

If you are considering to bring a feature that exists in Premium to Core, for example, follow this process:

After appropriate consideration, update all stakeholders on the decision that you've reached and move forward with making that change (or simply close the issue with the reasoning why not). 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 codebase from the Enterprise Edition codebase.

To avoid complexity, tiers and GitLab self-hosted tiers have a 1:1 match. No exceptions to this rule are acceptable.

Because we are not able to give admin access and do not yet have full feature parity between a self-hosted instance and, we avoid saying that there is a one on one match between subscriptions levels and tiers in marketing materials. This has been the cause of confusion in the past for customers.

Restriction of closed source Javascript

In addition, to meet the ethical criteria of GNU, all our javascript code on has to be free as in freedom. Read more about this on GNU's website.

Private tools and dashboards for monitoring and KPI tracking

Feature usage

EE usage: account

Grafana: Google account

Kibana: account

LogTrail: account

S3stat: GitLab 1Password account

Sentry: account

Writing about features

As PM we need to constantly write about the features we ship: in a blog post, internally to promote something, in emails sent to customers.

While we want every PM to have his unique voice and style, there are some guidelines that one should take into account when writing about features. Let's highlight them with a concrete example, Preventing Secrets in your repositories, that we've shipped in 8.12.

It's a bad idea to commit secrets (such as keys and certificates) to your repositories: they'll be cloned to the machines of anyone that has access to the repository, only one of which has to be insecure for the information to be compromised. Yet it happens quite easily. You write git commit -am 'quickfix' && git push and suddenly you've committed files that were meant to stay local!

GitLab now has a new push rule that will prevent commits with secrets from entering the repository.

Just check the checkbox and GitLab will prevent common unsafe files such as .pem and .key from being committed.

Writing release blog posts

For every monthly release, there is a blog post announcing features. The blog post should contain anything exciting or disruptive. All new features should appear in the blog post. We want to help people understand exciting features (which are often new), and increase adoption. Disruptive features may change workflows or even introduce unavoidable inconveniences. We want to anticipate questions and avoid confusion by communicating these changes through the blog post. Smaller tweaks and bug fixes don't necessarily need to be mentioned, but if interesting, can be included at the bottom of the post.


You have a hierarchy of bundling features:

  1. DevOps lifecycle stages (stages), see SDLC
  2. Product categories (categories), see SDLC
  3. Feature areas (areas), see end of 'Plan Positioning' Google Doc
  4. Individual features (features), see Features

The areas are used to position the plans (CE, Starter, Premium, Ultimate). Each plan has a maximum of 7 areas.

When we introduce a new feature we look for each plan if it matches an area. We start at Ultimate and go down to CE, the first area that matches is the plan for the feature. For CE the areas are equal to the 7 stages of the DevOps lifecycle. This is because if areas of non-CE plans don't match it ends up in CE, so it has to cover everyone.