diff --git a/base/util/type_safety/id_type.h b/base/util/type_safety/id_type.h
index 918e945b512c0..87daefae1f7a2 100644
--- a/base/util/type_safety/id_type.h
+++ b/base/util/type_safety/id_type.h
@@ -47,7 +47,10 @@ namespace util {
 // - it restricts the set of available operations (i.e. no multiplication);
 // - it default-constructs to a null value and allows checking against the null
 //   value via is_null method.
-template <typename TypeMarker, typename WrappedType, WrappedType kInvalidValue>
+template <typename TypeMarker,
+          typename WrappedType,
+          WrappedType kInvalidValue,
+          WrappedType kFirstGeneratedId = kInvalidValue + 1>
 class IdType : public StrongAlias<TypeMarker, WrappedType> {
  public:
   static_assert(
@@ -55,6 +58,15 @@ class IdType : public StrongAlias<TypeMarker, WrappedType> {
       "If signed, the invalid value should be negative or equal to zero to "
       "avoid overflow issues.");
 
+  static_assert(kFirstGeneratedId != kInvalidValue,
+                "The first generated ID cannot be invalid.");
+
+  static_assert(std::is_unsigned<WrappedType>::value ||
+                    kFirstGeneratedId > kInvalidValue,
+                "If signed, the first generated ID must be greater than the "
+                "invalid value so that the monotonically increasing "
+                "GenerateNextId method will never return the invalid value.");
+
   using StrongAlias<TypeMarker, WrappedType>::StrongAlias;
 
   // This class can be used to generate unique IdTypes. It keeps an internal
@@ -71,7 +83,7 @@ class IdType : public StrongAlias<TypeMarker, WrappedType> {
     Generator& operator=(const Generator&) = delete;
 
    private:
-    WrappedType next_id_ = kInvalidValue + 1;
+    WrappedType next_id_ = kFirstGeneratedId;
   };
 
   // Default-construct in the null state.
diff --git a/base/util/type_safety/id_type_unittest.cc b/base/util/type_safety/id_type_unittest.cc
index 1e07bcf2748e0..a2dc000ca67a5 100644
--- a/base/util/type_safety/id_type_unittest.cc
+++ b/base/util/type_safety/id_type_unittest.cc
@@ -52,6 +52,14 @@ TEST(IdType, GeneratorWithBigUnsignedInvalidValue) {
   }
 }
 
+TEST(IdType, GeneratorWithDifferentStartingValue) {
+  using TestId = IdType<class TestIdTag, int, -1, 1>;
+
+  TestId::Generator test_id_generator;
+  for (int i = 1; i < 10; i++)
+    EXPECT_EQ(test_id_generator.GenerateNextId(), TestId::FromUnsafeValue(i));
+}
+
 TEST(IdType, EnsureConstexpr) {
   using TestId = IdType32<class TestTag>;
 
diff --git a/components/performance_manager/BUILD.gn b/components/performance_manager/BUILD.gn
index a12397b080777..b82908b7b3c2b 100644
--- a/components/performance_manager/BUILD.gn
+++ b/components/performance_manager/BUILD.gn
@@ -231,6 +231,7 @@ source_set("unit_tests") {
     "performance_manager_tab_helper_unittest.cc",
     "performance_manager_unittest.cc",
     "registered_objects_unittest.cc",
+    "render_process_host_id_unittest.cc",
     "v8_memory/v8_context_tracker_helpers_unittest.cc",
     "v8_memory/v8_context_tracker_internal_unittest.cc",
     "v8_memory/v8_detailed_memory_unittest.cc",
diff --git a/components/performance_manager/public/render_process_host_id.h b/components/performance_manager/public/render_process_host_id.h
index 8a2f0a8a08f1c..4515293985762 100644
--- a/components/performance_manager/public/render_process_host_id.h
+++ b/components/performance_manager/public/render_process_host_id.h
@@ -6,11 +6,33 @@
 #define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_RENDER_PROCESS_HOST_ID_H_
 
 #include "base/util/type_safety/id_type.h"
+#include "content/public/common/child_process_host.h"
 
 namespace performance_manager {
 
+using RenderProcessHostIdBase =
+    util::IdType<class RenderProcessHostIdTag,
+                 int32_t,
+                 content::ChildProcessHost::kInvalidUniqueID,
+                 1>;
+
 // A strongly typed wrapper for the id returned by RenderProcessHost::GetID().
-using RenderProcessHostId = util::IdType32<class RenderProcessHostIdTag>;
+//
+// This uses ChildProcessHost::kInvalidUniqueId (-1) as the default invalid id,
+// but also recognizes 0 as an invalid id because there is existing code that
+// uses 0 as an invalid value. It starts generating id's at 1.
+class RenderProcessHostId : public RenderProcessHostIdBase {
+ public:
+  using RenderProcessHostIdBase::RenderProcessHostIdBase;
+
+  // 0 is also an invalid value.
+  constexpr bool is_null() const {
+    return RenderProcessHostIdBase::is_null() || this->value() == 0;
+  }
+
+  // Override operator bool() to call the overridden is_null().
+  constexpr explicit operator bool() const { return !is_null(); }
+};
 
 }  // namespace performance_manager
 
diff --git a/components/performance_manager/render_process_host_id_unittest.cc b/components/performance_manager/render_process_host_id_unittest.cc
new file mode 100644
index 0000000000000..d9c1763ba2176
--- /dev/null
+++ b/components/performance_manager/render_process_host_id_unittest.cc
@@ -0,0 +1,39 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/performance_manager/public/render_process_host_id.h"
+
+#include "content/public/common/child_process_host.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace performance_manager {
+
+TEST(RenderProcessHostIdTest, InvalidValues) {
+  RenderProcessHostId default_id;
+  EXPECT_TRUE(default_id.is_null());
+  EXPECT_FALSE(default_id);
+
+  RenderProcessHostId invalid_id(content::ChildProcessHost::kInvalidUniqueID);
+  EXPECT_TRUE(invalid_id.is_null());
+  EXPECT_FALSE(invalid_id);
+
+  RenderProcessHostId zero_id(0);
+  EXPECT_TRUE(zero_id.is_null());
+  EXPECT_FALSE(zero_id);
+
+  EXPECT_EQ(default_id, invalid_id);
+  EXPECT_NE(default_id, zero_id);
+
+  RenderProcessHostId valid_id(1);
+  EXPECT_FALSE(valid_id.is_null());
+  EXPECT_TRUE(valid_id);
+}
+
+TEST(RenderProcessHostIdTest, Generator) {
+  RenderProcessHostId::Generator generator;
+  EXPECT_EQ(generator.GenerateNextId(), RenderProcessHostId(1));
+  EXPECT_EQ(generator.GenerateNextId(), RenderProcessHostId(2));
+}
+
+}  // namespace performance_manager