Rename {absl => std}::optional in base + everywhere. [Final]

Automated patch. This is a no-op. Please avoid, as much as possible,
assigning unrelated bugs to this.

Context:
https://groups.google.com/a/chromium.org/g/cxx/c/nBD_1LaanTc/m/ghh-ZZhWAwAJ?utm_medium=email

As of https://crrev.com/1204351, absl::optional is now a type alias
for std::optional. We should migrate toward it.

Script:
```
function replace {
  echo "Replacing $1 by $2"
  git grep -l "$1" \
    | cut -f1 -d: \
    | grep -v \
      -e "components/cast_streaming/browser/public/receiver_config.*" \
      -e "components/power_metrics/*" \
      -e "components/zucchini/patch_reader.*" \
      -e "third_party/abseil-cpp/*" \
      -e "third_party/googletest/*" \
      -e "third_party/leveldatabase/*" \
      -e "third_party/libaddressinput/" \
      -e "third_party/liburlpattern/*" \
      -e "third_party/lzma_sdk/*" \
      -e "third_party/maldoca/*" \
      -e "third_party/mediapipe/*" \
      -e "third_party/shell-encryption/*"\
      -e "third_party/tflite_support/*" \
      -e "third_party/webrtc_overrides/*" \
      -e "third_party/zxcvbn-cpp/*" \
    | grep \
      -e "\.h" \
      -e "\.cc" \
      -e "\.mm" \
      -e "\.pidl" \
    | sort \
    | uniq \
    | xargs sed -i "s/$1/$2/g"
}
replace "absl::make_optional" "std::make_optional"
replace "absl::optional" "std::optional"
replace "absl::nullopt" "std::nullopt"
replace "absl::in_place," "std::in_place,"
replace "absl::in_place_t," "std::in_place_t,"
replace "absl::in_place)" "std::in_place)"
replace "absl::in_place_t)" "std::in_place_t)"
replace "\"third_party\/abseil-cpp\/absl\/types\/optional.h\"" "<optional>"

git status
echo "Formatting"

echo "IncludeBlocks: Regroup" >> ".clang-format"
echo "IncludeIsMainRegex: \"(_(android|apple|chromeos|freebsd|fuchsia|fuzzer|ios|linux|mac|nacl|openbsd|posix|stubs?|win))?(_(unit|browser|perf)?tests?)?$\"" >> ".clang-format"
git cl format
git restore ".clang-format"
```

Bug: chromium:1500249
Change-Id: Ic2994b982bbc64d62f030d3d158979dc5d266121
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5296147
Reviewed-by: danakj <[email protected]>
Commit-Queue: danakj <[email protected]>
Owners-Override: danakj <[email protected]>
Auto-Submit: Arthur Sonzogni <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1263362}
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc
index 27a396d..6662cf69 100644
--- a/android_webview/browser/aw_content_browser_client.cc
+++ b/android_webview/browser/aw_content_browser_client.cc
@@ -582,7 +582,7 @@
     const base::RepeatingCallback<content::WebContents*()>& wc_getter,
     content::NavigationUIData* navigation_ui_data,
     int frame_tree_node_id,
-    absl::optional<int64_t> navigation_id) {
+    std::optional<int64_t> navigation_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   // Set lookup mechanism based on feature flag
@@ -659,7 +659,7 @@
             return client->GetSafeBrowsingUrlCheckerDelegate();
           },
           base::Unretained(this)),
-      wc_getter, frame_tree_node_id, /*navigation_id=*/absl::nullopt,
+      wc_getter, frame_tree_node_id, /*navigation_id=*/std::nullopt,
       // TODO(crbug.com/1033760): rt_lookup_service is
       // used to perform real time URL check, which is gated by UKM opted-in.
       // Since AW currently doesn't support UKM, this feature is not enabled.
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h
index eeaa8cc..12cc523 100644
--- a/android_webview/browser/aw_content_browser_client.h
+++ b/android_webview/browser/aw_content_browser_client.h
@@ -161,7 +161,7 @@
       const base::RepeatingCallback<content::WebContents*()>& wc_getter,
       content::NavigationUIData* navigation_ui_data,
       int frame_tree_node_id,
-      absl::optional<int64_t> navigation_id) override;
+      std::optional<int64_t> navigation_id) override;
   std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
   CreateURLLoaderThrottlesForKeepAlive(
       const network::ResourceRequest& request,
diff --git a/android_webview/browser/component_updater/masked_domain_list_component_loader.cc b/android_webview/browser/component_updater/masked_domain_list_component_loader.cc
index c5094b9..689f12cc 100644
--- a/android_webview/browser/component_updater/masked_domain_list_component_loader.cc
+++ b/android_webview/browser/component_updater/masked_domain_list_component_loader.cc
@@ -31,8 +31,7 @@
   policies.push_back(std::make_unique<
                      component_updater::MaskedDomainListComponentLoaderPolicy>(
       /* on_list_ready=*/base::BindRepeating(
-          [](base::Version version,
-             const absl::optional<std::string>& raw_mdl) {
+          [](base::Version version, const std::optional<std::string>& raw_mdl) {
             if (raw_mdl.has_value()) {
               content::GetNetworkService()->UpdateMaskedDomainList(
                   raw_mdl.value());
diff --git a/android_webview/browser/safe_browsing/aw_safe_browsing_blocking_page.cc b/android_webview/browser/safe_browsing/aw_safe_browsing_blocking_page.cc
index 92e9af4..4646204 100644
--- a/android_webview/browser/safe_browsing/aw_safe_browsing_blocking_page.cc
+++ b/android_webview/browser/safe_browsing/aw_safe_browsing_blocking_page.cc
@@ -95,7 +95,7 @@
     const GURL& main_frame_url,
     const UnsafeResource& unsafe_resource,
     std::unique_ptr<AwWebResourceRequest> resource_request,
-    absl::optional<base::TimeTicks> blocked_page_shown_timestamp) {
+    std::optional<base::TimeTicks> blocked_page_shown_timestamp) {
   // Log the request destination that triggers the safe browsing blocking page.
   UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.BlockingPage.RequestDestination",
                             unsafe_resource.request_destination);
diff --git a/android_webview/browser/safe_browsing/aw_safe_browsing_blocking_page.h b/android_webview/browser/safe_browsing/aw_safe_browsing_blocking_page.h
index bfc694c..40d6eed 100644
--- a/android_webview/browser/safe_browsing/aw_safe_browsing_blocking_page.h
+++ b/android_webview/browser/safe_browsing/aw_safe_browsing_blocking_page.h
@@ -34,7 +34,7 @@
       const GURL& main_frame_url,
       const UnsafeResource& unsafe_resource,
       std::unique_ptr<AwWebResourceRequest> resource_request,
-      absl::optional<base::TimeTicks> blocked_page_shown_timestamp);
+      std::optional<base::TimeTicks> blocked_page_shown_timestamp);
 
   ~AwSafeBrowsingBlockingPage() override;
 
diff --git a/android_webview/browser/safe_browsing/aw_safe_browsing_navigation_throttle.cc b/android_webview/browser/safe_browsing/aw_safe_browsing_navigation_throttle.cc
index a3113a9..a4389b3 100644
--- a/android_webview/browser/safe_browsing/aw_safe_browsing_navigation_throttle.cc
+++ b/android_webview/browser/safe_browsing/aw_safe_browsing_navigation_throttle.cc
@@ -72,7 +72,7 @@
           AwSafeBrowsingBlockingPage::CreateBlockingPage(
               manager, handle->GetWebContents(), handle->GetURL(), resource,
               std::move(request),
-              /*blocked_page_shown_timestamp=*/absl::nullopt);
+              /*blocked_page_shown_timestamp=*/std::nullopt);
       std::string error_page_content = blocking_page->GetHTMLContents();
       security_interstitials::SecurityInterstitialTabHelper::
           AssociateBlockingPage(handle, base::WrapUnique(blocking_page));
diff --git a/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.cc b/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.cc
index 6898800..12740d5 100644
--- a/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.cc
+++ b/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.cc
@@ -130,7 +130,7 @@
     const GURL& blocked_url,
     const UnsafeResource& unsafe_resource,
     bool forward_extension_event,
-    absl::optional<base::TimeTicks> blocked_page_shown_timestamp) {
+    std::optional<base::TimeTicks> blocked_page_shown_timestamp) {
   // The AwWebResourceRequest can't be provided yet, since the navigation hasn't
   // started. Once it has, it will be provided via
   // AwSafeBrowsingBlockingPage::CreatedErrorPageNavigation.
diff --git a/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.h b/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.h
index 49263f20..1eb75d4c 100644
--- a/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.h
+++ b/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.h
@@ -80,7 +80,7 @@
       const GURL& blocked_url,
       const UnsafeResource& unsafe_resource,
       bool forward_extension_event,
-      absl::optional<base::TimeTicks> blocked_page_shown_timestamp) override;
+      std::optional<base::TimeTicks> blocked_page_shown_timestamp) override;
 
   // Called on the UI thread to create a URLLoaderFactory interface ptr for
   // the SB thread.
diff --git a/android_webview/nonembedded/component_updater/registration.cc b/android_webview/nonembedded/component_updater/registration.cc
index e2f1e20..6a4ddf0 100644
--- a/android_webview/nonembedded/component_updater/registration.cc
+++ b/android_webview/nonembedded/component_updater/registration.cc
@@ -47,7 +47,7 @@
           component_updater::MaskedDomainListComponentInstallerPolicy>(
           /*on_list_ready=*/base::BindRepeating(
               [](base::Version version,
-                 const absl::optional<std::string>& raw_mdl) {
+                 const std::optional<std::string>& raw_mdl) {
                 if (raw_mdl.has_value()) {
                   VLOG(1) << "Received Masked Domain List version " << version;
                 } else {
diff --git a/ash/accelerators/accelerator_alias_converter_unittest.cc b/ash/accelerators/accelerator_alias_converter_unittest.cc
index 5ec7b979..11fda9b 100644
--- a/ash/accelerators/accelerator_alias_converter_unittest.cc
+++ b/ash/accelerators/accelerator_alias_converter_unittest.cc
@@ -849,25 +849,25 @@
 
         // The following should not perform an alias since Alt is part of the
         // original accelerator.
-        {ui::Accelerator{ui::VKEY_DELETE, ui::EF_ALT_DOWN}, absl::nullopt},
+        {ui::Accelerator{ui::VKEY_DELETE, ui::EF_ALT_DOWN}, std::nullopt},
 
-        {ui::Accelerator{ui::VKEY_HOME, ui::EF_ALT_DOWN}, absl::nullopt},
+        {ui::Accelerator{ui::VKEY_HOME, ui::EF_ALT_DOWN}, std::nullopt},
 
-        {ui::Accelerator{ui::VKEY_PRIOR, ui::EF_ALT_DOWN}, absl::nullopt},
+        {ui::Accelerator{ui::VKEY_PRIOR, ui::EF_ALT_DOWN}, std::nullopt},
 
-        {ui::Accelerator{ui::VKEY_END, ui::EF_ALT_DOWN}, absl::nullopt},
+        {ui::Accelerator{ui::VKEY_END, ui::EF_ALT_DOWN}, std::nullopt},
 
-        {ui::Accelerator{ui::VKEY_NEXT, ui::EF_ALT_DOWN}, absl::nullopt},
+        {ui::Accelerator{ui::VKEY_NEXT, ui::EF_ALT_DOWN}, std::nullopt},
 
-        {ui::Accelerator{ui::VKEY_HOME, ui::EF_CONTROL_DOWN}, absl::nullopt},
+        {ui::Accelerator{ui::VKEY_HOME, ui::EF_CONTROL_DOWN}, std::nullopt},
 
-        {ui::Accelerator{ui::VKEY_END, ui::EF_CONTROL_DOWN}, absl::nullopt},
+        {ui::Accelerator{ui::VKEY_END, ui::EF_CONTROL_DOWN}, std::nullopt},
 
         {ui::Accelerator{ui::VKEY_HOME, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN},
-         absl::nullopt},
+         std::nullopt},
 
         {ui::Accelerator{ui::VKEY_END, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN},
-         absl::nullopt},
+         std::nullopt},
     }));
 
 TEST_P(SixPackAliasAltTest, CheckSixPackAliasAlt) {
@@ -1098,7 +1098,7 @@
 
         // The following should not perform an alias since Alt is part of the
         // original accelerator.
-        {ui::Accelerator{ui::VKEY_F11, ui::EF_ALT_DOWN}, absl::nullopt},
+        {ui::Accelerator{ui::VKEY_F11, ui::EF_ALT_DOWN}, std::nullopt},
     }));
 
 TEST_P(ExtendedFKeysAliasAltTest, CheckExtendedFKeysAliasAlt) {
@@ -1181,7 +1181,7 @@
 
         // The following should not perform an alias since Shift is part of
         // the original accelerator.
-        {ui::Accelerator{ui::VKEY_F11, ui::EF_SHIFT_DOWN}, absl::nullopt},
+        {ui::Accelerator{ui::VKEY_F11, ui::EF_SHIFT_DOWN}, std::nullopt},
     }));
 
 TEST_P(ExtendedFKeysAliasShiftTest, CheckExtendedFKeysAliasShift) {
@@ -1269,15 +1269,15 @@
         // The following should not perform an alias since Ctrl and Shift
         // are part of the original accelerator.
         {ui::Accelerator{ui::VKEY_F11, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN},
-         absl::nullopt},
+         std::nullopt},
 
         // The following should not perform an alias since Ctrl is part of the
         // original accelerator.
-        {ui::Accelerator{ui::VKEY_F11, ui::EF_CONTROL_DOWN}, absl::nullopt},
+        {ui::Accelerator{ui::VKEY_F11, ui::EF_CONTROL_DOWN}, std::nullopt},
 
         // The following should not perform an alias since Shift is part of the
         // original accelerator.
-        {ui::Accelerator{ui::VKEY_F11, ui::EF_SHIFT_DOWN}, absl::nullopt},
+        {ui::Accelerator{ui::VKEY_F11, ui::EF_SHIFT_DOWN}, std::nullopt},
     }));
 
 TEST_P(ExtendedFKeysAliasCtrlShiftTest, CheckExtendedFKeysAliasCtrlShift) {
diff --git a/ash/api/tasks/fake_tasks_client.cc b/ash/api/tasks/fake_tasks_client.cc
index c9d30ea..811a2079 100644
--- a/ash/api/tasks/fake_tasks_client.cc
+++ b/ash/api/tasks/fake_tasks_client.cc
@@ -6,6 +6,7 @@
 
 #include <list>
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "ash/api/tasks/tasks_client.h"
@@ -18,7 +19,6 @@
 #include "base/strings/string_util.h"
 #include "base/time/time.h"
 #include "base/uuid.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace ash::api {
 namespace {
@@ -158,7 +158,7 @@
 
   auto pending_task = std::make_unique<Task>(
       base::Uuid::GenerateRandomV4().AsLowercaseString(), title,
-      /*due=*/absl::nullopt, /*completed=*/false,
+      /*due=*/std::nullopt, /*completed=*/false,
       /*has_subtasks=*/false, /*has_email_link=*/false,
       /*has_notes=*/false,
       /*updated=*/base::Time::Now());
diff --git a/ash/app_list/views/app_list_toast_container_view.h b/ash/app_list/views/app_list_toast_container_view.h
index d7bbf69..3bcea1e 100644
--- a/ash/app_list/views/app_list_toast_container_view.h
+++ b/ash/app_list/views/app_list_toast_container_view.h
@@ -178,7 +178,7 @@
   bool committing_sort_order_ = false;
 
   // The amount of horizontal space available for the toast container.
-  absl::optional<int> available_width_;
+  std::optional<int> available_width_;
 
   // The abort handle for the `toast_view_` fade out animation.
   std::unique_ptr<views::AnimationAbortHandle>
diff --git a/ash/app_list/views/continue_section_view.h b/ash/app_list/views/continue_section_view.h
index 313a669..511c734 100644
--- a/ash/app_list/views/continue_section_view.h
+++ b/ash/app_list/views/continue_section_view.h
@@ -146,7 +146,7 @@
 
   // If set, the amount of horizontal space available for the continue section -
   // used to configure layout for the continue section privacy notice toast.
-  absl::optional<int> available_width_;
+  std::optional<int> available_width_;
 
   bool tablet_mode_ = false;
 
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc
index 933e5a6..3f43fa51 100644
--- a/ash/app_list/views/search_box_view.cc
+++ b/ash/app_list/views/search_box_view.cc
@@ -277,7 +277,7 @@
   ~RoundRectPathGenerator() override = default;
 
   // views::HighlightPathGenerator:
-  absl::optional<gfx::RRectF> GetRoundRect(const gfx::RectF& rect) override {
+  std::optional<gfx::RRectF> GetRoundRect(const gfx::RectF& rect) override {
     return gfx::RRectF(rect, radii_);
   }
 
diff --git a/ash/components/arc/video_accelerator/gpu_arc_video_encode_accelerator.cc b/ash/components/arc/video_accelerator/gpu_arc_video_encode_accelerator.cc
index b80d4a4..7d916c1 100644
--- a/ash/components/arc/video_accelerator/gpu_arc_video_encode_accelerator.cc
+++ b/ash/components/arc/video_accelerator/gpu_arc_video_encode_accelerator.cc
@@ -281,7 +281,7 @@
   // change the bitrate mode at runtime will result in the |accelerator_|
   // reporting an error through NotifyError.
   accelerator_->RequestEncodingParametersChange(bitrate, framerate,
-                                                absl::nullopt);
+                                                std::nullopt);
 }
 
 void GpuArcVideoEncodeAccelerator::RequestEncodingParametersChangeDeprecated(
@@ -293,7 +293,7 @@
     return;
   }
   accelerator_->RequestEncodingParametersChange(
-      media::Bitrate::ConstantBitrate(bitrate), framerate, absl::nullopt);
+      media::Bitrate::ConstantBitrate(bitrate), framerate, std::nullopt);
 }
 
 void GpuArcVideoEncodeAccelerator::Flush(FlushCallback callback) {
diff --git a/ash/display/cursor_window_controller.cc b/ash/display/cursor_window_controller.cc
index 2ef2b22..033fa54 100644
--- a/ash/display/cursor_window_controller.cc
+++ b/ash/display/cursor_window_controller.cc
@@ -4,6 +4,8 @@
 
 #include "ash/display/cursor_window_controller.h"
 
+#include <optional>
+
 #include "ash/accessibility/magnifier/fullscreen_magnifier_controller.h"
 #include "ash/capture_mode/capture_mode_camera_controller.h"
 #include "ash/capture_mode/capture_mode_controller.h"
@@ -22,7 +24,6 @@
 #include "base/command_line.h"
 #include "base/metrics/histogram_macros.h"
 #include "components/prefs/pref_service.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/accessibility/accessibility_features.h"
 #include "ui/aura/env.h"
 #include "ui/aura/window.h"
@@ -108,11 +109,11 @@
   // Rotation is handled in viz (for aura::Window based cursor)
   // or fast ink canvas (for fast ink based cursor), so don't do any
   // rotation here.
-  absl::optional<ui::CursorData> cursor_data = wm::GetCursorData(
+  std::optional<ui::CursorData> cursor_data = wm::GetCursorData(
       type, cursor_size, dsf,
       cursor_size == ui::CursorSize::kLarge
           ? std::make_optional(target_cursor_size_in_dip * dsf)
-          : absl::nullopt,
+          : std::nullopt,
       display::Display::ROTATE_0);
   if (!cursor_data) {
     return images;
diff --git a/ash/events/accessibility_event_rewriter_unittest.cc b/ash/events/accessibility_event_rewriter_unittest.cc
index 071443d..d5ec610 100644
--- a/ash/events/accessibility_event_rewriter_unittest.cc
+++ b/ash/events/accessibility_event_rewriter_unittest.cc
@@ -128,7 +128,7 @@
       ui::EventRewriterAsh::Delegate* delegate)
       : delegate_(delegate) {}
 
-  absl::optional<ui::mojom::ModifierKey> GetKeyboardRemappedModifierValue(
+  std::optional<ui::mojom::ModifierKey> GetKeyboardRemappedModifierValue(
       int device_id,
       ui::mojom::ModifierKey modifier_key,
       const std::string& pref_name) const override {
diff --git a/ash/events/event_rewriter_controller_impl.cc b/ash/events/event_rewriter_controller_impl.cc
index 51c1b0de..c33b7cd2 100644
--- a/ash/events/event_rewriter_controller_impl.cc
+++ b/ash/events/event_rewriter_controller_impl.cc
@@ -37,7 +37,7 @@
       ui::EventRewriterAsh::Delegate* event_rewriter_delegate)
       : event_rewriter_delegate_(event_rewriter_delegate) {}
 
-  absl::optional<ui::mojom::ModifierKey> GetKeyboardRemappedModifierValue(
+  std::optional<ui::mojom::ModifierKey> GetKeyboardRemappedModifierValue(
       int device_id,
       ui::mojom::ModifierKey modifier_key,
       const std::string& pref_name) const override {
diff --git a/ash/events/peripheral_customization_event_rewriter.cc b/ash/events/peripheral_customization_event_rewriter.cc
index db1f269..c2dd764 100644
--- a/ash/events/peripheral_customization_event_rewriter.cc
+++ b/ash/events/peripheral_customization_event_rewriter.cc
@@ -895,7 +895,7 @@
     const ui::Event& event,
     const mojom::Button& button,
     std::vector<std::unique_ptr<ui::Event>>& rewritten_events) {
-  absl::optional<RemappingActionResult> remapping_action_result =
+  std::optional<RemappingActionResult> remapping_action_result =
       GetRemappingAction(event.source_device_id(), button);
   if (!remapping_action_result) {
     return false;
@@ -1313,7 +1313,7 @@
         button, *graphics_tablet_settings);
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void PeripheralCustomizationEventRewriter::RemoveRemappedModifiers(
diff --git a/ash/glanceables/tasks/glanceables_task_view_v2_unittest.cc b/ash/glanceables/tasks/glanceables_task_view_v2_unittest.cc
index f62754f..f68003db 100644
--- a/ash/glanceables/tasks/glanceables_task_view_v2_unittest.cc
+++ b/ash/glanceables/tasks/glanceables_task_view_v2_unittest.cc
@@ -325,7 +325,7 @@
     // Simulate reply, the view should update itself with the new task id.
     const auto created_task =
         api::Task("task-id", "New",
-                  /*due=*/absl::nullopt, /*completed=*/false,
+                  /*due=*/std::nullopt, /*completed=*/false,
                   /*has_subtasks=*/false,
                   /*has_email_link=*/false, /*has_notes=*/false,
                   /*updated=*/base::Time::Now());
@@ -392,7 +392,7 @@
   // Simulate reply, this should re-enable the checkbox and title buttons.
   const auto created_task =
       api::Task("task-id", "New",
-                /*due=*/absl::nullopt, /*completed=*/false,
+                /*due=*/std::nullopt, /*completed=*/false,
                 /*has_subtasks=*/false,
                 /*has_email_link=*/false, /*has_notes=*/false,
                 /*updated=*/base::Time::Now());
diff --git a/ash/public/cpp/accelerators_util.cc b/ash/public/cpp/accelerators_util.cc
index 321abf1..ab3cf61 100644
--- a/ash/public/cpp/accelerators_util.cc
+++ b/ash/public/cpp/accelerators_util.cc
@@ -238,11 +238,11 @@
 
 }  // namespace
 
-absl::optional<ash::KeyCodeLookupEntry> FindKeyCodeEntry(
+std::optional<ash::KeyCodeLookupEntry> FindKeyCodeEntry(
     ui::KeyboardCode key_code,
     ui::DomCode original_dom_code,
     bool remap_positional_key) {
-  absl::optional<ash::KeyCodeLookupEntry> cached_key_data =
+  std::optional<ash::KeyCodeLookupEntry> cached_key_data =
       ash::AcceleratorKeycodeLookupCache::Get()->Find(key_code,
                                                       remap_positional_key);
   // Cache hit, return immediately.
@@ -275,7 +275,7 @@
           layout_engine->Lookup(dom_code, /*event_flags=*/ui::EF_NONE, &dom_key,
                                 &key_code_to_compare)) {
         if (!dom_key.IsValid()) {
-          return absl::nullopt;
+          return std::nullopt;
         }
         if (dom_key.IsDeadKey()) {
           result = GetStringForDeadKey(dom_key);
@@ -321,7 +321,7 @@
     return ash::KeyCodeLookupEntry{dom_code, dom_key, key_code_to_compare,
                                    key_string};
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 std::u16string KeycodeToKeyString(ui::KeyboardCode key_code,
diff --git a/ash/public/cpp/accelerators_util.h b/ash/public/cpp/accelerators_util.h
index a08eb86d..5be684d 100644
--- a/ash/public/cpp/accelerators_util.h
+++ b/ash/public/cpp/accelerators_util.h
@@ -69,7 +69,7 @@
 // layout keycodes based on `remap_positional_key`. Returns nullptr if no valid
 // `KeyCodeLookupEntry` can be produced from the given `key_code`.
 ASH_PUBLIC_EXPORT
-absl::optional<AcceleratorKeycodeLookupCache::KeyCodeLookupEntry>
+std::optional<AcceleratorKeycodeLookupCache::KeyCodeLookupEntry>
 FindKeyCodeEntry(ui::KeyboardCode key_code,
                  ui::DomCode dom_code = ui::DomCode::NONE,
                  bool remap_positional_key = true);
diff --git a/ash/public/cpp/accelerators_util_unittest.cc b/ash/public/cpp/accelerators_util_unittest.cc
index 56ab57cb..85de8ea 100644
--- a/ash/public/cpp/accelerators_util_unittest.cc
+++ b/ash/public/cpp/accelerators_util_unittest.cc
@@ -42,7 +42,7 @@
 TEST_F(AcceleratorsUtilTest, BasicDomCode) {
   const std::u16string expected = u"a";
 
-  absl::optional<KeyCodeLookupEntry> found_entry =
+  std::optional<KeyCodeLookupEntry> found_entry =
       AcceleratorKeycodeLookupCache::Get()->Find(ui::KeyboardCode::VKEY_A,
                                                  /*remap_positional_key=*/true);
   EXPECT_FALSE(found_entry.has_value());
@@ -80,9 +80,9 @@
 
 TEST_F(AcceleratorsUtilTest, NonAlphanumericKey) {
   const std::u16string expected = u"Meta";
-  absl::optional<AcceleratorKeycodeLookupCache::KeyCodeLookupEntry>
-      found_entry = AcceleratorKeycodeLookupCache::Get()->Find(
-          ui::KeyboardCode::VKEY_COMMAND, /*remap_positional_key=*/true);
+  std::optional<AcceleratorKeycodeLookupCache::KeyCodeLookupEntry> found_entry =
+      AcceleratorKeycodeLookupCache::Get()->Find(ui::KeyboardCode::VKEY_COMMAND,
+                                                 /*remap_positional_key=*/true);
   EXPECT_FALSE(found_entry.has_value());
   EXPECT_EQ(expected, KeycodeToKeyString(ui::KeyboardCode::VKEY_COMMAND));
 
diff --git a/ash/public/cpp/system/anchored_nudge_data.h b/ash/public/cpp/system/anchored_nudge_data.h
index 2601efcc..11de33e 100644
--- a/ash/public/cpp/system/anchored_nudge_data.h
+++ b/ash/public/cpp/system/anchored_nudge_data.h
@@ -5,6 +5,7 @@
 #ifndef ASH_PUBLIC_CPP_SYSTEM_ANCHORED_NUDGE_DATA_H_
 #define ASH_PUBLIC_CPP_SYSTEM_ANCHORED_NUDGE_DATA_H_
 
+#include <optional>
 #include <string>
 
 #include "ash/constants/notifier_catalogs.h"
@@ -13,7 +14,6 @@
 #include "base/functional/callback_forward.h"
 #include "base/functional/callback_helpers.h"
 #include "base/time/time.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/events/keycodes/keyboard_codes_posix.h"
 #include "ui/gfx/paint_vector_icon.h"
 #include "ui/views/bubble/bubble_border.h"
@@ -81,8 +81,8 @@
   ui::ImageModel image_model;
   std::u16string title_text;
   std::vector<ui::KeyboardCode> keyboard_codes;
-  absl::optional<ui::ColorId> background_color_id;
-  absl::optional<ui::ColorId> image_background_color_id;
+  std::optional<ui::ColorId> background_color_id;
+  std::optional<ui::ColorId> image_background_color_id;
 
   // Callback for close button pressed.
   base::RepeatingClosure close_button_callback;
diff --git a/ash/system/focus_mode/focus_mode_chip_carousel.cc b/ash/system/focus_mode/focus_mode_chip_carousel.cc
index f2a84f2..65e2101d 100644
--- a/ash/system/focus_mode/focus_mode_chip_carousel.cc
+++ b/ash/system/focus_mode/focus_mode_chip_carousel.cc
@@ -97,7 +97,7 @@
       views::ScrollView::ScrollBarMode::kHiddenButEnabled);
   scroll_view_->SetDrawOverflowIndicator(false);
   scroll_view_->SetPaintToLayer();
-  scroll_view_->SetBackgroundColor(absl::nullopt);
+  scroll_view_->SetBackgroundColor(std::nullopt);
 
   scroll_contents_ =
       scroll_view_->SetContents(std::make_unique<views::FlexLayoutView>());
diff --git a/ash/system/focus_mode/focus_mode_chip_carousel_unittest.cc b/ash/system/focus_mode/focus_mode_chip_carousel_unittest.cc
index d48644f..a47e88d9 100644
--- a/ash/system/focus_mode/focus_mode_chip_carousel_unittest.cc
+++ b/ash/system/focus_mode/focus_mode_chip_carousel_unittest.cc
@@ -57,7 +57,7 @@
   std::unique_ptr<api::Task> MakeTask(const std::string& title) {
     return std::make_unique<api::Task>(
         /*id=*/base::NumberToString(task_id_++), title,
-        /*due=*/absl::nullopt, /*completed=*/false, /*has_subtasks=*/false,
+        /*due=*/std::nullopt, /*completed=*/false, /*has_subtasks=*/false,
         /*has_email_link=*/false,
         /*has_notes=*/false, /*updated=*/base::Time::Now());
   }
diff --git a/ash/system/focus_mode/focus_mode_controller_unittest.cc b/ash/system/focus_mode/focus_mode_controller_unittest.cc
index faaf487..31996f7 100644
--- a/ash/system/focus_mode/focus_mode_controller_unittest.cc
+++ b/ash/system/focus_mode/focus_mode_controller_unittest.cc
@@ -196,7 +196,7 @@
   const std::string title = "Focus Task";
   controller->SetSelectedTask(std::make_unique<api::Task>(
                                   /*id=*/base::NumberToString(id), title,
-                                  /*due=*/absl::nullopt, /*completed=*/false,
+                                  /*due=*/std::nullopt, /*completed=*/false,
                                   /*has_subtasks=*/false,
                                   /*has_email_link=*/false,
                                   /*has_notes=*/false,
diff --git a/ash/system/focus_mode/focus_mode_detailed_view_unittest.cc b/ash/system/focus_mode/focus_mode_detailed_view_unittest.cc
index c7b26f2d8..9c9927e 100644
--- a/ash/system/focus_mode/focus_mode_detailed_view_unittest.cc
+++ b/ash/system/focus_mode/focus_mode_detailed_view_unittest.cc
@@ -802,7 +802,7 @@
   const std::string title = "Focus Task";
   controller->SetSelectedTask(std::make_unique<api::Task>(
                                   /*id=*/base::NumberToString(id), title,
-                                  /*due=*/absl::nullopt, /*completed=*/false,
+                                  /*due=*/std::nullopt, /*completed=*/false,
                                   /*has_subtasks=*/false,
                                   /*has_email_link=*/false,
                                   /*has_notes=*/false,
diff --git a/ash/system/focus_mode/focus_mode_tasks_provider.cc b/ash/system/focus_mode/focus_mode_tasks_provider.cc
index 806eff7..0394e76e 100644
--- a/ash/system/focus_mode/focus_mode_tasks_provider.cc
+++ b/ash/system/focus_mode/focus_mode_tasks_provider.cc
@@ -11,7 +11,6 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/time/time.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace ash {
 
@@ -121,7 +120,7 @@
                                      OnTaskSavedCallback callback) {
   std::unique_ptr<api::Task> task = std::make_unique<api::Task>(
       /*id=*/base::NumberToString(task_id_++), title,
-      /*due=*/absl::nullopt, /*completed=*/false, /*has_subtasks=*/false,
+      /*due=*/std::nullopt, /*completed=*/false, /*has_subtasks=*/false,
       /*has_email_link=*/false,
       /*has_notes=*/false, /*updated=*/base::Time::Now());
 
diff --git a/ash/system/focus_mode/focus_mode_tray_unittest.cc b/ash/system/focus_mode/focus_mode_tray_unittest.cc
index 737c9dd..ea1f57df 100644
--- a/ash/system/focus_mode/focus_mode_tray_unittest.cc
+++ b/ash/system/focus_mode/focus_mode_tray_unittest.cc
@@ -189,7 +189,7 @@
   controller->SetSelectedTask(
       std::make_unique<api::Task>(
           /*id=*/base::NumberToString(0), "make a travel plan",
-          /*due=*/absl::nullopt, /*completed=*/false, /*has_subtasks=*/false,
+          /*due=*/std::nullopt, /*completed=*/false, /*has_subtasks=*/false,
           /*has_email_link=*/false,
           /*has_notes=*/false,
           /*updated=*/base::Time::Now())
@@ -296,7 +296,7 @@
   controller->SetInactiveSessionDuration(session_duration);
   controller->SetSelectedTask(std::make_unique<api::Task>(
                                   /*id=*/base::NumberToString(1), task_name,
-                                  /*due=*/absl::nullopt, /*completed=*/false,
+                                  /*due=*/std::nullopt, /*completed=*/false,
                                   /*has_subtasks=*/false,
                                   /*has_email_link=*/false,
                                   /*has_notes=*/false,
diff --git a/ash/system/night_light/night_light_controller_impl.h b/ash/system/night_light/night_light_controller_impl.h
index 50f6c8ae..c7c709f 100644
--- a/ash/system/night_light/night_light_controller_impl.h
+++ b/ash/system/night_light/night_light_controller_impl.h
@@ -203,7 +203,7 @@
 
   // Night light state in the last call to `RefreshFeatureState()`. `nullopt`
   // if no call has been made yet.
-  absl::optional<bool> last_observed_enabled_state_;
+  std::optional<bool> last_observed_enabled_state_;
 
   base::WeakPtrFactory<NightLightControllerImpl> weak_ptr_factory_;
 };
diff --git a/ash/system/notification_center/notification_style_utils.cc b/ash/system/notification_center/notification_style_utils.cc
index 3d7da444..de7183c1 100644
--- a/ash/system/notification_center/notification_style_utils.cc
+++ b/ash/system/notification_center/notification_style_utils.cc
@@ -84,7 +84,7 @@
   }
 
   auto color_id = notification->accent_color_id();
-  absl::optional<SkColor> accent_color = notification->accent_color();
+  std::optional<SkColor> accent_color = notification->accent_color();
 
   if (!color_id || !accent_color.has_value()) {
     return default_color;
@@ -113,7 +113,7 @@
                      : gfx::kPlaceholderColor;
   return color_utils::BlendForMinContrast(
              fg_color, bg_color,
-             /*high_contrast_foreground=*/absl::nullopt, minContrastRatio)
+             /*high_contrast_foreground=*/std::nullopt, minContrastRatio)
       .color;
 }
 
diff --git a/ash/system/power/battery_notification_unittest.cc b/ash/system/power/battery_notification_unittest.cc
index 19bda76..536b92d 100644
--- a/ash/system/power/battery_notification_unittest.cc
+++ b/ash/system/power/battery_notification_unittest.cc
@@ -63,7 +63,7 @@
   }
 
   void TearDown() override {
-    OverrideIsBatterySaverAllowedForTesting(absl::nullopt);
+    OverrideIsBatterySaverAllowedForTesting(std::nullopt);
     battery_notification_.reset();
     AshTestBase::TearDown();
     chromeos::PowerManagerClient::Shutdown();
diff --git a/ash/system/power/battery_saver_controller.cc b/ash/system/power/battery_saver_controller.cc
index 943a37ee..358e23c5 100644
--- a/ash/system/power/battery_saver_controller.cc
+++ b/ash/system/power/battery_saver_controller.cc
@@ -40,7 +40,7 @@
 }
 
 // Overrides the result of IsBatterySaverAllowed for testing.
-absl::optional<bool> override_allowed_for_testing;
+std::optional<bool> override_allowed_for_testing;
 
 }  // namespace
 
@@ -57,7 +57,7 @@
   return false;
 }
 
-void OverrideIsBatterySaverAllowedForTesting(absl::optional<bool> isAllowed) {
+void OverrideIsBatterySaverAllowedForTesting(std::optional<bool> isAllowed) {
   CHECK_IS_TEST();
   override_allowed_for_testing = isAllowed;
 }
diff --git a/ash/system/power/battery_saver_controller.h b/ash/system/power/battery_saver_controller.h
index 39ebf7a..dd66b4e 100644
--- a/ash/system/power/battery_saver_controller.h
+++ b/ash/system/power/battery_saver_controller.h
@@ -26,7 +26,7 @@
 
 // Test method to allow testing without the Battery Saver feature.
 ASH_EXPORT void OverrideIsBatterySaverAllowedForTesting(
-    absl::optional<bool> isAllowed);
+    std::optional<bool> isAllowed);
 
 // BatterySaverController is a singleton that controls battery saver state via
 // PowerManagerClient by watching for updates to ash::prefs::kPowerBatterySaver
diff --git a/ash/system/power/power_sounds_controller_unittest.cc b/ash/system/power/power_sounds_controller_unittest.cc
index 791d0343..42ec07de 100644
--- a/ash/system/power/power_sounds_controller_unittest.cc
+++ b/ash/system/power/power_sounds_controller_unittest.cc
@@ -42,7 +42,7 @@
 class PowerSoundsControllerTest : public AshTestBase {
  public:
   explicit PowerSoundsControllerTest(
-      absl::optional<bool> battery_saver_allowed = false)
+      std::optional<bool> battery_saver_allowed = false)
       : battery_saver_allowed_(battery_saver_allowed) {}
 
   PowerSoundsControllerTest(const PowerSoundsControllerTest&) = delete;
@@ -61,7 +61,7 @@
 
   void TearDown() override {
     AshTestBase::TearDown();
-    OverrideIsBatterySaverAllowedForTesting(absl::nullopt);
+    OverrideIsBatterySaverAllowedForTesting(std::nullopt);
   }
 
   TestSystemSoundsDelegate* GetSystemSoundsDelegate() const {
@@ -151,7 +151,7 @@
 
  private:
   bool is_ac_charger_connected_;
-  absl::optional<bool> battery_saver_allowed_;
+  std::optional<bool> battery_saver_allowed_;
 };
 
 class PowerSoundsControllerWithBatterySaverTest
diff --git a/ash/system/video_conference/effects/video_conference_tray_effects_manager_unittest.cc b/ash/system/video_conference/effects/video_conference_tray_effects_manager_unittest.cc
index 00e8ed6..c04e25c 100644
--- a/ash/system/video_conference/effects/video_conference_tray_effects_manager_unittest.cc
+++ b/ash/system/video_conference/effects/video_conference_tray_effects_manager_unittest.cc
@@ -47,11 +47,11 @@
   ~TestEffectDelegate() override = default;
 
   // VcEffectsDelegate:
-  absl::optional<int> GetEffectState(VcEffectId effect_id) override {
+  std::optional<int> GetEffectState(VcEffectId effect_id) override {
     return std::nullopt;
   }
   void OnEffectControlActivated(VcEffectId effect_id,
-                                absl::optional<int> state) override {}
+                                std::optional<int> state) override {}
 };
 
 class VideoConferenceTrayEffectsManagerTest
diff --git a/ash/touch/touch_selection_pixeltest.cc b/ash/touch/touch_selection_pixeltest.cc
index af1661a..881475d8 100644
--- a/ash/touch/touch_selection_pixeltest.cc
+++ b/ash/touch/touch_selection_pixeltest.cc
@@ -37,7 +37,7 @@
   ~TouchSelectionPixelTest() override = default;
 
   // AshTestBase:
-  absl::optional<pixel_test::InitParams> CreatePixelTestInitParams()
+  std::optional<pixel_test::InitParams> CreatePixelTestInitParams()
       const override {
     return pixel_test::InitParams();
   }
diff --git a/ash/user_education/holding_space_wallpaper_nudge/holding_space_wallpaper_nudge_prefs_unittest.cc b/ash/user_education/holding_space_wallpaper_nudge/holding_space_wallpaper_nudge_prefs_unittest.cc
index d7b0f7e..aa7f00c 100644
--- a/ash/user_education/holding_space_wallpaper_nudge/holding_space_wallpaper_nudge_prefs_unittest.cc
+++ b/ash/user_education/holding_space_wallpaper_nudge/holding_space_wallpaper_nudge_prefs_unittest.cc
@@ -36,14 +36,14 @@
 // Helpers ---------------------------------------------------------------------
 
 // Fetches the time pref associated with the first time of a given interaction.
-absl::optional<base::Time> GetTimeOfFirstInteraction(PrefService* prefs,
-                                                     Interaction interaction) {
+std::optional<base::Time> GetTimeOfFirstInteraction(PrefService* prefs,
+                                                    Interaction interaction) {
   auto pref_name = base::StrCat(
       {kTimeOfFirstInteractionPrefPrefix,
        holding_space_wallpaper_nudge_metrics::ToString(interaction),
        ".first_time"});
   auto* pref = prefs->FindPreference(pref_name);
-  return pref->IsDefaultValue() ? absl::nullopt
+  return pref->IsDefaultValue() ? std::nullopt
                                 : base::ValueToTime(pref->GetValue());
 }
 
@@ -78,12 +78,12 @@
   for (auto interaction : kAllInteractionsSet) {
     // Should be unset by default.
     EXPECT_EQ(GetTimeOfFirstInteraction(pref_service(), interaction),
-              absl::nullopt);
+              std::nullopt);
 
     // Should remain unset because the user's first session is not set.
     EXPECT_FALSE(MarkTimeOfFirstInteraction(pref_service(), interaction));
     EXPECT_EQ(GetTimeOfFirstInteraction(pref_service(), interaction),
-              absl::nullopt);
+              std::nullopt);
   }
 
   MarkTimeOfFirstEligibleSession(pref_service());
@@ -99,7 +99,7 @@
     auto interaction_time =
         GetTimeOfFirstInteraction(pref_service(), interaction);
     EXPECT_THAT(interaction_time,
-                AllOf(Ne(absl::nullopt), Ge(before), Le(after)));
+                AllOf(Ne(std::nullopt), Ge(before), Le(after)));
 
     // For any call beyond the first, the function should return false and the
     // marked time should not change.
diff --git a/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider.cc b/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider.cc
index 9bfb323..13fa86f3 100644
--- a/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider.cc
+++ b/ash/webui/shortcut_customization_ui/backend/accelerator_configuration_provider.cc
@@ -383,7 +383,7 @@
   }
 
   // Case: Non-standard keys cannot have search as a modifier.
-  absl::optional<AcceleratorKeycodeLookupCache::KeyCodeLookupEntry>
+  std::optional<AcceleratorKeycodeLookupCache::KeyCodeLookupEntry>
       key_code_entry = FindKeyCodeEntry(accelerator.key_code());
   if (key_code_entry.has_value()) {
     const ui::KeyEvent key_event(
diff --git a/ash/wm/bounds_tracker/window_bounds_tracker_unittests.cc b/ash/wm/bounds_tracker/window_bounds_tracker_unittests.cc
index 25ca16bd..06d0447 100644
--- a/ash/wm/bounds_tracker/window_bounds_tracker_unittests.cc
+++ b/ash/wm/bounds_tracker/window_bounds_tracker_unittests.cc
@@ -585,14 +585,14 @@
   // Enter mirror mode.
   const gfx::Rect w2_remapping_bounds_in_1st(
       gfx::Rect(gfx::Point(200, 0), window_size));
-  display_manager()->SetMirrorMode(display::MirrorMode::kNormal, absl::nullopt);
+  display_manager()->SetMirrorMode(display::MirrorMode::kNormal, std::nullopt);
   EXPECT_TRUE(display_manager()->IsInMirrorMode());
   EXPECT_EQ(first_display_id, display_manager()->mirroring_source_id());
   EXPECT_EQ(w1_initial_bounds, w1->GetBoundsInScreen());
   EXPECT_EQ(w2_remapping_bounds_in_1st, w2->GetBoundsInScreen());
 
   // Exit mirror mode.
-  display_manager()->SetMirrorMode(display::MirrorMode::kOff, absl::nullopt);
+  display_manager()->SetMirrorMode(display::MirrorMode::kOff, std::nullopt);
   EXPECT_FALSE(display_manager()->IsInMirrorMode());
   EXPECT_EQ(w2_initial_bounds, w2->GetBoundsInScreen());
 
diff --git a/ash/wm/overview/overview_session_unittest.cc b/ash/wm/overview/overview_session_unittest.cc
index 0d1dce4..f322ff5 100644
--- a/ash/wm/overview/overview_session_unittest.cc
+++ b/ash/wm/overview/overview_session_unittest.cc
@@ -98,7 +98,6 @@
 #include "base/time/time.h"
 #include "chromeos/ui/base/window_state_type.h"
 #include "chromeos/ui/frame/caption_buttons/snap_controller.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/aura/test/test_window_delegate.h"
 #include "ui/aura/window.h"
diff --git a/ash/wm/overview/overview_utils.cc b/ash/wm/overview/overview_utils.cc
index 1dc3cb36..d0c916ec 100644
--- a/ash/wm/overview/overview_utils.cc
+++ b/ash/wm/overview/overview_utils.cc
@@ -299,10 +299,10 @@
 
 std::optional<gfx::RectF> GetSplitviewBoundsMaintainingAspectRatio() {
   if (!ShouldAllowSplitView()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   if (!display::Screen::GetScreen()->InTabletMode()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   auto* overview_session = OverviewController::Get()->overview_session();
   DCHECK(overview_session);
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc
index c861141c..e2be98e 100644
--- a/ash/wm/splitview/split_view_controller.cc
+++ b/ash/wm/splitview/split_view_controller.cc
@@ -234,7 +234,7 @@
   // For the current tablet mode split view design, we can assume that the
   // `window` is being snapped to the same `snap_position` it was snapped since
   // it's single layer design. We need to check if the snap ratio is the same.
-  absl::optional<float> snap_ratio = window_state->snap_ratio();
+  std::optional<float> snap_ratio = window_state->snap_ratio();
   // Get the snap ratio for the window that is currently occupying the
   // `snap_position`.
   const auto* window_state_in_current_snap_position =
@@ -809,7 +809,7 @@
   bool do_snap_animation = false;
   int divider_position =
       split_view_divider_.divider_widget() ? GetDividerPosition() : -1;
-  if (absl::optional<float> snap_ratio = WindowState::Get(window)->snap_ratio();
+  if (std::optional<float> snap_ratio = WindowState::Get(window)->snap_ratio();
       snap_ratio) {
     divider_position = CalculateDividerPosition(snap_position, *snap_ratio);
     // If `other_window` can't fit in the requested snap ratio, show a snap
diff --git a/base/allocator/partition_alloc_support.cc b/base/allocator/partition_alloc_support.cc
index d6bc52d5..06e4088 100644
--- a/base/allocator/partition_alloc_support.cc
+++ b/base/allocator/partition_alloc_support.cc
@@ -8,6 +8,7 @@
 #include <cinttypes>
 #include <cstdint>
 #include <map>
+#include <optional>
 #include <string>
 
 #include "base/allocator/partition_alloc_features.h"
@@ -55,7 +56,6 @@
 #include "base/timer/timer.h"
 #include "base/trace_event/base_tracing.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(USE_STARSCAN)
 #include "base/allocator/partition_allocator/src/partition_alloc/shim/nonscannable_allocator.h"
@@ -421,7 +421,7 @@
   uintptr_t id = 0;
 };
 using DanglingRawPtrBuffer =
-    std::array<absl::optional<DanglingPointerFreeInfo>, 32>;
+    std::array<std::optional<DanglingPointerFreeInfo>, 32>;
 DanglingRawPtrBuffer g_stack_trace_buffer GUARDED_BY(g_stack_trace_buffer_lock);
 
 void DanglingRawPtrDetected(uintptr_t id) {
@@ -430,12 +430,12 @@
   internal::PartitionAutoLock guard(g_stack_trace_buffer_lock);
 
 #if DCHECK_IS_ON()
-  for (absl::optional<DanglingPointerFreeInfo>& entry : g_stack_trace_buffer) {
+  for (std::optional<DanglingPointerFreeInfo>& entry : g_stack_trace_buffer) {
     PA_DCHECK(!entry || entry->id != id);
   }
 #endif  // DCHECK_IS_ON()
 
-  for (absl::optional<DanglingPointerFreeInfo>& entry : g_stack_trace_buffer) {
+  for (std::optional<DanglingPointerFreeInfo>& entry : g_stack_trace_buffer) {
     if (!entry) {
       entry = {debug::StackTrace(), debug::TaskTrace(), id};
       return;
@@ -448,17 +448,17 @@
 
 // From the traces recorded in |DanglingRawPtrDetected|, extract the one
 // whose id match |id|. Return nullopt if not found.
-absl::optional<DanglingPointerFreeInfo> TakeDanglingPointerFreeInfo(
+std::optional<DanglingPointerFreeInfo> TakeDanglingPointerFreeInfo(
     uintptr_t id) {
   internal::PartitionAutoLock guard(g_stack_trace_buffer_lock);
-  for (absl::optional<DanglingPointerFreeInfo>& entry : g_stack_trace_buffer) {
+  for (std::optional<DanglingPointerFreeInfo>& entry : g_stack_trace_buffer) {
     if (entry && entry->id == id) {
-      absl::optional<DanglingPointerFreeInfo> result(entry);
-      entry = absl::nullopt;
+      std::optional<DanglingPointerFreeInfo> result(entry);
+      entry = std::nullopt;
       return result;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 // Extract from the StackTrace output, the signature of the pertinent caller.
@@ -562,7 +562,7 @@
 }
 
 std::string ExtractDanglingPtrSignature(
-    absl::optional<DanglingPointerFreeInfo> free_info,
+    std::optional<DanglingPointerFreeInfo> free_info,
     debug::StackTrace release_stack_trace,
     debug::TaskTrace release_task_trace) {
   if (free_info) {
@@ -597,7 +597,7 @@
   // allocate memory.
   debug::StackTrace stack_trace_release;
   debug::TaskTrace task_trace_release;
-  absl::optional<DanglingPointerFreeInfo> free_info =
+  std::optional<DanglingPointerFreeInfo> free_info =
       TakeDanglingPointerFreeInfo(id);
 
   if constexpr (dangling_pointer_type ==
diff --git a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_test_support.h b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_test_support.h
index c412281..3855327 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_test_support.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_test_support.h
@@ -5,8 +5,9 @@
 #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_SRC_PARTITION_ALLOC_POINTERS_RAW_PTR_TEST_SUPPORT_H_
 #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_SRC_PARTITION_ALLOC_POINTERS_RAW_PTR_TEST_SUPPORT_H_
 
+#include <optional>
+
 #include "testing/gmock/include/gmock/gmock.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // Struct intended to be used with designated initializers and passed
 // to the `CountersMatch()` matcher.
@@ -17,16 +18,16 @@
 // that would prohibit designated initiaizers.
 template <int IGNORE>
 struct CountingRawPtrExpectationTemplate {
-  absl::optional<int> wrap_raw_ptr_cnt;
-  absl::optional<int> release_wrapped_ptr_cnt;
-  absl::optional<int> get_for_dereference_cnt;
-  absl::optional<int> get_for_extraction_cnt;
-  absl::optional<int> get_for_comparison_cnt;
-  absl::optional<int> wrapped_ptr_swap_cnt;
-  absl::optional<int> wrapped_ptr_less_cnt;
-  absl::optional<int> pointer_to_member_operator_cnt;
-  absl::optional<int> wrap_raw_ptr_for_dup_cnt;
-  absl::optional<int> get_for_duplication_cnt;
+  std::optional<int> wrap_raw_ptr_cnt;
+  std::optional<int> release_wrapped_ptr_cnt;
+  std::optional<int> get_for_dereference_cnt;
+  std::optional<int> get_for_extraction_cnt;
+  std::optional<int> get_for_comparison_cnt;
+  std::optional<int> wrapped_ptr_swap_cnt;
+  std::optional<int> wrapped_ptr_less_cnt;
+  std::optional<int> pointer_to_member_operator_cnt;
+  std::optional<int> wrap_raw_ptr_for_dup_cnt;
+  std::optional<int> get_for_duplication_cnt;
 };
 using CountingRawPtrExpectations = CountingRawPtrExpectationTemplate<0>;
 
diff --git a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.cc b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.cc
index cd07130..368df22 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.cc
+++ b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.cc
@@ -8,6 +8,7 @@
 #include <cstddef>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <string>
 #include <thread>
 #include <type_traits>
@@ -42,7 +43,6 @@
 #include "partition_alloc/tagging.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
 
 #if BUILDFLAG(USE_ASAN_BACKUP_REF_PTR)
@@ -1429,7 +1429,7 @@
 
 TEST_F(RawPtrTest, WorksWithOptional) {
   int x = 0;
-  absl::optional<raw_ptr<int>> maybe_int;
+  std::optional<raw_ptr<int>> maybe_int;
   EXPECT_FALSE(maybe_int.has_value());
 
   maybe_int = nullptr;
@@ -1983,14 +1983,14 @@
 }
 #endif  // PA_CONFIG(REF_COUNT_CHECK_COOKIE)
 
-// Tests that ref-count management is correct, despite `absl::optional` may be
+// Tests that ref-count management is correct, despite `std::optional` may be
 // using `union` underneath.
 TEST_F(BackupRefPtrTest, WorksWithOptional) {
   void* ptr = allocator_.root()->Alloc(16);
   auto* ref_count = allocator_.root()->RefCountPointerFromObjectForTesting(ptr);
   EXPECT_TRUE(ref_count->IsAliveWithNoKnownRefs());
 
-  absl::optional<raw_ptr<void>> opt = ptr;
+  std::optional<raw_ptr<void>> opt = ptr;
   ASSERT_TRUE(opt.has_value());
   EXPECT_TRUE(ref_count->IsAlive() && !ref_count->IsAliveWithNoKnownRefs());
 
@@ -2007,7 +2007,7 @@
   EXPECT_TRUE(ref_count->IsAliveWithNoKnownRefs());
 
   {
-    absl::optional<raw_ptr<void>> opt2 = ptr;
+    std::optional<raw_ptr<void>> opt2 = ptr;
     ASSERT_TRUE(opt2.has_value());
     EXPECT_TRUE(ref_count->IsAlive() && !ref_count->IsAliveWithNoKnownRefs());
   }
diff --git a/base/android/child_process_service.cc b/base/android/child_process_service.cc
index e86e072d..8d6cb8d 100644
--- a/base/android/child_process_service.cc
+++ b/base/android/child_process_service.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <optional>
+
 #include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
 #include "base/android/library_loader/library_loader_hooks.h"
@@ -10,7 +12,6 @@
 #include "base/logging.h"
 #include "base/posix/global_descriptors.h"
 #include "base/process_launcher_jni/ChildProcessService_jni.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using base::android::JavaIntArrayToIntVector;
 using base::android::JavaParamRef;
@@ -25,11 +26,11 @@
     const JavaParamRef<jintArray>& j_fds,
     const JavaParamRef<jlongArray>& j_offsets,
     const JavaParamRef<jlongArray>& j_sizes) {
-  std::vector<absl::optional<std::string>> keys;
+  std::vector<std::optional<std::string>> keys;
   JavaObjectArrayReader<jstring> keys_array(j_keys);
   keys.reserve(checked_cast<size_t>(keys_array.size()));
   for (auto str : keys_array) {
-    absl::optional<std::string> key;
+    std::optional<std::string> key;
     if (str) {
       key = base::android::ConvertJavaStringToUTF8(env, str);
     }
@@ -53,7 +54,7 @@
   for (size_t i = 0; i < ids.size(); i++) {
     base::MemoryMappedFile::Region region = {offsets.at(i),
                                              static_cast<size_t>(sizes.at(i))};
-    const absl::optional<std::string>& key = keys.at(i);
+    const std::optional<std::string>& key = keys.at(i);
     const auto id = static_cast<GlobalDescriptors::Key>(ids.at(i));
     int fd = fds.at(i);
     if (key) {
diff --git a/base/android/jni_bytebuffer.cc b/base/android/jni_bytebuffer.cc
index a4b9862..580c0bd6 100644
--- a/base/android/jni_bytebuffer.cc
+++ b/base/android/jni_bytebuffer.cc
@@ -20,15 +20,15 @@
   return *span;
 }
 
-absl::optional<base::span<const uint8_t>> MaybeJavaByteBufferToSpan(
+std::optional<base::span<const uint8_t>> MaybeJavaByteBufferToSpan(
     JNIEnv* env,
     jobject buffer) {
   auto span = MaybeJavaByteBufferToMutableSpan(env, buffer);
-  return span ? absl::make_optional(base::span<const uint8_t>(*span))
-              : absl::nullopt;
+  return span ? std::make_optional(base::span<const uint8_t>(*span))
+              : std::nullopt;
 }
 
-absl::optional<base::span<uint8_t>> MaybeJavaByteBufferToMutableSpan(
+std::optional<base::span<uint8_t>> MaybeJavaByteBufferToMutableSpan(
     JNIEnv* env,
     jobject buffer) {
   void* data = env->GetDirectBufferAddress(buffer);
@@ -37,7 +37,7 @@
   // !data && size == 0 is allowed - this is how a 0-length Buffer is
   // represented.
   if (size < 0 || (!data && size > 0)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return base::span<uint8_t>(static_cast<uint8_t*>(data),
diff --git a/base/android/jni_bytebuffer.h b/base/android/jni_bytebuffer.h
index b4747135..990f6729 100644
--- a/base/android/jni_bytebuffer.h
+++ b/base/android/jni_bytebuffer.h
@@ -7,9 +7,10 @@
 
 #include <jni.h>
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/containers/span.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base::android {
 
@@ -24,17 +25,17 @@
 // errors.
 //
 // If needed, there are also variants below starting with Maybe that return
-// absl::nullopt in that case and do not crash.
+// std::nullopt in that case and do not crash.
 base::span<const uint8_t> BASE_EXPORT JavaByteBufferToSpan(JNIEnv* env,
                                                            jobject buffer);
 
 base::span<uint8_t> BASE_EXPORT JavaByteBufferToMutableSpan(JNIEnv* env,
                                                             jobject buffer);
 
-absl::optional<base::span<const uint8_t>> BASE_EXPORT
+std::optional<base::span<const uint8_t>> BASE_EXPORT
 MaybeJavaByteBufferToSpan(JNIEnv* env, jobject buffer);
 
-absl::optional<base::span<uint8_t>> BASE_EXPORT
+std::optional<base::span<uint8_t>> BASE_EXPORT
 MaybeJavaByteBufferToMutableSpan(JNIEnv* env, jobject buffer);
 
 }  // namespace base::android
diff --git a/base/android/jni_bytebuffer_unittest.cc b/base/android/jni_bytebuffer_unittest.cc
index 6d89cf0..00b7e2f9 100644
--- a/base/android/jni_bytebuffer_unittest.cc
+++ b/base/android/jni_bytebuffer_unittest.cc
@@ -48,7 +48,7 @@
 
   ScopedJavaLocalRef<jobject> jnonbuffer(env, env->NewObject(cls, init));
 
-  absl::optional<base::span<const uint8_t>> maybe_span =
+  std::optional<base::span<const uint8_t>> maybe_span =
       MaybeJavaByteBufferToSpan(env, jnonbuffer.obj());
   EXPECT_FALSE(maybe_span.has_value());
 }
diff --git a/base/android/radio_utils.cc b/base/android/radio_utils.cc
index bddced2..121e36a 100644
--- a/base/android/radio_utils.cc
+++ b/base/android/radio_utils.cc
@@ -4,8 +4,9 @@
 
 #include "base/android/radio_utils.h"
 
+#include <optional>
+
 #include "base/base_jni/RadioUtils_jni.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace android {
@@ -51,22 +52,22 @@
   }
 }
 
-absl::optional<RadioSignalLevel> RadioUtils::GetCellSignalLevel() {
+std::optional<RadioSignalLevel> RadioUtils::GetCellSignalLevel() {
   if (!IsSupported())
-    return absl::nullopt;
+    return std::nullopt;
 
   JNIEnv* env = AttachCurrentThread();
   int signal_level = Java_RadioUtils_getCellSignalLevel(env);
   if (signal_level < 0) {
-    return absl::nullopt;
+    return std::nullopt;
   } else {
     return static_cast<RadioSignalLevel>(signal_level);
   }
 }
 
-absl::optional<RadioDataActivity> RadioUtils::GetCellDataActivity() {
+std::optional<RadioDataActivity> RadioUtils::GetCellDataActivity() {
   if (!IsSupported())
-    return absl::nullopt;
+    return std::nullopt;
 
   JNIEnv* env = AttachCurrentThread();
   return static_cast<RadioDataActivity>(
diff --git a/base/android/radio_utils.h b/base/android/radio_utils.h
index 959647c..3474a85 100644
--- a/base/android/radio_utils.h
+++ b/base/android/radio_utils.h
@@ -5,8 +5,9 @@
 #ifndef BASE_ANDROID_RADIO_UTILS_H_
 #define BASE_ANDROID_RADIO_UTILS_H_
 
+#include <optional>
+
 #include "base/android/jni_android.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace android {
@@ -55,8 +56,8 @@
   };
   static bool IsSupported();
   static RadioConnectionType GetConnectionType();
-  static absl::optional<RadioSignalLevel> GetCellSignalLevel();
-  static absl::optional<RadioDataActivity> GetCellDataActivity();
+  static std::optional<RadioSignalLevel> GetCellSignalLevel();
+  static std::optional<RadioDataActivity> GetCellDataActivity();
 };
 
 }  // namespace android
diff --git a/base/android/unguessable_token_android.cc b/base/android/unguessable_token_android.cc
index ae4b642d..b4d71979 100644
--- a/base/android/unguessable_token_android.cc
+++ b/base/android/unguessable_token_android.cc
@@ -20,7 +20,7 @@
                                       static_cast<jlong>(low));
 }
 
-absl::optional<base::UnguessableToken>
+std::optional<base::UnguessableToken>
 UnguessableTokenAndroid::FromJavaUnguessableToken(
     JNIEnv* env,
     const JavaRef<jobject>& token) {
diff --git a/base/android/unguessable_token_android.h b/base/android/unguessable_token_android.h
index 07fc350..4c9d46a 100644
--- a/base/android/unguessable_token_android.h
+++ b/base/android/unguessable_token_android.h
@@ -22,7 +22,7 @@
       const base::UnguessableToken& token);
 
   // Create a native UnguessableToken from Java UnguessableToken |token|.
-  static absl::optional<base::UnguessableToken> FromJavaUnguessableToken(
+  static std::optional<base::UnguessableToken> FromJavaUnguessableToken(
       JNIEnv* env,
       const JavaRef<jobject>& token);
 
diff --git a/base/android/unguessable_token_android_unittest.cc b/base/android/unguessable_token_android_unittest.cc
index 0a399ec0..989887ce 100644
--- a/base/android/unguessable_token_android_unittest.cc
+++ b/base/android/unguessable_token_android_unittest.cc
@@ -18,7 +18,7 @@
       base::UnguessableToken::CreateForTesting(high, low);
   ScopedJavaLocalRef<jobject> jtoken =
       UnguessableTokenAndroid::Create(env, token);
-  absl::optional<base::UnguessableToken> result =
+  std::optional<base::UnguessableToken> result =
       UnguessableTokenAndroid::FromJavaUnguessableToken(env, jtoken);
 
   ASSERT_TRUE(result.has_value());
@@ -35,7 +35,7 @@
       UnguessableTokenAndroid::Create(env, token);
   ScopedJavaLocalRef<jobject> jtoken_clone =
       UnguessableTokenAndroid::ParcelAndUnparcelForTesting(env, jtoken);
-  absl::optional<base::UnguessableToken> token_clone =
+  std::optional<base::UnguessableToken> token_clone =
       UnguessableTokenAndroid::FromJavaUnguessableToken(env, jtoken_clone);
 
   ASSERT_TRUE(token_clone.has_value());
diff --git a/base/apple/scoped_mach_port.cc b/base/apple/scoped_mach_port.cc
index c5bb5ca3..1a309b2 100644
--- a/base/apple/scoped_mach_port.cc
+++ b/base/apple/scoped_mach_port.cc
@@ -36,7 +36,7 @@
 
 bool CreateMachPort(ScopedMachReceiveRight* receive,
                     ScopedMachSendRight* send,
-                    absl::optional<mach_port_msgcount_t> queue_limit) {
+                    std::optional<mach_port_msgcount_t> queue_limit) {
   mach_port_options_t options{};
   options.flags = (send != nullptr ? MPO_INSERT_SEND_RIGHT : 0);
 
diff --git a/base/apple/scoped_mach_port.h b/base/apple/scoped_mach_port.h
index 6b3236e..99706b0 100644
--- a/base/apple/scoped_mach_port.h
+++ b/base/apple/scoped_mach_port.h
@@ -7,9 +7,10 @@
 
 #include <mach/mach.h>
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/scoped_generic.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base::apple {
 
@@ -68,7 +69,7 @@
 BASE_EXPORT bool CreateMachPort(
     ScopedMachReceiveRight* receive,
     ScopedMachSendRight* send,
-    absl::optional<mach_port_msgcount_t> queue_limit = absl::nullopt);
+    std::optional<mach_port_msgcount_t> queue_limit = std::nullopt);
 
 // Increases the user reference count for MACH_PORT_RIGHT_SEND by 1 and returns
 // a new scoper to manage the additional right.
diff --git a/base/apple/scoped_nsautorelease_pool_unittest.mm b/base/apple/scoped_nsautorelease_pool_unittest.mm
index 8bd1120..19b0af4 100644
--- a/base/apple/scoped_nsautorelease_pool_unittest.mm
+++ b/base/apple/scoped_nsautorelease_pool_unittest.mm
@@ -4,15 +4,16 @@
 
 #import "base/apple/scoped_nsautorelease_pool.h"
 
+#include <optional>
+
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base::apple {
 
 #if DCHECK_IS_ON()
 TEST(ScopedNSAutoreleasePoolTest, DieOutOfOrder) {
-  absl::optional<ScopedNSAutoreleasePool> pool1;
-  absl::optional<ScopedNSAutoreleasePool> pool2;
+  std::optional<ScopedNSAutoreleasePool> pool1;
+  std::optional<ScopedNSAutoreleasePool> pool2;
 
   // Instantiate the pools in the order 1, then 2.
   pool1.emplace();
diff --git a/base/base64.cc b/base/base64.cc
index c333fd9..660ab8d 100644
--- a/base/base64.cc
+++ b/base/base64.cc
@@ -87,14 +87,14 @@
   return true;
 }
 
-absl::optional<std::vector<uint8_t>> Base64Decode(StringPiece input) {
+std::optional<std::vector<uint8_t>> Base64Decode(StringPiece input) {
   std::vector<uint8_t> ret(modp_b64_decode_len(input.size()));
 
   size_t input_size = input.size();
   size_t output_size = modp_b64_decode(reinterpret_cast<char*>(ret.data()),
                                        input.data(), input_size);
   if (output_size == MODP_B64_ERROR)
-    return absl::nullopt;
+    return std::nullopt;
 
   ret.resize(output_size);
   return ret;
diff --git a/base/base64.h b/base/base64.h
index 6c35e66..3ebf60c 100644
--- a/base/base64.h
+++ b/base/base64.h
@@ -7,13 +7,13 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "base/base_export.h"
 #include "base/containers/span.h"
 #include "base/strings/string_piece.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -48,9 +48,8 @@
     std::string* output,
     Base64DecodePolicy policy = Base64DecodePolicy::kStrict);
 
-// Decodes the base64 input string. Returns `absl::nullopt` if unsuccessful.
-BASE_EXPORT absl::optional<std::vector<uint8_t>> Base64Decode(
-    StringPiece input);
+// Decodes the base64 input string. Returns `std::nullopt` if unsuccessful.
+BASE_EXPORT std::optional<std::vector<uint8_t>> Base64Decode(StringPiece input);
 
 }  // namespace base
 
diff --git a/base/base64url.cc b/base/base64url.cc
index 9f9f4e16..daf91ff 100644
--- a/base/base64url.cc
+++ b/base/base64url.cc
@@ -35,18 +35,18 @@
   }
 
  private:
-  const absl::optional<std::string> str_;
+  const std::optional<std::string> str_;
   const StringPiece piece_;
 };
 
 // Converts the base64url `input` into a plain base64 string.
-absl::optional<StringPieceOrString> Base64ToBase64URL(
+std::optional<StringPieceOrString> Base64ToBase64URL(
     StringPiece input,
     Base64UrlDecodePolicy policy) {
   // Characters outside of the base64url alphabet are disallowed, which includes
   // the {+, /} characters found in the conventional base64 alphabet.
   if (input.find_first_of(kBase64Chars) != std::string::npos)
-    return absl::nullopt;
+    return std::nullopt;
 
   const size_t required_padding_characters = input.size() % 4;
   const bool needs_replacement =
@@ -56,7 +56,7 @@
     case Base64UrlDecodePolicy::REQUIRE_PADDING:
       // Fail if the required padding is not included in |input|.
       if (required_padding_characters > 0)
-        return absl::nullopt;
+        return std::nullopt;
       break;
     case Base64UrlDecodePolicy::IGNORE_PADDING:
       // Missing padding will be silently appended.
@@ -64,7 +64,7 @@
     case Base64UrlDecodePolicy::DISALLOW_PADDING:
       // Fail if padding characters are included in |input|.
       if (input.find_first_of(kPaddingChar) != std::string::npos)
-        return absl::nullopt;
+        return std::nullopt;
       break;
   }
 
@@ -129,7 +129,7 @@
 bool Base64UrlDecode(StringPiece input,
                      Base64UrlDecodePolicy policy,
                      std::string* output) {
-  absl::optional<StringPieceOrString> base64_input =
+  std::optional<StringPieceOrString> base64_input =
       Base64ToBase64URL(input, policy);
   if (!base64_input) {
     return false;
@@ -137,13 +137,13 @@
   return Base64Decode(base64_input->get(), output);
 }
 
-absl::optional<std::vector<uint8_t>> Base64UrlDecode(
+std::optional<std::vector<uint8_t>> Base64UrlDecode(
     StringPiece input,
     Base64UrlDecodePolicy policy) {
-  absl::optional<StringPieceOrString> base64_input =
+  std::optional<StringPieceOrString> base64_input =
       Base64ToBase64URL(input, policy);
   if (!base64_input) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return Base64Decode(base64_input->get());
 }
diff --git a/base/base64url.h b/base/base64url.h
index b8f5c9f8..6fa0484 100644
--- a/base/base64url.h
+++ b/base/base64url.h
@@ -5,13 +5,13 @@
 #ifndef BASE_BASE64URL_H_
 #define BASE_BASE64URL_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "base/base_export.h"
 #include "base/containers/span.h"
 #include "base/strings/string_piece.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -58,7 +58,7 @@
                                                std::string* output);
 
 // Same as the previous function, but writing to a `std::vector`.
-[[nodiscard]] BASE_EXPORT absl::optional<std::vector<uint8_t>> Base64UrlDecode(
+[[nodiscard]] BASE_EXPORT std::optional<std::vector<uint8_t>> Base64UrlDecode(
     StringPiece input,
     Base64UrlDecodePolicy policy);
 
diff --git a/base/base64url_unittest.cc b/base/base64url_unittest.cc
index 92d2781..ddf072d5 100644
--- a/base/base64url_unittest.cc
+++ b/base/base64url_unittest.cc
@@ -41,7 +41,7 @@
 
   EXPECT_THAT(Base64UrlDecode(string_encoded_with_padding,
                               Base64UrlDecodePolicy::DISALLOW_PADDING),
-              absl::nullopt);
+              std::nullopt);
 }
 
 TEST(Base64UrlTest, BinaryOmitPaddingPolicy) {
@@ -70,7 +70,7 @@
 
   EXPECT_THAT(Base64UrlDecode(string_encoded_without_padding,
                               Base64UrlDecodePolicy::REQUIRE_PADDING),
-              absl::nullopt);
+              std::nullopt);
 }
 
 TEST(Base64UrlTest, EncodeIncludePaddingPolicy) {
@@ -143,7 +143,7 @@
       Base64UrlDecode("invalid=", Base64UrlDecodePolicy::DISALLOW_PADDING));
 
   static constexpr uint8_t kExpected[] = {'1', '2', '3', '4'};
-  absl::optional<std::vector<uint8_t>> result =
+  std::optional<std::vector<uint8_t>> result =
       Base64UrlDecode("MTIzNA", Base64UrlDecodePolicy::DISALLOW_PADDING);
   ASSERT_TRUE(ranges::equal(*result, kExpected));
 }
diff --git a/base/base_paths_posix.cc b/base/base_paths_posix.cc
index 4e32871..d83961ad 100644
--- a/base/base_paths_posix.cc
+++ b/base/base_paths_posix.cc
@@ -49,7 +49,7 @@
       return true;
 #elif BUILDFLAG(IS_FREEBSD)
       int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
-      absl::optional<std::string> bin_dir = StringSysctl(name, std::size(name));
+      std::optional<std::string> bin_dir = StringSysctl(name, std::size(name));
       if (!bin_dir.has_value() || bin_dir.value().length() <= 1) {
         NOTREACHED() << "Unable to resolve path.";
         return false;
diff --git a/base/containers/buffer_iterator_unittest.cc b/base/containers/buffer_iterator_unittest.cc
index f0ff870..fc27316 100644
--- a/base/containers/buffer_iterator_unittest.cc
+++ b/base/containers/buffer_iterator_unittest.cc
@@ -7,10 +7,10 @@
 #include <string.h>
 
 #include <limits>
+#include <optional>
 #include <vector>
 
 #include "base/containers/span.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace base {
@@ -180,7 +180,7 @@
   }
 
   BufferIterator<char> iterator(buffer);
-  absl::optional<TestStruct> actual;
+  std::optional<TestStruct> actual;
   for (int i = 0; i < kNumCopies; i++) {
     actual = iterator.CopyObject<TestStruct>();
     ASSERT_TRUE(actual.has_value());
diff --git a/base/containers/containers_memory_benchmark.cc b/base/containers/containers_memory_benchmark.cc
index 28a623b..edba255 100644
--- a/base/containers/containers_memory_benchmark.cc
+++ b/base/containers/containers_memory_benchmark.cc
@@ -53,6 +53,7 @@
 #include <charconv>
 #include <limits>
 #include <map>
+#include <optional>
 #include <string>
 #include <unordered_map>
 #include <utility>
@@ -67,7 +68,6 @@
 #include "third_party/abseil-cpp/absl/container/btree_map.h"
 #include "third_party/abseil-cpp/absl/container/flat_hash_map.h"
 #include "third_party/abseil-cpp/absl/container/node_hash_map.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -131,7 +131,7 @@
 
   RAW_LOG(INFO, "iteration 0");
   // Record any initial allocations made by an empty container.
-  absl::optional<ScopedLogAllocAndFree> base_size_logger;
+  std::optional<ScopedLogAllocAndFree> base_size_logger;
   base_size_logger.emplace();
   Container c;
   base_size_logger.reset();
diff --git a/base/critical_closure.h b/base/critical_closure.h
index 064d56a..0c6a773b 100644
--- a/base/critical_closure.h
+++ b/base/critical_closure.h
@@ -14,9 +14,10 @@
 #include "build/ios_buildflags.h"
 
 #if BUILDFLAG(IS_IOS) && !BUILDFLAG(IS_IOS_APP_EXTENSION)
+#include <optional>
+
 #include "base/functional/bind.h"
 #include "base/ios/scoped_critical_action.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #endif
 
 namespace base {
@@ -51,7 +52,7 @@
   void Run();
 
  private:
-  absl::optional<ios::ScopedCriticalAction> critical_action_;
+  std::optional<ios::ScopedCriticalAction> critical_action_;
   std::string task_name_;
   OnceClosure closure_;
 };
diff --git a/base/debug/elf_reader.cc b/base/debug/elf_reader.cc
index 0fa0b6b..296fba6 100644
--- a/base/debug/elf_reader.cc
+++ b/base/debug/elf_reader.cc
@@ -8,12 +8,13 @@
 #include <elf.h>
 #include <string.h>
 
+#include <optional>
+
 #include "base/bits.h"
 #include "base/containers/span.h"
 #include "base/hash/sha1.h"
 #include "base/strings/safe_sprintf.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // NOTE: This code may be used in crash handling code, so the implementation
 // must avoid dynamic memory allocation or using data structures which rely on
@@ -122,7 +123,7 @@
   return 0;
 }
 
-absl::optional<StringPiece> ReadElfLibraryName(const void* elf_mapped_base) {
+std::optional<StringPiece> ReadElfLibraryName(const void* elf_mapped_base) {
   // NOTE: Function should use async signal safe calls only.
 
   const Ehdr* elf_header = GetElfHeader(elf_mapped_base);
@@ -163,7 +164,7 @@
       return StringPiece(strtab_addr + soname_strtab_offset);
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 span<const Phdr> GetElfProgramHeaders(const void* elf_mapped_base) {
diff --git a/base/debug/elf_reader.h b/base/debug/elf_reader.h
index de56ca8..0092415 100644
--- a/base/debug/elf_reader.h
+++ b/base/debug/elf_reader.h
@@ -7,11 +7,12 @@
 
 #include <elf.h>
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/containers/span.h"
 #include "base/hash/sha1.h"
 #include "base/strings/string_piece.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // Functions for querying metadata from ELF binaries. All functions are signal
 // safe and require that the file be fully memory mapped.
@@ -38,7 +39,7 @@
 
 // Returns the library name from the ELF file mapped at |elf_mapped_base|.
 // Returns an empty result if the name could not be read.
-absl::optional<StringPiece> BASE_EXPORT
+std::optional<StringPiece> BASE_EXPORT
 ReadElfLibraryName(const void* elf_mapped_base);
 
 // Returns a span of ELF program headers for the ELF file mapped at
diff --git a/base/debug/elf_reader_unittest.cc b/base/debug/elf_reader_unittest.cc
index 42fc4aa..747c0c4 100644
--- a/base/debug/elf_reader_unittest.cc
+++ b/base/debug/elf_reader_unittest.cc
@@ -7,6 +7,7 @@
 #include <dlfcn.h>
 
 #include <cstdint>
+#include <optional>
 
 #include "base/debug/test_elf_image_builder.h"
 #include "base/files/memory_mapped_file.h"
@@ -14,7 +15,6 @@
 #include "base/strings/string_util.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 extern char __executable_start;
 
@@ -128,9 +128,9 @@
                            .AddSoName("mysoname")
                            .Build();
 
-  absl::optional<StringPiece> library_name =
+  std::optional<StringPiece> library_name =
       ReadElfLibraryName(image.elf_start());
-  ASSERT_NE(absl::nullopt, library_name);
+  ASSERT_NE(std::nullopt, library_name);
   EXPECT_EQ("mysoname", *library_name);
 }
 
@@ -139,9 +139,9 @@
                            .AddLoadSegment(PF_R | PF_X, /* size = */ 2000)
                            .Build();
 
-  absl::optional<StringPiece> library_name =
+  std::optional<StringPiece> library_name =
       ReadElfLibraryName(image.elf_start());
-  EXPECT_EQ(absl::nullopt, library_name);
+  EXPECT_EQ(std::nullopt, library_name);
 }
 
 TEST_P(ElfReaderTest, GetRelocationOffset) {
diff --git a/base/debug/gdi_debug_util_win.cc b/base/debug/gdi_debug_util_win.cc
index 1b54861..8f11713 100644
--- a/base/debug/gdi_debug_util_win.cc
+++ b/base/debug/gdi_debug_util_win.cc
@@ -3,22 +3,22 @@
 // found in the LICENSE file.
 #include "base/debug/gdi_debug_util_win.h"
 
-#include <algorithm>
-#include <cmath>
-
 #include <TlHelp32.h>
 #include <psapi.h>
 #include <stddef.h>
 #include <windows.h>
 #include <winternl.h>
 
+#include <algorithm>
+#include <cmath>
+#include <optional>
+
 #include "base/debug/alias.h"
 #include "base/logging.h"
 #include "base/process/process.h"
 #include "base/win/scoped_handle.h"
 #include "base/win/win_util.h"
 #include "base/win/windows_version.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -287,11 +287,11 @@
 }
 
 template <typename ProcessType>
-absl::optional<base::debug::GdiHandleCounts> CollectGdiHandleCountsImpl(
+std::optional<base::debug::GdiHandleCounts> CollectGdiHandleCountsImpl(
     DWORD pid) {
   base::Process process = base::Process::OpenWithExtraPrivileges(pid);
   if (!process.IsValid())
-    return absl::nullopt;
+    return std::nullopt;
 
   std::vector<GdiTableEntry<typename ProcessType::NativePointerType>>
       gdi_entries = GetGdiTableEntries<ProcessType>(process);
@@ -300,7 +300,7 @@
 
 // Returns the GDI Handle counts from the GDI Shared handle table. Empty on
 // failure.
-absl::optional<base::debug::GdiHandleCounts> CollectGdiHandleCounts(DWORD pid) {
+std::optional<base::debug::GdiHandleCounts> CollectGdiHandleCounts(DWORD pid) {
   if (base::win::OSInfo::GetInstance()->IsWowX86OnAMD64()) {
     return CollectGdiHandleCountsImpl<WowProcessTypes>(pid);
   }
@@ -460,7 +460,7 @@
   base::debug::Alias(&num_global_gdi_handles);
   base::debug::Alias(&num_global_user_handles);
 
-  absl::optional<GdiHandleCounts> optional_handle_counts =
+  std::optional<GdiHandleCounts> optional_handle_counts =
       CollectGdiHandleCounts(GetCurrentProcessId());
   bool handle_counts_set = optional_handle_counts.has_value();
   GdiHandleCounts handle_counts =
@@ -504,7 +504,7 @@
 }
 
 GdiHandleCounts GetGDIHandleCountsInCurrentProcessForTesting() {
-  absl::optional<GdiHandleCounts> handle_counts =
+  std::optional<GdiHandleCounts> handle_counts =
       CollectGdiHandleCounts(GetCurrentProcessId());
   DCHECK(handle_counts.has_value());
   return handle_counts.value_or(GdiHandleCounts());
diff --git a/base/debug/stack_trace.cc b/base/debug/stack_trace.cc
index 551c0d2..aca23a83 100644
--- a/base/debug/stack_trace.cc
+++ b/base/debug/stack_trace.cc
@@ -14,7 +14,7 @@
 #include "build/config/compiler/compiler_buildflags.h"
 
 #if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include <optional>
 
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
 #include <pthread.h>
diff --git a/base/debug/stack_trace_fuchsia.cc b/base/debug/stack_trace_fuchsia.cc
index 543e475b..512a720 100644
--- a/base/debug/stack_trace_fuchsia.cc
+++ b/base/debug/stack_trace_fuchsia.cc
@@ -170,7 +170,7 @@
 
     // Get the human-readable library name from the ELF header, falling back on
     // using names from the link map for binaries that aren't shared libraries.
-    absl::optional<StringPiece> elf_library_name =
+    std::optional<StringPiece> elf_library_name =
         ReadElfLibraryName(next_entry.addr);
     if (elf_library_name) {
       strlcpy(next_entry.name, elf_library_name->data(),
diff --git a/base/debug/task_trace.h b/base/debug/task_trace.h
index 7cad5315..d643e76 100644
--- a/base/debug/task_trace.h
+++ b/base/debug/task_trace.h
@@ -6,12 +6,12 @@
 #define BASE_DEBUG_TASK_TRACE_H_
 
 #include <iosfwd>
+#include <optional>
 #include <string>
 
 #include "base/base_export.h"
 #include "base/containers/span.h"
 #include "base/debug/stack_trace.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace debug {
@@ -55,7 +55,7 @@
   size_t GetAddresses(span<const void*> addresses) const;
 
  private:
-  absl::optional<StackTrace> stack_trace_;
+  std::optional<StackTrace> stack_trace_;
   bool trace_overflow_ = false;
 };
 
diff --git a/base/debug/test_elf_image_builder.h b/base/debug/test_elf_image_builder.h
index 095e191..47f1bf1 100644
--- a/base/debug/test_elf_image_builder.h
+++ b/base/debug/test_elf_image_builder.h
@@ -8,13 +8,13 @@
 #include <elf.h>
 
 #include <cstdint>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "base/containers/span.h"
 #include "base/memory/raw_ptr.h"
 #include "base/strings/string_piece.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if __SIZEOF_POINTER__ == 4
 using Addr = Elf32_Addr;
@@ -121,7 +121,7 @@
   const MappingType mapping_type_;
   std::vector<std::vector<uint8_t>> note_contents_;
   std::vector<LoadSegment> load_segments_;
-  absl::optional<std::string> soname_;
+  std::optional<std::string> soname_;
 };
 
 }  // namespace base
diff --git a/base/feature_list.cc b/base/feature_list.cc
index 8a26a97..6849e50 100644
--- a/base/feature_list.cc
+++ b/base/feature_list.cc
@@ -470,14 +470,14 @@
 }
 
 // static
-absl::optional<bool> FeatureList::GetStateIfOverridden(const Feature& feature) {
+std::optional<bool> FeatureList::GetStateIfOverridden(const Feature& feature) {
   if (!g_feature_list_instance ||
       !g_feature_list_instance->AllowFeatureAccess(feature)) {
     EarlyFeatureAccessTracker::GetInstance()->AccessedFeature(
         feature, g_feature_list_instance &&
                      g_feature_list_instance->IsEarlyAccessInstance());
     // If there is no feature list, there can be no overrides.
-    return absl::nullopt;
+    return std::nullopt;
   }
   return g_feature_list_instance->IsFeatureEnabledIfOverridden(feature);
 }
@@ -725,7 +725,7 @@
   return feature.default_state == FEATURE_ENABLED_BY_DEFAULT;
 }
 
-absl::optional<bool> FeatureList::IsFeatureEnabledIfOverridden(
+std::optional<bool> FeatureList::IsFeatureEnabledIfOverridden(
     const Feature& feature) const {
   OverrideState overridden_state = GetOverrideState(feature);
 
@@ -733,7 +733,7 @@
   if (overridden_state != OVERRIDE_USE_DEFAULT)
     return overridden_state == OVERRIDE_ENABLE_FEATURE;
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 FeatureList::OverrideState FeatureList::GetOverrideState(
diff --git a/base/feature_list.h b/base/feature_list.h
index a3a78e3..dee0a52 100644
--- a/base/feature_list.h
+++ b/base/feature_list.h
@@ -9,6 +9,7 @@
 #include <functional>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -26,7 +27,6 @@
 #include "base/synchronization/lock.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -414,7 +414,7 @@
   // has been registered via SetInstance(). Additionally, a feature with a given
   // name must only have a single corresponding Feature struct, which is checked
   // in builds with DCHECKs enabled.
-  static absl::optional<bool> GetStateIfOverridden(const Feature& feature);
+  static std::optional<bool> GetStateIfOverridden(const Feature& feature);
 
   // Returns the field trial associated with the given |feature|. Must only be
   // called after the singleton instance has been registered via SetInstance().
@@ -567,7 +567,7 @@
   // Returns whether the given |feature| is enabled. This is invoked by the
   // public FeatureList::GetStateIfOverridden() static function on the global
   // singleton. Requires the FeatureList to have already been fully initialized.
-  absl::optional<bool> IsFeatureEnabledIfOverridden(
+  std::optional<bool> IsFeatureEnabledIfOverridden(
       const Feature& feature) const;
 
   // Returns the override state of a given |feature|. If the feature was not
diff --git a/base/files/block_tests_writing_to_special_dirs.cc b/base/files/block_tests_writing_to_special_dirs.cc
index 8dd595d..59dcb809 100644
--- a/base/files/block_tests_writing_to_special_dirs.cc
+++ b/base/files/block_tests_writing_to_special_dirs.cc
@@ -13,9 +13,9 @@
 namespace base {
 
 // static
-absl::optional<BlockTestsWritingToSpecialDirs>&
+std::optional<BlockTestsWritingToSpecialDirs>&
 BlockTestsWritingToSpecialDirs::Get() {
-  static NoDestructor<absl::optional<BlockTestsWritingToSpecialDirs>>
+  static NoDestructor<std::optional<BlockTestsWritingToSpecialDirs>>
       block_tests_writing_to_special_dirs;
   return *block_tests_writing_to_special_dirs;
 }
diff --git a/base/files/block_tests_writing_to_special_dirs.h b/base/files/block_tests_writing_to_special_dirs.h
index 25670521..f1136b81 100644
--- a/base/files/block_tests_writing_to_special_dirs.h
+++ b/base/files/block_tests_writing_to_special_dirs.h
@@ -5,12 +5,12 @@
 #ifndef BASE_FILES_BLOCK_TESTS_WRITING_TO_SPECIAL_DIRS_H_
 #define BASE_FILES_BLOCK_TESTS_WRITING_TO_SPECIAL_DIRS_H_
 
+#include <optional>
 #include <set>
 #include <vector>
 
 #include "base/base_export.h"
 #include "base/gtest_prod_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -43,7 +43,7 @@
   // `CanWriteToPath` above checks the paths stored in that object, if it is
   // set. Thus, only ScopedBlockTestsWritingToSpecialDirs should be able to
   // block tests writing to special dirs.
-  static absl::optional<BlockTestsWritingToSpecialDirs>& Get();
+  static std::optional<BlockTestsWritingToSpecialDirs>& Get();
 
   // `blocked_paths_` will be initialized lazily, from `blocked_dirs_`.
   std::set<FilePath> blocked_paths_;
diff --git a/base/files/block_tests_writing_to_special_dirs_unittest.cc b/base/files/block_tests_writing_to_special_dirs_unittest.cc
index a43567d..eabbe56c 100644
--- a/base/files/block_tests_writing_to_special_dirs_unittest.cc
+++ b/base/files/block_tests_writing_to_special_dirs_unittest.cc
@@ -29,10 +29,10 @@
   }
 
  protected:
-  absl::optional<BlockTestsWritingToSpecialDirs>& Get() {
+  std::optional<BlockTestsWritingToSpecialDirs>& Get() {
     return BlockTestsWritingToSpecialDirs::Get();
   }
-  absl::optional<BlockTestsWritingToSpecialDirs> save_block_tests_;
+  std::optional<BlockTestsWritingToSpecialDirs> save_block_tests_;
 };
 
 // Test that with no special dirs blocked,
diff --git a/base/files/file.cc b/base/files/file.cc
index a3bb8c9..1c540c8 100644
--- a/base/files/file.cc
+++ b/base/files/file.cc
@@ -99,12 +99,12 @@
 }
 #endif
 
-absl::optional<size_t> File::Read(int64_t offset, span<uint8_t> data) {
+std::optional<size_t> File::Read(int64_t offset, span<uint8_t> data) {
   span<char> chars = base::as_writable_chars(data);
   int size = checked_cast<int>(chars.size());
   int result = Read(offset, chars.data(), size);
   if (result < 0) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return checked_cast<size_t>(result);
 }
@@ -114,12 +114,12 @@
   return Read(offset, data) == static_cast<int>(data.size());
 }
 
-absl::optional<size_t> File::ReadAtCurrentPos(span<uint8_t> data) {
+std::optional<size_t> File::ReadAtCurrentPos(span<uint8_t> data) {
   span<char> chars = base::as_writable_chars(data);
   int size = checked_cast<int>(chars.size());
   int result = ReadAtCurrentPos(chars.data(), size);
   if (result < 0) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return checked_cast<size_t>(result);
 }
@@ -129,12 +129,12 @@
   return ReadAtCurrentPos(data) == static_cast<int>(data.size());
 }
 
-absl::optional<size_t> File::Write(int64_t offset, span<const uint8_t> data) {
+std::optional<size_t> File::Write(int64_t offset, span<const uint8_t> data) {
   span<const char> chars = base::as_chars(data);
   int size = checked_cast<int>(chars.size());
   int result = Write(offset, chars.data(), size);
   if (result < 0) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return checked_cast<size_t>(result);
 }
@@ -144,12 +144,12 @@
   return Write(offset, data) == static_cast<int>(data.size());
 }
 
-absl::optional<size_t> File::WriteAtCurrentPos(span<const uint8_t> data) {
+std::optional<size_t> File::WriteAtCurrentPos(span<const uint8_t> data) {
   span<const char> chars = base::as_chars(data);
   int size = checked_cast<int>(chars.size());
   int result = WriteAtCurrentPos(chars.data(), size);
   if (result < 0) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return checked_cast<size_t>(result);
 }
diff --git a/base/files/file.h b/base/files/file.h
index e33842eb..08ce29ac 100644
--- a/base/files/file.h
+++ b/base/files/file.h
@@ -7,6 +7,7 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 
 #include "base/base_export.h"
@@ -17,7 +18,6 @@
 #include "base/time/time.h"
 #include "base/trace_event/base_tracing_forward.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 struct stat;
 
@@ -221,11 +221,11 @@
   // normal expectation is that actually |size| bytes are read unless there is
   // an error.
   int Read(int64_t offset, char* data, int size);
-  absl::optional<size_t> Read(int64_t offset, base::span<uint8_t> data);
+  std::optional<size_t> Read(int64_t offset, base::span<uint8_t> data);
 
   // Same as above but without seek.
   int ReadAtCurrentPos(char* data, int size);
-  absl::optional<size_t> ReadAtCurrentPos(base::span<uint8_t> data);
+  std::optional<size_t> ReadAtCurrentPos(base::span<uint8_t> data);
 
   // Reads the given number of bytes (or until EOF is reached) starting with the
   // given offset, but does not make any effort to read all data on all
@@ -242,11 +242,11 @@
   // Ignores the offset and writes to the end of the file if the file was opened
   // with FLAG_APPEND.
   int Write(int64_t offset, const char* data, int size);
-  absl::optional<size_t> Write(int64_t offset, base::span<const uint8_t> data);
+  std::optional<size_t> Write(int64_t offset, base::span<const uint8_t> data);
 
   // Save as above but without seek.
   int WriteAtCurrentPos(const char* data, int size);
-  absl::optional<size_t> WriteAtCurrentPos(base::span<const uint8_t> data);
+  std::optional<size_t> WriteAtCurrentPos(base::span<const uint8_t> data);
 
   // Save as above but does not make any effort to write all data on all
   // platforms. Returns the number of bytes written, or -1 on error.
diff --git a/base/files/file_path_watcher.h b/base/files/file_path_watcher.h
index 100fefd..f6575808 100644
--- a/base/files/file_path_watcher.h
+++ b/base/files/file_path_watcher.h
@@ -8,6 +8,7 @@
 #define BASE_FILES_FILE_PATH_WATCHER_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 
@@ -19,7 +20,6 @@
 #include "base/sequence_checker.h"
 #include "base/task/sequenced_task_runner.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -75,7 +75,7 @@
     // to coalesce these events. Consider upstreaming this event coalesing logic
     // to the platform-specific implementations and then replacing `cookie` with
     // the file path that the file was moved from, if this is known.
-    absl::optional<uint32_t> cookie;
+    std::optional<uint32_t> cookie;
   };
 
   // TODO(https://crbug.com/1425601): Rename this now that this class declares
diff --git a/base/files/file_path_watcher_inotify.cc b/base/files/file_path_watcher_inotify.cc
index 7a2872f..dc88723 100644
--- a/base/files/file_path_watcher_inotify.cc
+++ b/base/files/file_path_watcher_inotify.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/files/file_path_watcher.h"
+#include "base/files/file_path_watcher_inotify.h"
 
 #include <errno.h>
 #include <poll.h>
@@ -18,6 +18,7 @@
 #include <fstream>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <unordered_map>
 #include <utility>
@@ -26,7 +27,7 @@
 #include "base/containers/contains.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_path.h"
-#include "base/files/file_path_watcher_inotify.h"
+#include "base/files/file_path_watcher.h"
 #include "base/files/file_util.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
@@ -44,7 +45,6 @@
 #include "base/threading/scoped_blocking_call.h"
 #include "base/trace_event/base_tracing.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -419,7 +419,7 @@
                               : FilePathWatcher::FilePathType::kFile,
         .change_type = ToChangeType(event),
         .cookie =
-            event->cookie ? absl::make_optional(event->cookie) : absl::nullopt,
+            event->cookie ? std::make_optional(event->cookie) : std::nullopt,
     };
     bool created = event->mask & (IN_CREATE | IN_MOVED_TO);
     bool deleted = event->mask & (IN_DELETE | IN_MOVED_FROM);
@@ -838,7 +838,7 @@
   return false;
 #else   // BUILDFLAG(IS_FUCHSIA)
   DUMP_WILL_BE_CHECK_EQ(InotifyReader::kInvalidWatch, watch_entry->watch);
-  absl::optional<FilePath> link = ReadSymbolicLinkAbsolute(path);
+  std::optional<FilePath> link = ReadSymbolicLinkAbsolute(path);
   if (!link) {
     return true;
   }
diff --git a/base/files/file_posix.cc b/base/files/file_posix.cc
index eca609c..ce18c41 100644
--- a/base/files/file_posix.cc
+++ b/base/files/file_posix.cc
@@ -18,6 +18,8 @@
 
 static_assert(sizeof(base::stat_wrapper_t::st_size) >= 8);
 
+#include <optional>
+
 #include "base/check_op.h"
 #include "base/notimplemented.h"
 #include "base/notreached.h"
@@ -26,7 +28,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/scoped_blocking_call.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_ANDROID)
 #include "base/os_compat_android.h"
@@ -76,7 +77,7 @@
 }
 
 #if !BUILDFLAG(IS_FUCHSIA)
-short FcntlFlockType(absl::optional<File::LockMode> mode) {
+short FcntlFlockType(std::optional<File::LockMode> mode) {
   if (!mode.has_value())
     return F_UNLCK;
   switch (mode.value()) {
@@ -89,7 +90,7 @@
 }
 
 File::Error CallFcntlFlock(PlatformFile file,
-                           absl::optional<File::LockMode> mode) {
+                           std::optional<File::LockMode> mode) {
   struct flock lock;
   lock.l_type = FcntlFlockType(std::move(mode));
   lock.l_whence = SEEK_SET;
@@ -121,7 +122,7 @@
 }
 
 File::Error CallFcntlFlock(PlatformFile file,
-                           absl::optional<File::LockMode> mode) {
+                           std::optional<File::LockMode> mode) {
   NOTIMPLEMENTED();  // NaCl doesn't implement flock struct.
   return File::FILE_ERROR_INVALID_OPERATION;
 }
@@ -421,7 +422,7 @@
 
 File::Error File::Unlock() {
   SCOPED_FILE_TRACE("Unlock");
-  return CallFcntlFlock(file_.get(), absl::optional<File::LockMode>());
+  return CallFcntlFlock(file_.get(), std::optional<File::LockMode>());
 }
 #endif
 
diff --git a/base/files/file_proxy.cc b/base/files/file_proxy.cc
index b4430e0c..ec45495 100644
--- a/base/files/file_proxy.cc
+++ b/base/files/file_proxy.cc
@@ -5,6 +5,7 @@
 #include "base/files/file_proxy.h"
 
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "base/containers/heap_array.h"
@@ -15,7 +16,6 @@
 #include "base/location.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/task/task_runner.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -182,7 +182,7 @@
   ReadHelper& operator=(const ReadHelper&) = delete;
 
   void RunWork(int64_t offset) {
-    absl::optional<size_t> result = file_.Read(offset, buffer_);
+    std::optional<size_t> result = file_.Read(offset, buffer_);
     if (!result.has_value()) {
       bytes_read_ = -1;
       error_ = File::FILE_ERROR_FAILED;
@@ -219,7 +219,7 @@
   WriteHelper& operator=(const WriteHelper&) = delete;
 
   void RunWork(int64_t offset) {
-    absl::optional<size_t> result = file_.Write(offset, buffer_);
+    std::optional<size_t> result = file_.Write(offset, buffer_);
     if (!result.has_value()) {
       bytes_written_ = -1;
       error_ = File::FILE_ERROR_FAILED;
diff --git a/base/files/file_unittest.cc b/base/files/file_unittest.cc
index 6f20e60..98e2fa8 100644
--- a/base/files/file_unittest.cc
+++ b/base/files/file_unittest.cc
@@ -260,7 +260,7 @@
   ASSERT_TRUE(file.IsValid());
 
   // Write 0 bytes to the file.
-  absl::optional<size_t> bytes_written = file.Write(0, base::span<uint8_t>());
+  std::optional<size_t> bytes_written = file.Write(0, base::span<uint8_t>());
   ASSERT_TRUE(bytes_written.has_value());
   EXPECT_EQ(0u, bytes_written.value());
 
@@ -272,7 +272,7 @@
 
   // Read from EOF.
   uint8_t data_read_1[32];
-  absl::optional<size_t> bytes_read =
+  std::optional<size_t> bytes_read =
       file.Read(bytes_written.value(), data_read_1);
   ASSERT_TRUE(bytes_read.has_value());
   EXPECT_EQ(0u, bytes_read.value());
@@ -588,7 +588,7 @@
   EXPECT_TRUE(file.IsValid());
 
   std::string data("test");
-  absl::optional<size_t> result = file.Write(0, base::as_byte_span(data));
+  std::optional<size_t> result = file.Write(0, base::as_byte_span(data));
   ASSERT_TRUE(result.has_value());
   EXPECT_EQ(data.size(), result.value());
 
@@ -645,7 +645,7 @@
 
   std::string data("test");
   size_t first_chunk_size = data.size() / 2;
-  absl::optional<size_t> result =
+  std::optional<size_t> result =
       file.WriteAtCurrentPos(base::as_byte_span(data).first(first_chunk_size));
   ASSERT_TRUE(result.has_value());
   EXPECT_EQ(first_chunk_size, result.value());
diff --git a/base/files/file_util.cc b/base/files/file_util.cc
index c84190d4..dc41bff 100644
--- a/base/files/file_util.cc
+++ b/base/files/file_util.cc
@@ -322,14 +322,14 @@
   return read_successs;
 }
 
-absl::optional<std::vector<uint8_t>> ReadFileToBytes(const FilePath& path) {
+std::optional<std::vector<uint8_t>> ReadFileToBytes(const FilePath& path) {
   if (path.ReferencesParent()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   ScopedFILE file_stream(OpenFile(path, "rb"));
   if (!file_stream) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   std::vector<uint8_t> bytes;
@@ -339,7 +339,7 @@
                                      bytes.resize(size);
                                      return make_span(bytes);
                                    })) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return bytes;
 }
diff --git a/base/files/file_util.h b/base/files/file_util.h
index 19c7c42..4af9031 100644
--- a/base/files/file_util.h
+++ b/base/files/file_util.h
@@ -24,7 +24,6 @@
 #include "base/files/scoped_file.h"
 #include "base/functional/callback.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_WIN)
 #include "base/win/windows_types.h"
@@ -59,9 +58,9 @@
 // This may block if `input` is a relative path, when calling
 // GetCurrentDirectory().
 //
-// This doesn't return absl::nullopt unless (1) `input` is empty, or (2)
+// This doesn't return std::nullopt unless (1) `input` is empty, or (2)
 // `input` is a relative path and GetCurrentDirectory() fails.
-[[nodiscard]] BASE_EXPORT absl::optional<FilePath>
+[[nodiscard]] BASE_EXPORT std::optional<FilePath>
 MakeAbsoluteFilePathNoResolveSymbolicLinks(const FilePath& input);
 #endif
 
@@ -226,7 +225,7 @@
 // Reads the file at |path| and returns a vector of bytes on success, and
 // nullopt on error. For security reasons, a |path| containing path traversal
 // components ('..') is treated as a read error, returning nullopt.
-BASE_EXPORT absl::optional<std::vector<uint8_t>> ReadFileToBytes(
+BASE_EXPORT std::optional<std::vector<uint8_t>> ReadFileToBytes(
     const FilePath& path);
 
 // Reads the file at |path| into |contents| and returns true on success and
@@ -310,7 +309,7 @@
 // Can fail if readlink() fails, or if
 // MakeAbsoluteFilePathNoResolveSymbolicLinks() fails on the resulting absolute
 // path.
-BASE_EXPORT absl::optional<FilePath> ReadSymbolicLinkAbsolute(
+BASE_EXPORT std::optional<FilePath> ReadSymbolicLinkAbsolute(
     const FilePath& symlink);
 
 // Bits and masks of the file permission.
diff --git a/base/files/file_util_posix.cc b/base/files/file_util_posix.cc
index cd75e7d..69064e29 100644
--- a/base/files/file_util_posix.cc
+++ b/base/files/file_util_posix.cc
@@ -343,10 +343,10 @@
   return FilePath(full_path);
 }
 
-absl::optional<FilePath> MakeAbsoluteFilePathNoResolveSymbolicLinks(
+std::optional<FilePath> MakeAbsoluteFilePathNoResolveSymbolicLinks(
     const FilePath& input) {
   if (input.empty()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   FilePath collapsed_path;
@@ -359,7 +359,7 @@
     components_span = components_span.subspan(1);
   } else {
     if (!GetCurrentDirectory(&collapsed_path)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
 
@@ -577,11 +577,10 @@
   return true;
 }
 
-absl::optional<FilePath> ReadSymbolicLinkAbsolute(
-    const FilePath& symlink_path) {
+std::optional<FilePath> ReadSymbolicLinkAbsolute(const FilePath& symlink_path) {
   FilePath target_path;
   if (!ReadSymbolicLink(symlink_path, &target_path)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Relative symbolic links are relative to the symlink's directory.
diff --git a/base/files/file_util_unittest.cc b/base/files/file_util_unittest.cc
index 26e68b50..12e7af6 100644
--- a/base/files/file_util_unittest.cc
+++ b/base/files/file_util_unittest.cc
@@ -401,8 +401,8 @@
 TEST_F(FileUtilTest, MakeAbsoluteFilePathNoResolveSymbolicLinks) {
   FilePath cwd;
   ASSERT_TRUE(GetCurrentDirectory(&cwd));
-  const std::pair<FilePath, absl::optional<FilePath>> kExpectedResults[]{
-      {FilePath(), absl::nullopt},
+  const std::pair<FilePath, std::optional<FilePath>> kExpectedResults[]{
+      {FilePath(), std::nullopt},
       {FilePath("."), cwd},
       {FilePath(".."), cwd.DirName()},
       {FilePath("a/.."), cwd},
@@ -1072,7 +1072,7 @@
   ASSERT_TRUE(ReadSymbolicLink(link_from, &result));
   EXPECT_EQ(filename_link_to.value(), result.value());
 
-  absl::optional<FilePath> absolute_link = ReadSymbolicLinkAbsolute(link_from);
+  std::optional<FilePath> absolute_link = ReadSymbolicLinkAbsolute(link_from);
   ASSERT_TRUE(absolute_link);
   EXPECT_EQ(link_to.value(), absolute_link->value());
 
@@ -3444,7 +3444,7 @@
   // Create test file.
   ASSERT_TRUE(WriteFile(file_path, kTestData));
 
-  absl::optional<std::vector<uint8_t>> bytes = ReadFileToBytes(file_path);
+  std::optional<std::vector<uint8_t>> bytes = ReadFileToBytes(file_path);
   ASSERT_TRUE(bytes.has_value());
   EXPECT_EQ(kTestData, bytes);
 
diff --git a/base/files/important_file_writer.cc b/base/files/important_file_writer.cc
index 81021e5..ba84a7d 100644
--- a/base/files/important_file_writer.cc
+++ b/base/files/important_file_writer.cc
@@ -121,7 +121,7 @@
     OnceCallback<void(bool success)> after_write_callback,
     const std::string& histogram_suffix) {
   // Produce the actual data string on the background sequence.
-  absl::optional<std::string> data =
+  std::optional<std::string> data =
       std::move(data_producer_for_background_sequence).Run();
   if (!data) {
     DLOG(WARNING) << "Failed to serialize data to be saved in " << path.value();
@@ -310,7 +310,7 @@
   }
 
   WriteNowWithBackgroundDataProducer(base::BindOnce(
-      [](std::string data) { return absl::make_optional(std::move(data)); },
+      [](std::string data) { return std::make_optional(std::move(data)); },
       std::move(data)));
 }
 
@@ -373,7 +373,7 @@
   BackgroundDataProducerCallback data_producer_for_background_sequence;
 
   if (absl::holds_alternative<DataSerializer*>(serializer_)) {
-    absl::optional<std::string> data;
+    std::optional<std::string> data;
     data = absl::get<DataSerializer*>(serializer_)->SerializeData();
     if (!data) {
       DLOG(WARNING) << "Failed to serialize data to be saved in "
@@ -384,7 +384,7 @@
 
     previous_data_size_ = data->size();
     data_producer_for_background_sequence = base::BindOnce(
-        [](std::string data) { return absl::make_optional(std::move(data)); },
+        [](std::string data) { return std::make_optional(std::move(data)); },
         std::move(data).value());
   } else {
     data_producer_for_background_sequence =
diff --git a/base/files/important_file_writer.h b/base/files/important_file_writer.h
index 80e432d..1ec3aba 100644
--- a/base/files/important_file_writer.h
+++ b/base/files/important_file_writer.h
@@ -6,6 +6,7 @@
 #define BASE_FILES_IMPORTANT_FILE_WRITER_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "base/base_export.h"
@@ -16,7 +17,6 @@
 #include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
 
 namespace base {
@@ -43,7 +43,7 @@
   // data to be written. This callback is invoked on the sequence where I/O
   // operations are executed. Returning false indicates an error.
   using BackgroundDataProducerCallback =
-      base::OnceCallback<absl::optional<std::string>()>;
+      base::OnceCallback<std::optional<std::string>()>;
 
   // Used by ScheduleSave to lazily provide the data to be saved. Allows us
   // to also batch data serializations.
@@ -52,7 +52,7 @@
     // Returns a string for serialisation when successful, or a nullopt in case
     // it failed to generate the data. Will be called on the same thread on
     // which ImportantFileWriter has been created.
-    virtual absl::optional<std::string> SerializeData() = 0;
+    virtual std::optional<std::string> SerializeData() = 0;
 
    protected:
     virtual ~DataSerializer() = default;
diff --git a/base/files/important_file_writer_cleaner_unittest.cc b/base/files/important_file_writer_cleaner_unittest.cc
index 11c0bfa..46c7d12 100644
--- a/base/files/important_file_writer_cleaner_unittest.cc
+++ b/base/files/important_file_writer_cleaner_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "base/files/important_file_writer_cleaner.h"
 
+#include <optional>
+
 #include "base/check.h"
 #include "base/files/file.h"
 #include "base/files/file_path.h"
@@ -16,7 +18,6 @@
 #include "base/time/time.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using ::testing::ElementsAre;
 
@@ -98,7 +99,7 @@
   FilePath dir_2_file_new_;
   FilePath dir_2_file_old_;
   FilePath dir_2_file_other_;
-  absl::optional<ScopedCleanerLifetime> cleaner_lifetime_;
+  std::optional<ScopedCleanerLifetime> cleaner_lifetime_;
 };
 
 void ImportantFileWriterCleanerTest::SetUp() {
diff --git a/base/files/important_file_writer_unittest.cc b/base/files/important_file_writer_unittest.cc
index 36cb21f..7fe49d9e 100644
--- a/base/files/important_file_writer_unittest.cc
+++ b/base/files/important_file_writer_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "base/files/important_file_writer.h"
 
+#include <optional>
+
 #include "base/compiler_specific.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -22,7 +24,6 @@
 #include "base/time/time.h"
 #include "base/timer/mock_timer.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -41,7 +42,7 @@
   explicit DataSerializer(const std::string& data) : data_(data) {
   }
 
-  absl::optional<std::string> SerializeData() override {
+  std::optional<std::string> SerializeData() override {
     EXPECT_TRUE(sequence_checker_.CalledOnValidSequence());
     return data_;
   }
@@ -53,7 +54,7 @@
 
 class FailingDataSerializer : public ImportantFileWriter::DataSerializer {
  public:
-  absl::optional<std::string> SerializeData() override { return absl::nullopt; }
+  std::optional<std::string> SerializeData() override { return std::nullopt; }
 };
 
 class BackgroundDataSerializer
@@ -380,7 +381,7 @@
   EXPECT_FALSE(writer.HasPendingWrite());
   ASSERT_FALSE(file_writer_thread.task_runner()->RunsTasksInCurrentSequence());
   BackgroundDataSerializer serializer(
-      base::BindLambdaForTesting([&]() -> absl::optional<std::string> {
+      base::BindLambdaForTesting([&]() -> std::optional<std::string> {
         EXPECT_TRUE(
             file_writer_thread.task_runner()->RunsTasksInCurrentSequence());
         return "foo";
@@ -416,10 +417,10 @@
   EXPECT_FALSE(writer.HasPendingWrite());
   ASSERT_FALSE(file_writer_thread.task_runner()->RunsTasksInCurrentSequence());
   BackgroundDataSerializer serializer(
-      base::BindLambdaForTesting([&]() -> absl::optional<std::string> {
+      base::BindLambdaForTesting([&]() -> std::optional<std::string> {
         EXPECT_TRUE(
             file_writer_thread.task_runner()->RunsTasksInCurrentSequence());
-        return absl::nullopt;
+        return std::nullopt;
       }));
   writer.ScheduleWriteWithBackgroundDataSerializer(&serializer);
   EXPECT_TRUE(writer.HasPendingWrite());
diff --git a/base/files/safe_base_name.cc b/base/files/safe_base_name.cc
index cc0cc8d..0b17f31 100644
--- a/base/files/safe_base_name.cc
+++ b/base/files/safe_base_name.cc
@@ -7,19 +7,19 @@
 namespace base {
 
 // static
-absl::optional<SafeBaseName> SafeBaseName::Create(const FilePath& path) {
+std::optional<SafeBaseName> SafeBaseName::Create(const FilePath& path) {
   auto basename = path.BaseName();
 
   if (!basename.IsAbsolute() && !basename.ReferencesParent() &&
       !basename.EndsWithSeparator()) {
-    return absl::make_optional(SafeBaseName(basename));
+    return std::make_optional(SafeBaseName(basename));
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 // static
-absl::optional<SafeBaseName> SafeBaseName::Create(
+std::optional<SafeBaseName> SafeBaseName::Create(
     FilePath::StringPieceType path) {
   return Create(FilePath(path));
 }
diff --git a/base/files/safe_base_name.h b/base/files/safe_base_name.h
index 13faaeb..188ae43 100644
--- a/base/files/safe_base_name.h
+++ b/base/files/safe_base_name.h
@@ -5,9 +5,10 @@
 #ifndef BASE_FILES_SAFE_BASE_NAME_H_
 #define BASE_FILES_SAFE_BASE_NAME_H_
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/files/file_path.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -16,7 +17,7 @@
 // directories and is considered safe to be passed over IPC. See
 // FilePath::BaseName().
 // Usage examples:
-// absl::optional<SafeBaseName> a
+// std::optional<SafeBaseName> a
 //     (SafeBaseName::Create(FILE_PATH_LITERAL("file.txt")));
 // FilePath dir(FILE_PATH_LITERAL("foo")); dir.Append(*a);
 class BASE_EXPORT SafeBaseName {
@@ -24,11 +25,11 @@
   // TODO(crbug.com/1269986): Change to only be exposed to Mojo.
   SafeBaseName() = default;
 
-  // Factory method that returns a valid SafeBaseName or absl::nullopt.
-  static absl::optional<SafeBaseName> Create(const FilePath&);
+  // Factory method that returns a valid SafeBaseName or std::nullopt.
+  static std::optional<SafeBaseName> Create(const FilePath&);
 
   // Same as above, but takes a StringPieceType for convenience.
-  static absl::optional<SafeBaseName> Create(FilePath::StringPieceType);
+  static std::optional<SafeBaseName> Create(FilePath::StringPieceType);
   const FilePath& path() const { return path_; }
 
   bool operator==(const SafeBaseName& that) const;
diff --git a/base/files/safe_base_name_unittest.cc b/base/files/safe_base_name_unittest.cc
index 0023a2a..6443fbd 100644
--- a/base/files/safe_base_name_unittest.cc
+++ b/base/files/safe_base_name_unittest.cc
@@ -9,11 +9,11 @@
 namespace base {
 
 TEST(SafeBaseNameTest, Basic) {
-  absl::optional<SafeBaseName> basename(SafeBaseName::Create(FilePath()));
+  std::optional<SafeBaseName> basename(SafeBaseName::Create(FilePath()));
   EXPECT_TRUE(basename.has_value());
   EXPECT_TRUE(basename->path().empty());
 
-  absl::optional<SafeBaseName> basename2(
+  std::optional<SafeBaseName> basename2(
       SafeBaseName::Create(FILE_PATH_LITERAL("bar")));
   EXPECT_TRUE(basename2);
   EXPECT_EQ(basename2->path(), FilePath(FILE_PATH_LITERAL("bar")));
@@ -21,7 +21,7 @@
 
 #if defined(FILE_PATH_USES_WIN_SEPARATORS)
 TEST(SafeBaseNameTest, WinRoot) {
-  absl::optional<SafeBaseName> basename(
+  std::optional<SafeBaseName> basename(
       SafeBaseName::Create(FILE_PATH_LITERAL("C:\\foo\\bar")));
   EXPECT_TRUE(basename.has_value());
   EXPECT_EQ(basename->path(), FilePath(FILE_PATH_LITERAL("bar")));
@@ -31,14 +31,14 @@
 }
 #else
 TEST(SafeBaseNameTest, Root) {
-  absl::optional<SafeBaseName> basename(
+  std::optional<SafeBaseName> basename(
       SafeBaseName::Create(FilePath(FILE_PATH_LITERAL("/"))));
   EXPECT_FALSE(basename.has_value());
 }
 #endif  // FILE_PATH_USES_WIN_SEPARATORS
 
 TEST(SafeBaseNameTest, Separators) {
-  absl::optional<SafeBaseName> basename(
+  std::optional<SafeBaseName> basename(
       SafeBaseName::Create(FILE_PATH_LITERAL("/foo/bar")));
   EXPECT_TRUE(basename.has_value());
   EXPECT_EQ(basename->path(), FilePath(FILE_PATH_LITERAL("bar")));
diff --git a/base/fuchsia/fidl_event_handler.h b/base/fuchsia/fidl_event_handler.h
index 01cdefdf..b069c07 100644
--- a/base/fuchsia/fidl_event_handler.h
+++ b/base/fuchsia/fidl_event_handler.h
@@ -8,13 +8,13 @@
 #include <lib/fidl/cpp/wire/client_base.h>
 #include <lib/fidl/cpp/wire/status.h>
 
+#include <optional>
 #include <string>
 
 #include "base/fuchsia/fuchsia_logging.h"
 #include "base/functional/callback.h"
 #include "base/location.h"
 #include "base/strings/string_piece.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace fidl {
 template <typename Protocol>
diff --git a/base/fuchsia/fidl_event_handler_unittest.cc b/base/fuchsia/fidl_event_handler_unittest.cc
index 3283c981..b3640fc 100644
--- a/base/fuchsia/fidl_event_handler_unittest.cc
+++ b/base/fuchsia/fidl_event_handler_unittest.cc
@@ -60,7 +60,7 @@
 
   constexpr char kLogMessage[] =
       "base.testfidl.TestInterface was disconnected with ZX_ERR_PEER_CLOSED";
-  absl::optional<fuchsia_logger::LogMessage> logged_message =
+  std::optional<fuchsia_logger::LogMessage> logged_message =
       listener_.RunUntilMessageReceived(kLogMessage);
 
   ASSERT_TRUE(logged_message.has_value());
@@ -78,7 +78,7 @@
 
   constexpr char kLogMessage[] =
       "test_protocol_name was disconnected with ZX_ERR_PEER_CLOSED";
-  absl::optional<fuchsia_logger::LogMessage> logged_message =
+  std::optional<fuchsia_logger::LogMessage> logged_message =
       listener_.RunUntilMessageReceived(kLogMessage);
 
   ASSERT_TRUE(logged_message.has_value());
@@ -105,7 +105,7 @@
 
   constexpr char kLogMessage[] =
       "base.testfidl.TestInterface was disconnected with ZX_ERR_PEER_CLOSED";
-  absl::optional<fuchsia_logger::LogMessage> logged_message =
+  std::optional<fuchsia_logger::LogMessage> logged_message =
       listener_.RunUntilMessageReceived(kLogMessage);
 
   ASSERT_TRUE(logged_message.has_value());
diff --git a/base/fuchsia/fuchsia_logging_unittest.cc b/base/fuchsia/fuchsia_logging_unittest.cc
index 93ca473..c366df7c 100644
--- a/base/fuchsia/fuchsia_logging_unittest.cc
+++ b/base/fuchsia/fuchsia_logging_unittest.cc
@@ -49,7 +49,7 @@
   // test listener.
   LOG(ERROR) << kLogMessage;
 
-  absl::optional<fuchsia_logger::LogMessage> logged_message =
+  std::optional<fuchsia_logger::LogMessage> logged_message =
       listener.RunUntilMessageReceived(kLogMessage);
 
   ASSERT_TRUE(logged_message.has_value());
@@ -82,7 +82,7 @@
       std::move(log_sink_client_end.value()), kTags);
   logger.LogMessage("", 0, kLogMessage, FUCHSIA_LOG_ERROR);
 
-  absl::optional<fuchsia_logger::LogMessage> logged_message =
+  std::optional<fuchsia_logger::LogMessage> logged_message =
       listener.RunUntilMessageReceived(kLogMessage);
 
   ASSERT_TRUE(logged_message.has_value());
@@ -157,7 +157,7 @@
   base::FidlBindingClosureWarningLogger<base_testfidl::TestInterface>()(
       fidl::UnbindInfo::PeerClosed(ZX_ERR_PEER_CLOSED));
 
-  absl::optional<fuchsia_logger::LogMessage> logged_message =
+  std::optional<fuchsia_logger::LogMessage> logged_message =
       listener.RunUntilMessageReceived(
           "base.testfidl.TestInterface unbound: ZX_ERR_PEER_CLOSED (-24)");
 
diff --git a/base/fuchsia/koid.cc b/base/fuchsia/koid.cc
index bf26dae9e..63f90c3 100644
--- a/base/fuchsia/koid.cc
+++ b/base/fuchsia/koid.cc
@@ -10,7 +10,7 @@
 
 namespace {
 
-absl::optional<zx_info_handle_basic_t> GetBasicInfo(
+std::optional<zx_info_handle_basic_t> GetBasicInfo(
     const zx::object_base& handle) {
   zx_info_handle_basic_t basic;
   zx_status_t status = handle.get_info(ZX_INFO_HANDLE_BASIC, &basic,
@@ -25,14 +25,14 @@
 
 }  // namespace
 
-absl::optional<zx_koid_t> GetKoid(const zx::object_base& handle) {
+std::optional<zx_koid_t> GetKoid(const zx::object_base& handle) {
   auto basic_info = GetBasicInfo(handle);
   if (!basic_info)
     return {};
   return basic_info->koid;
 }
 
-absl::optional<zx_koid_t> GetRelatedKoid(const zx::object_base& handle) {
+std::optional<zx_koid_t> GetRelatedKoid(const zx::object_base& handle) {
   auto basic_info = GetBasicInfo(handle);
   if (!basic_info)
     return {};
diff --git a/base/fuchsia/koid.h b/base/fuchsia/koid.h
index be9c17457..7525908 100644
--- a/base/fuchsia/koid.h
+++ b/base/fuchsia/koid.h
@@ -8,18 +8,19 @@
 #include <lib/zx/object.h>
 #include <zircon/types.h>
 
+#include <optional>
+
 #include "base/base_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
 // Returns the Kernel Object IDentifier for the object referred to by |handle|,
 // if it is valid.
-BASE_EXPORT absl::optional<zx_koid_t> GetKoid(const zx::object_base& handle);
+BASE_EXPORT std::optional<zx_koid_t> GetKoid(const zx::object_base& handle);
 
 // Returns the Kernel Object IDentifier for the peer of the paired object (i.e.
 // a channel, socket, eventpair, etc) referred to by |handle|.
-BASE_EXPORT absl::optional<zx_koid_t> GetRelatedKoid(
+BASE_EXPORT std::optional<zx_koid_t> GetRelatedKoid(
     const zx::object_base& handle);
 
 }  // namespace base
diff --git a/base/fuchsia/mem_buffer_util.cc b/base/fuchsia/mem_buffer_util.cc
index 5495be1..9afc697 100644
--- a/base/fuchsia/mem_buffer_util.cc
+++ b/base/fuchsia/mem_buffer_util.cc
@@ -18,15 +18,15 @@
 
 namespace base {
 
-absl::optional<std::u16string> ReadUTF8FromVMOAsUTF16(
+std::optional<std::u16string> ReadUTF8FromVMOAsUTF16(
     const fuchsia::mem::Buffer& buffer) {
-  absl::optional<std::string> output_utf8 = StringFromMemBuffer(buffer);
+  std::optional<std::string> output_utf8 = StringFromMemBuffer(buffer);
   if (!output_utf8)
-    return absl::nullopt;
+    return std::nullopt;
   std::u16string output;
   return UTF8ToUTF16(&output_utf8->front(), output_utf8->size(), &output)
-             ? absl::optional<std::u16string>(std::move(output))
-             : absl::nullopt;
+             ? std::optional<std::u16string>(std::move(output))
+             : std::nullopt;
 }
 
 zx::vmo VmoFromString(StringPiece data, StringPiece name) {
@@ -60,14 +60,14 @@
       name);
 }
 
-absl::optional<std::string> StringFromVmo(const zx::vmo& vmo) {
+std::optional<std::string> StringFromVmo(const zx::vmo& vmo) {
   std::string result;
 
   size_t size;
   zx_status_t status = vmo.get_prop_content_size(&size);
   if (status != ZX_OK) {
     ZX_LOG(ERROR, status) << "zx::vmo::get_prop_content_size";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (size == 0)
@@ -79,10 +79,10 @@
     return result;
 
   ZX_LOG(ERROR, status) << "zx_vmo_read";
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<std::string> StringFromMemBuffer(
+std::optional<std::string> StringFromMemBuffer(
     const fuchsia::mem::Buffer& buffer) {
   std::string result;
 
@@ -95,10 +95,10 @@
     return result;
 
   ZX_LOG(ERROR, status) << "zx_vmo_read";
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<std::string> StringFromMemData(const fuchsia::mem::Data& data) {
+std::optional<std::string> StringFromMemData(const fuchsia::mem::Data& data) {
   switch (data.Which()) {
     case fuchsia::mem::Data::kBytes: {
       const std::vector<uint8_t>& bytes = data.bytes();
@@ -112,7 +112,7 @@
       break;
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 fuchsia::mem::Buffer MemBufferFromFile(File file) {
diff --git a/base/fuchsia/mem_buffer_util.h b/base/fuchsia/mem_buffer_util.h
index 0c17515..30bc3a61 100644
--- a/base/fuchsia/mem_buffer_util.h
+++ b/base/fuchsia/mem_buffer_util.h
@@ -6,18 +6,19 @@
 #define BASE_FUCHSIA_MEM_BUFFER_UTIL_H_
 
 #include <fuchsia/mem/cpp/fidl.h>
+
+#include <optional>
 #include <string>
 
 #include "base/base_export.h"
 #include "base/files/file.h"
 #include "base/strings/string_piece.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
 // Returns the contents of `buffer` (which must be a valid UTF-8 string), or
 // null in case of a conversion error.
-BASE_EXPORT absl::optional<std::u16string> ReadUTF8FromVMOAsUTF16(
+BASE_EXPORT std::optional<std::u16string> ReadUTF8FromVMOAsUTF16(
     const fuchsia::mem::Buffer& buffer);
 
 // Creates a Fuchsia VMO from `data`. The size of the resulting virtual memory
@@ -38,16 +39,16 @@
                                                        StringPiece name);
 
 // Returns the contents of `data`, or null if the read operation fails.
-BASE_EXPORT absl::optional<std::string> StringFromVmo(const zx::vmo& vmo);
+BASE_EXPORT std::optional<std::string> StringFromVmo(const zx::vmo& vmo);
 
 // Returns the contents of `buffer`, or null if the read operation fails.
 // `fuchsia::mem::Buffer` is deprecated: for new interfaces, prefer using
 // a VMO object directly (see `StringFromVmo`).
-BASE_EXPORT absl::optional<std::string> StringFromMemBuffer(
+BASE_EXPORT std::optional<std::string> StringFromMemBuffer(
     const fuchsia::mem::Buffer& buffer);
 
 // Returns the contents of `data`, or null if the read operation fails.
-BASE_EXPORT absl::optional<std::string> StringFromMemData(
+BASE_EXPORT std::optional<std::string> StringFromMemData(
     const fuchsia::mem::Data& data);
 
 // Creates a memory-mapped, read-only Buffer with the contents of `file`. Will
diff --git a/base/fuchsia/process_lifecycle.h b/base/fuchsia/process_lifecycle.h
index 9bcdd83..06ea93a8 100644
--- a/base/fuchsia/process_lifecycle.h
+++ b/base/fuchsia/process_lifecycle.h
@@ -9,9 +9,10 @@
 #include <lib/fidl/cpp/binding.h>
 #include <lib/fidl/cpp/wire/channel.h>
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/functional/callback.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -37,7 +38,7 @@
  private:
   base::OnceClosure on_stop_;
 
-  absl::optional<fidl::ServerBinding<fuchsia_process_lifecycle::Lifecycle>>
+  std::optional<fidl::ServerBinding<fuchsia_process_lifecycle::Lifecycle>>
       binding_;
 };
 
diff --git a/base/fuchsia/scoped_service_binding.h b/base/fuchsia/scoped_service_binding.h
index 79574240..b88b33f 100644
--- a/base/fuchsia/scoped_service_binding.h
+++ b/base/fuchsia/scoped_service_binding.h
@@ -16,11 +16,12 @@
 #include <lib/fidl/cpp/wire/connect_service.h>
 #include <lib/zx/channel.h>
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/fuchsia/scoped_service_publisher.h"
 #include "base/functional/callback.h"
 #include "base/strings/string_piece.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sys {
 class OutgoingDirectory;
@@ -199,7 +200,7 @@
   }
 
   fidl::Binding<Interface> binding_;
-  absl::optional<ScopedServicePublisher<Interface>> publisher_;
+  std::optional<ScopedServicePublisher<Interface>> publisher_;
   base::OnceClosure on_last_client_callback_;
 };
 
diff --git a/base/fuchsia/test_log_listener_safe.cc b/base/fuchsia/test_log_listener_safe.cc
index b51bcea..cee316e 100644
--- a/base/fuchsia/test_log_listener_safe.cc
+++ b/base/fuchsia/test_log_listener_safe.cc
@@ -8,6 +8,8 @@
 #include <lib/fidl/cpp/box.h>
 #include <lib/zx/clock.h>
 
+#include <optional>
+
 #include "base/fuchsia/fuchsia_component_connect.h"
 #include "base/fuchsia/fuchsia_logging.h"
 #include "base/functional/callback_helpers.h"
@@ -16,7 +18,6 @@
 #include "base/strings/string_piece.h"
 #include "base/test/bind.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -77,7 +78,7 @@
   }
 }
 
-absl::optional<fuchsia_logger::LogMessage>
+std::optional<fuchsia_logger::LogMessage>
 SimpleTestLogListener::RunUntilMessageReceived(
     base::StringPiece expected_string) {
   while (!logged_messages_.empty()) {
@@ -89,7 +90,7 @@
     }
   }
 
-  absl::optional<fuchsia_logger::LogMessage> logged_message;
+  std::optional<fuchsia_logger::LogMessage> logged_message;
   base::RunLoop loop;
   on_log_message_ = base::BindLambdaForTesting(
       [ignore_before = ignore_before_, &logged_message,
diff --git a/base/fuchsia/test_log_listener_safe.h b/base/fuchsia/test_log_listener_safe.h
index 8364dd7..57f39ca4 100644
--- a/base/fuchsia/test_log_listener_safe.h
+++ b/base/fuchsia/test_log_listener_safe.h
@@ -6,19 +6,18 @@
 #define BASE_FUCHSIA_TEST_LOG_LISTENER_SAFE_H_
 
 #include <fidl/fuchsia.logger/cpp/fidl.h>
-
 #include <lib/async/default.h>
 #include <lib/fidl/cpp/binding.h>
 #include <lib/zx/time.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "base/containers/circular_deque.h"
 #include "base/functional/callback.h"
 #include "base/strings/string_piece.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -70,9 +69,9 @@
                    std::unique_ptr<fuchsia_logger::LogFilterOptions> options);
 
   // Runs the message loop until a log message containing `expected_string` is
-  // received, and returns it. Returns `absl::nullopt` if `binding_` disconnects
+  // received, and returns it. Returns `std::nullopt` if `binding_` disconnects
   // without the `expected_string` having been logged.
-  absl::optional<fuchsia_logger::LogMessage> RunUntilMessageReceived(
+  std::optional<fuchsia_logger::LogMessage> RunUntilMessageReceived(
       base::StringPiece expected_string);
 
  private:
@@ -83,7 +82,7 @@
   zx::time ignore_before_;
 
   TestLogListenerSafe listener_;
-  absl::optional<fidl::ServerBinding<fuchsia_logger::LogListenerSafe>> binding_;
+  std::optional<fidl::ServerBinding<fuchsia_logger::LogListenerSafe>> binding_;
 
   base::circular_deque<fuchsia_logger::LogMessage> logged_messages_;
   TestLogListenerSafe::OnLogMessageCallback on_log_message_;
diff --git a/base/functional/callback_helpers.h b/base/functional/callback_helpers.h
index f7af4f8..d7444427 100644
--- a/base/functional/callback_helpers.h
+++ b/base/functional/callback_helpers.h
@@ -191,15 +191,15 @@
 };
 
 // Returns a placeholder type that will implicitly convert into a null callback,
-// similar to how absl::nullopt / std::nullptr work in conjunction with
-// absl::optional and various smart pointer types.
+// similar to how std::nullopt / std::nullptr work in conjunction with
+// std::optional and various smart pointer types.
 constexpr auto NullCallback() {
   return internal::NullCallbackTag();
 }
 
 // Returns a placeholder type that will implicitly convert into a callback that
-// does nothing, similar to how absl::nullopt / std::nullptr work in conjunction
-// with absl::optional and various smart pointer types.
+// does nothing, similar to how std::nullopt / std::nullptr work in conjunction
+// with std::optional and various smart pointer types.
 constexpr auto DoNothing() {
   return internal::DoNothingCallbackTag();
 }
diff --git a/base/immediate_crash_unittest.cc b/base/immediate_crash_unittest.cc
index 59cf8041..7ba79004 100644
--- a/base/immediate_crash_unittest.cc
+++ b/base/immediate_crash_unittest.cc
@@ -6,6 +6,8 @@
 
 #include <stdint.h>
 
+#include <optional>
+
 #include "base/base_paths.h"
 #include "base/clang_profiling_buildflags.h"
 #include "base/containers/span.h"
@@ -17,7 +19,6 @@
 #include "build/build_config.h"
 #include "build/buildflag.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -139,17 +140,16 @@
     body->push_back(instruction);
 }
 
-absl::optional<std::vector<Instruction>> ExpectImmediateCrashInvocation(
+std::optional<std::vector<Instruction>> ExpectImmediateCrashInvocation(
     std::vector<Instruction> instructions) {
   auto iter = instructions.begin();
   for (const auto inst : kRequiredBody) {
     if (iter == instructions.end())
-      return absl::nullopt;
+      return std::nullopt;
     EXPECT_EQ(inst, *iter);
     iter++;
   }
-  return absl::make_optional(
-      std::vector<Instruction>(iter, instructions.end()));
+  return std::make_optional(std::vector<Instruction>(iter, instructions.end()));
 }
 
 std::vector<Instruction> MaybeSkipOptionalFooter(
@@ -222,7 +222,7 @@
   it++;
 
   body = std::vector<Instruction>(it, body.end());
-  absl::optional<std::vector<Instruction>> result = MaybeSkipCoverageHook(body);
+  std::optional<std::vector<Instruction>> result = MaybeSkipCoverageHook(body);
   result = ExpectImmediateCrashInvocation(result.value());
   result = MaybeSkipOptionalFooter(result.value());
   result = MaybeSkipCoverageHook(result.value());
diff --git a/base/json/json_parser.cc b/base/json/json_parser.cc
index 71381a4..db7c85a 100644
--- a/base/json/json_parser.cc
+++ b/base/json/json_parser.cc
@@ -6,6 +6,7 @@
 
 #include <cmath>
 #include <iterator>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -24,7 +25,6 @@
 #include "base/strings/utf_string_conversion_utils.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/third_party/icu/icu_utf.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace internal {
@@ -127,7 +127,7 @@
 
 JSONParser::~JSONParser() = default;
 
-absl::optional<Value> JSONParser::Parse(StringPiece input) {
+std::optional<Value> JSONParser::Parse(StringPiece input) {
   input_ = input;
   index_ = 0;
   // Line and column counting is 1-based, but |index_| is 0-based. For example,
@@ -154,14 +154,14 @@
   ConsumeIfMatch("\xEF\xBB\xBF");
 
   // Parse the first and any nested tokens.
-  absl::optional<Value> root(ParseNextToken());
+  std::optional<Value> root(ParseNextToken());
   if (!root)
-    return absl::nullopt;
+    return std::nullopt;
 
   // Make sure the input stream is at an end.
   if (GetNextToken() != T_END_OF_INPUT) {
     ReportError(JSON_UNEXPECTED_DATA_AFTER_ROOT, 0);
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return root;
@@ -230,33 +230,33 @@
 
 // JSONParser private //////////////////////////////////////////////////////////
 
-absl::optional<StringPiece> JSONParser::PeekChars(size_t count) {
+std::optional<StringPiece> JSONParser::PeekChars(size_t count) {
   if (index_ + count > input_.length())
-    return absl::nullopt;
+    return std::nullopt;
   // Using StringPiece::substr() is significantly slower (according to
   // base_perftests) than constructing a substring manually.
   return StringPiece(input_.data() + index_, count);
 }
 
-absl::optional<char> JSONParser::PeekChar() {
-  absl::optional<StringPiece> chars = PeekChars(1);
+std::optional<char> JSONParser::PeekChar() {
+  std::optional<StringPiece> chars = PeekChars(1);
   if (chars)
     return (*chars)[0];
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<StringPiece> JSONParser::ConsumeChars(size_t count) {
-  absl::optional<StringPiece> chars = PeekChars(count);
+std::optional<StringPiece> JSONParser::ConsumeChars(size_t count) {
+  std::optional<StringPiece> chars = PeekChars(count);
   if (chars)
     index_ += count;
   return chars;
 }
 
-absl::optional<char> JSONParser::ConsumeChar() {
-  absl::optional<StringPiece> chars = ConsumeChars(1);
+std::optional<char> JSONParser::ConsumeChar() {
+  std::optional<StringPiece> chars = ConsumeChars(1);
   if (chars)
     return (*chars)[0];
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 const char* JSONParser::pos() {
@@ -267,7 +267,7 @@
 JSONParser::Token JSONParser::GetNextToken() {
   EatWhitespaceAndComments();
 
-  absl::optional<char> c = PeekChar();
+  std::optional<char> c = PeekChar();
   if (!c)
     return T_END_OF_INPUT;
 
@@ -310,7 +310,7 @@
 }
 
 void JSONParser::EatWhitespaceAndComments() {
-  while (absl::optional<char> c = PeekChar()) {
+  while (std::optional<char> c = PeekChar()) {
     switch (*c) {
       case '\r':
       case '\n':
@@ -335,7 +335,7 @@
 }
 
 bool JSONParser::EatComment() {
-  absl::optional<StringPiece> comment_start = PeekChars(2);
+  std::optional<StringPiece> comment_start = PeekChars(2);
   if (!comment_start)
     return false;
 
@@ -351,7 +351,7 @@
 
     ConsumeChars(2);
     // Single line comment, read to newline.
-    while (absl::optional<char> c = PeekChar()) {
+    while (std::optional<char> c = PeekChar()) {
       if (c == '\n' || c == '\r')
         return true;
       ConsumeChar();
@@ -367,7 +367,7 @@
     ConsumeChars(2);
     char previous_char = '\0';
     // Block comment, read until end marker.
-    while (absl::optional<char> c = PeekChar()) {
+    while (std::optional<char> c = PeekChar()) {
       if (previous_char == '*' && c == '/') {
         // EatWhitespaceAndComments will inspect pos(), which will still be on
         // the last / of the comment, so advance once more (which may also be
@@ -384,11 +384,11 @@
   return false;
 }
 
-absl::optional<Value> JSONParser::ParseNextToken() {
+std::optional<Value> JSONParser::ParseNextToken() {
   return ParseToken(GetNextToken());
 }
 
-absl::optional<Value> JSONParser::ParseToken(Token token) {
+std::optional<Value> JSONParser::ParseToken(Token token) {
   switch (token) {
     case T_OBJECT_BEGIN:
       return ConsumeDictionary();
@@ -404,20 +404,20 @@
       return ConsumeLiteral();
     default:
       ReportError(JSON_UNEXPECTED_TOKEN, 0);
-      return absl::nullopt;
+      return std::nullopt;
   }
 }
 
-absl::optional<Value> JSONParser::ConsumeDictionary() {
+std::optional<Value> JSONParser::ConsumeDictionary() {
   if (ConsumeChar() != '{') {
     ReportError(JSON_UNEXPECTED_TOKEN, 0);
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   StackMarker depth_check(max_depth_, &stack_depth_);
   if (depth_check.IsTooDeep()) {
     ReportError(JSON_TOO_MUCH_NESTING, -1);
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   std::vector<std::pair<std::string, Value>> values;
@@ -426,28 +426,28 @@
   while (token != T_OBJECT_END) {
     if (token != T_STRING) {
       ReportError(JSON_UNQUOTED_DICTIONARY_KEY, 0);
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     // First consume the key.
     StringBuilder key;
     if (!ConsumeStringRaw(&key)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     // Read the separator.
     token = GetNextToken();
     if (token != T_OBJECT_PAIR_SEPARATOR) {
       ReportError(JSON_SYNTAX_ERROR, 0);
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     // The next token is the value. Ownership transfers to |dict|.
     ConsumeChar();
-    absl::optional<Value> value = ParseNextToken();
+    std::optional<Value> value = ParseNextToken();
     if (!value) {
       // ReportError from deeper level.
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     values.emplace_back(key.DestructiveAsString(), std::move(*value));
@@ -458,11 +458,11 @@
       token = GetNextToken();
       if (token == T_OBJECT_END && !(options_ & JSON_ALLOW_TRAILING_COMMAS)) {
         ReportError(JSON_TRAILING_COMMA, 0);
-        return absl::nullopt;
+        return std::nullopt;
       }
     } else if (token != T_OBJECT_END) {
       ReportError(JSON_SYNTAX_ERROR, 0);
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
 
@@ -474,26 +474,26 @@
                            std::make_move_iterator(values.end())));
 }
 
-absl::optional<Value> JSONParser::ConsumeList() {
+std::optional<Value> JSONParser::ConsumeList() {
   if (ConsumeChar() != '[') {
     ReportError(JSON_UNEXPECTED_TOKEN, 0);
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   StackMarker depth_check(max_depth_, &stack_depth_);
   if (depth_check.IsTooDeep()) {
     ReportError(JSON_TOO_MUCH_NESTING, -1);
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   Value::List list;
 
   Token token = GetNextToken();
   while (token != T_ARRAY_END) {
-    absl::optional<Value> item = ParseToken(token);
+    std::optional<Value> item = ParseToken(token);
     if (!item) {
       // ReportError from deeper level.
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     list.Append(std::move(*item));
@@ -504,11 +504,11 @@
       token = GetNextToken();
       if (token == T_ARRAY_END && !(options_ & JSON_ALLOW_TRAILING_COMMAS)) {
         ReportError(JSON_TRAILING_COMMA, 0);
-        return absl::nullopt;
+        return std::nullopt;
       }
     } else if (token != T_ARRAY_END) {
       ReportError(JSON_SYNTAX_ERROR, 0);
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
 
@@ -517,10 +517,10 @@
   return Value(std::move(list));
 }
 
-absl::optional<Value> JSONParser::ConsumeString() {
+std::optional<Value> JSONParser::ConsumeString() {
   StringBuilder string;
   if (!ConsumeStringRaw(&string))
-    return absl::nullopt;
+    return std::nullopt;
   return Value(string.DestructiveAsString());
 }
 
@@ -535,7 +535,7 @@
   // std::string.
   StringBuilder string(pos());
 
-  while (absl::optional<char> c = PeekChar()) {
+  while (std::optional<char> c = PeekChar()) {
     base_icu::UChar32 next_char = 0;
     if (static_cast<unsigned char>(*c) < kExtendedASCIIStart) {
       // Fast path for ASCII.
@@ -594,7 +594,7 @@
       string.Convert();
 
       // Read past the escape '\' and ensure there's a character following.
-      absl::optional<StringPiece> escape_sequence = ConsumeChars(2);
+      std::optional<StringPiece> escape_sequence = ConsumeChars(2);
       if (!escape_sequence) {
         ReportError(JSON_INVALID_ESCAPE, -1);
         return false;
@@ -685,7 +685,7 @@
 
 // Entry is at the first X in \uXXXX.
 bool JSONParser::DecodeUTF16(base_icu::UChar32* out_code_point) {
-  absl::optional<StringPiece> escape_sequence = ConsumeChars(4);
+  std::optional<StringPiece> escape_sequence = ConsumeChars(4);
   if (!escape_sequence)
     return false;
 
@@ -743,7 +743,7 @@
   return true;
 }
 
-absl::optional<Value> JSONParser::ConsumeNumber() {
+std::optional<Value> JSONParser::ConsumeNumber() {
   const char* num_start = pos();
   const size_t start_index = index_;
   size_t end_index = start_index;
@@ -753,7 +753,7 @@
 
   if (!ReadInt(false)) {
     ReportError(JSON_SYNTAX_ERROR, 0);
-    return absl::nullopt;
+    return std::nullopt;
   }
   end_index = index_;
 
@@ -762,13 +762,13 @@
     ConsumeChar();
     if (!ReadInt(true)) {
       ReportError(JSON_SYNTAX_ERROR, 0);
-      return absl::nullopt;
+      return std::nullopt;
     }
     end_index = index_;
   }
 
   // Optional exponent part.
-  absl::optional<char> c = PeekChar();
+  std::optional<char> c = PeekChar();
   if (c == 'e' || c == 'E') {
     ConsumeChar();
     if (PeekChar() == '-' || PeekChar() == '+') {
@@ -776,7 +776,7 @@
     }
     if (!ReadInt(true)) {
       ReportError(JSON_SYNTAX_ERROR, 0);
-      return absl::nullopt;
+      return std::nullopt;
     }
     end_index = index_;
   }
@@ -795,7 +795,7 @@
       break;
     default:
       ReportError(JSON_SYNTAX_ERROR, 0);
-      return absl::nullopt;
+      return std::nullopt;
   }
 
   index_ = exit_index;
@@ -820,14 +820,14 @@
   }
 
   ReportError(JSON_UNREPRESENTABLE_NUMBER, 0);
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool JSONParser::ReadInt(bool allow_leading_zeros) {
   size_t len = 0;
   char first = 0;
 
-  while (absl::optional<char> c = PeekChar()) {
+  while (std::optional<char> c = PeekChar()) {
     if (!IsAsciiDigit(c))
       break;
 
@@ -847,7 +847,7 @@
   return true;
 }
 
-absl::optional<Value> JSONParser::ConsumeLiteral() {
+std::optional<Value> JSONParser::ConsumeLiteral() {
   if (ConsumeIfMatch("true"))
     return Value(true);
   if (ConsumeIfMatch("false"))
@@ -855,7 +855,7 @@
   if (ConsumeIfMatch("null"))
     return Value(Value::Type::NONE);
   ReportError(JSON_SYNTAX_ERROR, 0);
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool JSONParser::ConsumeIfMatch(StringPiece match) {
diff --git a/base/json/json_parser.h b/base/json/json_parser.h
index 0eb4fac..7a9cc688 100644
--- a/base/json/json_parser.h
+++ b/base/json/json_parser.h
@@ -9,6 +9,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "base/base_export.h"
@@ -18,7 +19,6 @@
 #include "base/strings/string_piece.h"
 #include "base/third_party/icu/icu_utf.h"
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -81,7 +81,7 @@
   // result as a Value.
   // Wrap this in base::FooValue::From() to check the Value is of type Foo and
   // convert to a FooValue at the same time.
-  absl::optional<Value> Parse(StringPiece input);
+  std::optional<Value> Parse(StringPiece input);
 
   // Returns the error code.
   JsonParseError error_code() const;
@@ -155,22 +155,22 @@
 
     // The copied string representation. Will be unset until Convert() is
     // called.
-    absl::optional<std::string> string_;
+    std::optional<std::string> string_;
   };
 
   // Returns the next |count| bytes of the input stream, or nullopt if fewer
   // than |count| bytes remain.
-  absl::optional<StringPiece> PeekChars(size_t count);
+  std::optional<StringPiece> PeekChars(size_t count);
 
   // Calls PeekChars() with a |count| of 1.
-  absl::optional<char> PeekChar();
+  std::optional<char> PeekChar();
 
   // Returns the next |count| bytes of the input stream, or nullopt if fewer
   // than |count| bytes remain, and advances the parser position by |count|.
-  absl::optional<StringPiece> ConsumeChars(size_t count);
+  std::optional<StringPiece> ConsumeChars(size_t count);
 
   // Calls ConsumeChars() with a |count| of 1.
-  absl::optional<char> ConsumeChar();
+  std::optional<char> ConsumeChar();
 
   // Returns a pointer to the current character position.
   const char* pos();
@@ -187,22 +187,22 @@
   bool EatComment();
 
   // Calls GetNextToken() and then ParseToken().
-  absl::optional<Value> ParseNextToken();
+  std::optional<Value> ParseNextToken();
 
   // Takes a token that represents the start of a Value ("a structural token"
   // in RFC terms) and consumes it, returning the result as a Value.
-  absl::optional<Value> ParseToken(Token token);
+  std::optional<Value> ParseToken(Token token);
 
   // Assuming that the parser is currently wound to '{', this parses a JSON
   // object into a Value.
-  absl::optional<Value> ConsumeDictionary();
+  std::optional<Value> ConsumeDictionary();
 
   // Assuming that the parser is wound to '[', this parses a JSON list into a
   // Value.
-  absl::optional<Value> ConsumeList();
+  std::optional<Value> ConsumeList();
 
   // Calls through ConsumeStringRaw and wraps it in a value.
-  absl::optional<Value> ConsumeString();
+  std::optional<Value> ConsumeString();
 
   // Assuming that the parser is wound to a double quote, this parses a string,
   // decoding any escape sequences and converts UTF-16 to UTF-8. Returns true on
@@ -217,14 +217,14 @@
 
   // Assuming that the parser is wound to the start of a valid JSON number,
   // this parses and converts it to either an int or double value.
-  absl::optional<Value> ConsumeNumber();
+  std::optional<Value> ConsumeNumber();
   // Helper that reads characters that are ints. Returns true if a number was
   // read and false on error.
   bool ReadInt(bool allow_leading_zeros);
 
   // Consumes the literal values of |true|, |false|, and |null|, assuming the
   // parser is wound to the first character of any of those.
-  absl::optional<Value> ConsumeLiteral();
+  std::optional<Value> ConsumeLiteral();
 
   // Helper function that returns true if the byte squence |match| can be
   // consumed at the current parser position. Returns false if there are fewer
diff --git a/base/json/json_parser_unittest.cc b/base/json/json_parser_unittest.cc
index a185e47..3985a70 100644
--- a/base/json/json_parser_unittest.cc
+++ b/base/json/json_parser_unittest.cc
@@ -7,12 +7,12 @@
 #include <stddef.h>
 
 #include <memory>
+#include <optional>
 
 #include "base/json/json_reader.h"
 #include "base/memory/ptr_util.h"
 #include "base/values.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace internal {
@@ -54,7 +54,7 @@
 TEST_F(JSONParserTest, ConsumeString) {
   std::string input("\"test\",|");
   std::unique_ptr<JSONParser> parser(NewTestParser(input));
-  absl::optional<Value> value(parser->ConsumeString());
+  std::optional<Value> value(parser->ConsumeString());
   EXPECT_EQ(',', *parser->pos());
 
   TestLastThree(parser.get());
@@ -67,7 +67,7 @@
 TEST_F(JSONParserTest, ConsumeList) {
   std::string input("[true, false],|");
   std::unique_ptr<JSONParser> parser(NewTestParser(input));
-  absl::optional<Value> value(parser->ConsumeList());
+  std::optional<Value> value(parser->ConsumeList());
   EXPECT_EQ(',', *parser->pos());
 
   TestLastThree(parser.get());
@@ -81,7 +81,7 @@
 TEST_F(JSONParserTest, ConsumeDictionary) {
   std::string input("{\"abc\":\"def\"},|");
   std::unique_ptr<JSONParser> parser(NewTestParser(input));
-  absl::optional<Value> value(parser->ConsumeDictionary());
+  std::optional<Value> value(parser->ConsumeDictionary());
   EXPECT_EQ(',', *parser->pos());
 
   TestLastThree(parser.get());
@@ -98,7 +98,7 @@
   // Literal |true|.
   std::string input("true,|");
   std::unique_ptr<JSONParser> parser(NewTestParser(input));
-  absl::optional<Value> value(parser->ConsumeLiteral());
+  std::optional<Value> value(parser->ConsumeLiteral());
   EXPECT_EQ(',', *parser->pos());
 
   TestLastThree(parser.get());
@@ -135,7 +135,7 @@
   // Integer.
   std::string input("1234,|");
   std::unique_ptr<JSONParser> parser(NewTestParser(input));
-  absl::optional<Value> value(parser->ConsumeNumber());
+  std::optional<Value> value(parser->ConsumeNumber());
   EXPECT_EQ(',', *parser->pos());
 
   TestLastThree(parser.get());
@@ -232,7 +232,7 @@
 TEST_F(JSONParserTest, ErrorMessages) {
   {
     JSONParser parser(JSON_PARSE_RFC);
-    absl::optional<Value> value = parser.Parse("[42]");
+    std::optional<Value> value = parser.Parse("[42]");
     EXPECT_TRUE(value);
     EXPECT_TRUE(parser.GetErrorMessage().empty());
     EXPECT_EQ(0, parser.error_code());
@@ -241,7 +241,7 @@
   // Test each of the error conditions
   {
     JSONParser parser(JSON_PARSE_RFC);
-    absl::optional<Value> value = parser.Parse("{},{}");
+    std::optional<Value> value = parser.Parse("{},{}");
     EXPECT_FALSE(value);
     EXPECT_EQ(JSONParser::FormatErrorMessage(
                   1, 3, JSONParser::kUnexpectedDataAfterRoot),
@@ -256,7 +256,7 @@
       nested_json.append(1, ']');
     }
     JSONParser parser(JSON_PARSE_RFC);
-    absl::optional<Value> value = parser.Parse(nested_json);
+    std::optional<Value> value = parser.Parse(nested_json);
     EXPECT_FALSE(value);
     EXPECT_EQ(
         JSONParser::FormatErrorMessage(1, 200, JSONParser::kTooMuchNesting),
@@ -266,7 +266,7 @@
 
   {
     JSONParser parser(JSON_PARSE_RFC);
-    absl::optional<Value> value = parser.Parse("[1,]");
+    std::optional<Value> value = parser.Parse("[1,]");
     EXPECT_FALSE(value);
     EXPECT_EQ(JSONParser::FormatErrorMessage(1, 4, JSONParser::kTrailingComma),
               parser.GetErrorMessage());
@@ -275,7 +275,7 @@
 
   {
     JSONParser parser(JSON_PARSE_RFC);
-    absl::optional<Value> value = parser.Parse("{foo:\"bar\"}");
+    std::optional<Value> value = parser.Parse("{foo:\"bar\"}");
     EXPECT_FALSE(value);
     EXPECT_EQ(JSONParser::FormatErrorMessage(
                   1, 2, JSONParser::kUnquotedDictionaryKey),
@@ -285,7 +285,7 @@
 
   {
     JSONParser parser(JSON_PARSE_RFC);
-    absl::optional<Value> value = parser.Parse("{\"foo\":\"bar\",}");
+    std::optional<Value> value = parser.Parse("{\"foo\":\"bar\",}");
     EXPECT_FALSE(value);
     EXPECT_EQ(JSONParser::FormatErrorMessage(1, 14, JSONParser::kTrailingComma),
               parser.GetErrorMessage());
@@ -294,7 +294,7 @@
 
   {
     JSONParser parser(JSON_PARSE_RFC);
-    absl::optional<Value> value = parser.Parse("[nu]");
+    std::optional<Value> value = parser.Parse("[nu]");
     EXPECT_FALSE(value);
     EXPECT_EQ(JSONParser::FormatErrorMessage(1, 2, JSONParser::kSyntaxError),
               parser.GetErrorMessage());
@@ -303,7 +303,7 @@
 
   {
     JSONParser parser(JSON_PARSE_RFC | JSON_ALLOW_X_ESCAPES);
-    absl::optional<Value> value = parser.Parse("[\"xxx\\xq\"]");
+    std::optional<Value> value = parser.Parse("[\"xxx\\xq\"]");
     EXPECT_FALSE(value);
     EXPECT_EQ(JSONParser::FormatErrorMessage(1, 7, JSONParser::kInvalidEscape),
               parser.GetErrorMessage());
@@ -312,7 +312,7 @@
 
   {
     JSONParser parser(JSON_PARSE_RFC);
-    absl::optional<Value> value = parser.Parse("[\"xxx\\uq\"]");
+    std::optional<Value> value = parser.Parse("[\"xxx\\uq\"]");
     EXPECT_FALSE(value);
     EXPECT_EQ(JSONParser::FormatErrorMessage(1, 7, JSONParser::kInvalidEscape),
               parser.GetErrorMessage());
@@ -321,7 +321,7 @@
 
   {
     JSONParser parser(JSON_PARSE_RFC);
-    absl::optional<Value> value = parser.Parse("[\"xxx\\q\"]");
+    std::optional<Value> value = parser.Parse("[\"xxx\\q\"]");
     EXPECT_FALSE(value);
     EXPECT_EQ(JSONParser::FormatErrorMessage(1, 7, JSONParser::kInvalidEscape),
               parser.GetErrorMessage());
diff --git a/base/json/json_reader.cc b/base/json/json_reader.cc
index 5a1aa75..62e670c 100644
--- a/base/json/json_reader.cc
+++ b/base/json/json_reader.cc
@@ -4,13 +4,13 @@
 
 #include "base/json/json_reader.h"
 
+#include <optional>
 #include <utility>
 
 #include "base/features.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/rust_buildflags.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(BUILD_RUST_JSON_READER)
 #include "base/strings/string_piece_rust.h"
@@ -134,15 +134,15 @@
 #endif  // BUILDFLAG(BUILD_RUST_JSON_READER)
 
 // static
-absl::optional<Value> JSONReader::Read(StringPiece json,
-                                       int options,
-                                       size_t max_depth) {
+std::optional<Value> JSONReader::Read(StringPiece json,
+                                      int options,
+                                      size_t max_depth) {
 #if BUILDFLAG(BUILD_RUST_JSON_READER)
   SCOPED_UMA_HISTOGRAM_TIMER_MICROS(kSecurityJsonParsingTime);
   if (UsingRust()) {
     JSONReader::Result result = DecodeJSONInRust(json, options, max_depth);
     if (!result.has_value()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return std::move(*result);
   } else {
@@ -156,12 +156,12 @@
 }
 
 // static
-absl::optional<Value::Dict> JSONReader::ReadDict(StringPiece json,
-                                                 int options,
-                                                 size_t max_depth) {
-  absl::optional<Value> value = Read(json, options, max_depth);
+std::optional<Value::Dict> JSONReader::ReadDict(StringPiece json,
+                                                int options,
+                                                size_t max_depth) {
+  std::optional<Value> value = Read(json, options, max_depth);
   if (!value || !value->is_dict()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return std::move(*value).TakeDict();
 }
diff --git a/base/json/json_reader.h b/base/json/json_reader.h
index fa3b5bb..5b9b25b 100644
--- a/base/json/json_reader.h
+++ b/base/json/json_reader.h
@@ -36,6 +36,7 @@
 #ifndef BASE_JSON_JSON_READER_H_
 #define BASE_JSON_JSON_READER_H_
 
+#include <optional>
 #include <string>
 
 #include "base/base_export.h"
@@ -44,7 +45,6 @@
 #include "base/strings/string_piece.h"
 #include "base/types/expected.h"
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -106,15 +106,15 @@
   JSONReader& operator=(const JSONReader&) = delete;
 
   // Reads and parses |json|, returning a Value.
-  // If |json| is not a properly formed JSON string, returns absl::nullopt.
-  static absl::optional<Value> Read(
+  // If |json| is not a properly formed JSON string, returns std::nullopt.
+  static std::optional<Value> Read(
       StringPiece json,
       int options = JSON_PARSE_CHROMIUM_EXTENSIONS,
       size_t max_depth = internal::kAbsoluteMaxDepth);
 
   // Reads and parses |json|, returning a Value::Dict.
-  // If |json| is not a properly formed JSON dict string, returns absl::nullopt.
-  static absl::optional<Value::Dict> ReadDict(
+  // If |json| is not a properly formed JSON dict string, returns std::nullopt.
+  static std::optional<Value::Dict> ReadDict(
       StringPiece json,
       int options = JSON_PARSE_CHROMIUM_EXTENSIONS,
       size_t max_depth = internal::kAbsoluteMaxDepth);
diff --git a/base/json/json_reader_fuzzer.cc b/base/json/json_reader_fuzzer.cc
index fb82787..17a56062 100644
--- a/base/json/json_reader_fuzzer.cc
+++ b/base/json/json_reader_fuzzer.cc
@@ -3,9 +3,11 @@
 // found in the LICENSE file.
 
 #include "base/json/json_reader.h"
+
+#include <optional>
+
 #include "base/json/json_writer.h"
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -32,7 +34,7 @@
     std::string serialized;
     CHECK(JSONWriter::Write(value, &serialized));
 
-    absl::optional<Value> deserialized =
+    std::optional<Value> deserialized =
         JSONReader::Read(StringPiece(serialized));
     CHECK(deserialized);
     CHECK_EQ(value, deserialized.value());
diff --git a/base/json/json_reader_unittest.cc b/base/json/json_reader_unittest.cc
index 10a9ba2..7b51089 100644
--- a/base/json/json_reader_unittest.cc
+++ b/base/json/json_reader_unittest.cc
@@ -7,6 +7,7 @@
 #include <stddef.h>
 
 #include <cmath>
+#include <optional>
 #include <utility>
 
 #include "base/base_paths.h"
@@ -25,7 +26,6 @@
 #include "build/build_config.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -57,7 +57,7 @@
 };
 
 TEST_P(JSONReaderTest, Whitespace) {
-  absl::optional<Value> root = JSONReader::Read("   null   ");
+  std::optional<Value> root = JSONReader::Read("   null   ");
   ASSERT_TRUE(root);
   EXPECT_TRUE(root->is_none());
 }
@@ -73,7 +73,7 @@
 #if BUILDFLAG(BUILD_RUST_JSON_READER)
   base::HistogramTester histograms;
 #endif  // BUILDFLAG(BUILD_RUST_JSON_READER)
-  absl::optional<Value> root = JSONReader::Read("true  ");
+  std::optional<Value> root = JSONReader::Read("true  ");
   ASSERT_TRUE(root);
   EXPECT_TRUE(root->is_bool());
 #if BUILDFLAG(BUILD_RUST_JSON_READER)
@@ -82,7 +82,7 @@
 }
 
 TEST_P(JSONReaderTest, EmbeddedComments) {
-  absl::optional<Value> root = JSONReader::Read("/* comment */null");
+  std::optional<Value> root = JSONReader::Read("/* comment */null");
   ASSERT_TRUE(root);
   EXPECT_TRUE(root->is_none());
   root = JSONReader::Read("40 /* comment */");
@@ -138,7 +138,7 @@
 }
 
 TEST_P(JSONReaderTest, Ints) {
-  absl::optional<Value> root = JSONReader::Read("43");
+  std::optional<Value> root = JSONReader::Read("43");
   ASSERT_TRUE(root);
   ASSERT_TRUE(root->is_int());
   EXPECT_EQ(43, root->GetInt());
@@ -154,7 +154,7 @@
 TEST_P(JSONReaderTest, NumberZero) {
   // Test 0 (which needs to be special cased because of the leading zero
   // clause).
-  absl::optional<Value> root = JSONReader::Read("0");
+  std::optional<Value> root = JSONReader::Read("0");
   ASSERT_TRUE(root);
   ASSERT_TRUE(root->is_int());
   EXPECT_EQ(0, root->GetInt());
@@ -163,7 +163,7 @@
 TEST_P(JSONReaderTest, LargeIntPromotion) {
   // Numbers that overflow ints should succeed, being internally promoted to
   // storage as doubles
-  absl::optional<Value> root = JSONReader::Read("2147483648");
+  std::optional<Value> root = JSONReader::Read("2147483648");
   ASSERT_TRUE(root);
   EXPECT_TRUE(root->is_double());
   EXPECT_DOUBLE_EQ(2147483648.0, root->GetDouble());
@@ -180,7 +180,7 @@
   // In this case, parsing is lossy.
   const char* etc807 = "9223372036854775807";
   const char* etc808 = "9223372036854775808.000000";
-  absl::optional<Value> root = JSONReader::Read(etc807);
+  std::optional<Value> root = JSONReader::Read(etc807);
   ASSERT_TRUE(root);
   ASSERT_FALSE(root->is_int());
   ASSERT_TRUE(root->is_double());
@@ -191,7 +191,7 @@
 }
 
 TEST_P(JSONReaderTest, Doubles) {
-  absl::optional<Value> root = JSONReader::Read("43.1");
+  std::optional<Value> root = JSONReader::Read("43.1");
   ASSERT_TRUE(root);
   EXPECT_TRUE(root->is_double());
   EXPECT_DOUBLE_EQ(43.1, root->GetDouble());
@@ -268,7 +268,7 @@
 }
 
 TEST_P(JSONReaderTest, Zeroes) {
-  absl::optional<Value> root = JSONReader::Read("0");
+  std::optional<Value> root = JSONReader::Read("0");
   ASSERT_TRUE(root);
   EXPECT_TRUE(root->is_int());
   EXPECT_DOUBLE_EQ(0, root->GetInt());
@@ -293,21 +293,21 @@
 }
 
 TEST_P(JSONReaderTest, SimpleString) {
-  absl::optional<Value> root = JSONReader::Read("\"hello world\"");
+  std::optional<Value> root = JSONReader::Read("\"hello world\"");
   ASSERT_TRUE(root);
   ASSERT_TRUE(root->is_string());
   EXPECT_EQ("hello world", root->GetString());
 }
 
 TEST_P(JSONReaderTest, EmptyString) {
-  absl::optional<Value> root = JSONReader::Read("\"\"");
+  std::optional<Value> root = JSONReader::Read("\"\"");
   ASSERT_TRUE(root);
   ASSERT_TRUE(root->is_string());
   EXPECT_EQ("", root->GetString());
 }
 
 TEST_P(JSONReaderTest, BasicStringEscapes) {
-  absl::optional<Value> root =
+  std::optional<Value> root =
       JSONReader::Read("\" \\\"\\\\\\/\\b\\f\\n\\r\\t\\v\"");
   ASSERT_TRUE(root);
   ASSERT_TRUE(root->is_string());
@@ -316,7 +316,7 @@
 
 TEST_P(JSONReaderTest, UnicodeEscapes) {
   // Test hex and unicode escapes including the null character.
-  absl::optional<Value> root =
+  std::optional<Value> root =
       JSONReader::Read("\"\\x41\\xFF\\x00\\u1234\\u0000\"");
   ASSERT_TRUE(root);
   ASSERT_TRUE(root->is_string());
@@ -341,21 +341,21 @@
 }
 
 TEST_P(JSONReaderTest, BasicArray) {
-  absl::optional<Value> root = JSONReader::Read("[true, false, null]");
+  std::optional<Value> root = JSONReader::Read("[true, false, null]");
   ASSERT_TRUE(root);
   Value::List* list = root->GetIfList();
   ASSERT_TRUE(list);
   EXPECT_EQ(3U, list->size());
 
   // Test with trailing comma.  Should be parsed the same as above.
-  absl::optional<Value> root2 =
+  std::optional<Value> root2 =
       JSONReader::Read("[true, false, null, ]", JSON_ALLOW_TRAILING_COMMAS);
   ASSERT_TRUE(root2);
   EXPECT_EQ(*list, *root2);
 }
 
 TEST_P(JSONReaderTest, EmptyArray) {
-  absl::optional<Value> value = JSONReader::Read("[]");
+  std::optional<Value> value = JSONReader::Read("[]");
   ASSERT_TRUE(value);
   Value::List* list = value->GetIfList();
   ASSERT_TRUE(list);
@@ -363,7 +363,7 @@
 }
 
 TEST_P(JSONReaderTest, CompleteArray) {
-  absl::optional<Value> value = JSONReader::Read("[\"a\", 3, 4.56, null]");
+  std::optional<Value> value = JSONReader::Read("[\"a\", 3, 4.56, null]");
   ASSERT_TRUE(value);
   Value::List* list = value->GetIfList();
   ASSERT_TRUE(list);
@@ -371,7 +371,7 @@
 }
 
 TEST_P(JSONReaderTest, NestedArrays) {
-  absl::optional<Value> value = JSONReader::Read(
+  std::optional<Value> value = JSONReader::Read(
       "[[true], [], {\"smell\": \"nice\",\"taste\": \"yummy\" }, [false, [], "
       "[null]], null]");
   ASSERT_TRUE(value);
@@ -380,7 +380,7 @@
   EXPECT_EQ(5U, list->size());
 
   // Lots of trailing commas.
-  absl::optional<Value> root2 = JSONReader::Read(
+  std::optional<Value> root2 = JSONReader::Read(
       "[[true], [], {\"smell\": \"nice\",\"taste\": \"yummy\" }, [false, [], "
       "[null, ]  , ], null,]",
       JSON_ALLOW_TRAILING_COMMAS);
@@ -405,7 +405,7 @@
 
 TEST_P(JSONReaderTest, ArrayTrailingComma) {
   // Valid if we set |allow_trailing_comma| to true.
-  absl::optional<Value> value =
+  std::optional<Value> value =
       JSONReader::Read("[true,]", JSON_ALLOW_TRAILING_COMMAS);
   ASSERT_TRUE(value);
   Value::List* list = value->GetIfList();
@@ -426,13 +426,13 @@
 }
 
 TEST_P(JSONReaderTest, EmptyDictionary) {
-  absl::optional<Value> dict_val = JSONReader::Read("{}");
+  std::optional<Value> dict_val = JSONReader::Read("{}");
   ASSERT_TRUE(dict_val);
   ASSERT_TRUE(dict_val->is_dict());
 }
 
 TEST_P(JSONReaderTest, CompleteDictionary) {
-  absl::optional<Value> root1 = JSONReader::Read(
+  std::optional<Value> root1 = JSONReader::Read(
       "{\"number\":9.87654321, \"null\":null , \"\\x53\" : \"str\", \"bool\": "
       "false, \"more\": {} }");
   ASSERT_TRUE(root1);
@@ -451,7 +451,7 @@
   ASSERT_TRUE(bool_val);
   ASSERT_FALSE(*bool_val);
 
-  absl::optional<Value> root2 = JSONReader::Read(
+  std::optional<Value> root2 = JSONReader::Read(
       "{\"number\":9.87654321, \"null\":null , \"\\x53\" : \"str\", \"bool\": "
       "false, \"more\": {},}",
       JSON_PARSE_CHROMIUM_EXTENSIONS | JSON_ALLOW_TRAILING_COMMAS);
@@ -491,7 +491,7 @@
 }
 
 TEST_P(JSONReaderTest, NestedDictionaries) {
-  absl::optional<Value> root1 = JSONReader::Read(
+  std::optional<Value> root1 = JSONReader::Read(
       "{\"inner\":{\"array\":[true, 3, 4.56, null]},\"false\":false,\"d\":{}}");
   ASSERT_TRUE(root1);
   const base::Value::Dict* root1_dict = root1->GetIfDict();
@@ -507,7 +507,7 @@
   inner_dict = root1_dict->FindDict("d");
   EXPECT_TRUE(inner_dict);
 
-  absl::optional<Value> root2 = JSONReader::Read(
+  std::optional<Value> root2 = JSONReader::Read(
       "{\"inner\": {\"array\":[true, 3, 4.56, null] , "
       "},\"false\":false,\"d\":{},}",
       JSON_ALLOW_TRAILING_COMMAS);
@@ -516,7 +516,7 @@
 }
 
 TEST_P(JSONReaderTest, DictionaryKeysWithPeriods) {
-  absl::optional<Value> root =
+  std::optional<Value> root =
       JSONReader::Read("{\"a.b\":3,\"c\":2,\"d.e.f\":{\"g.h.i.j\":1}}");
   ASSERT_TRUE(root);
   Value::Dict* root_dict = root->GetIfDict();
@@ -548,7 +548,7 @@
 }
 
 TEST_P(JSONReaderTest, DuplicateKeys) {
-  absl::optional<Value> root = JSONReader::Read("{\"x\":1,\"x\":2,\"y\":3}");
+  std::optional<Value> root = JSONReader::Read("{\"x\":1,\"x\":2,\"y\":3}");
   ASSERT_TRUE(root);
   const Value::Dict* root_dict = root->GetIfDict();
   ASSERT_TRUE(root_dict);
@@ -599,7 +599,7 @@
   for (int i = 0; i < 5000; ++i)
     not_evil.append("[],");
   not_evil.append("[]]");
-  absl::optional<Value> value = JSONReader::Read(not_evil);
+  std::optional<Value> value = JSONReader::Read(not_evil);
   ASSERT_TRUE(value);
   Value::List* list = value->GetIfList();
   ASSERT_TRUE(list);
@@ -607,7 +607,7 @@
 }
 
 TEST_P(JSONReaderTest, UTF8Input) {
-  absl::optional<Value> root = JSONReader::Read("\"\xe7\xbd\x91\xe9\xa1\xb5\"");
+  std::optional<Value> root = JSONReader::Read("\"\xe7\xbd\x91\xe9\xa1\xb5\"");
   ASSERT_TRUE(root);
   ASSERT_TRUE(root->is_string());
   const std::string& str_val = root->GetString();
@@ -677,7 +677,7 @@
 }
 
 TEST_P(JSONReaderTest, UTF16Escapes) {
-  absl::optional<Value> root = JSONReader::Read("\"\\u20ac3,14\"");
+  std::optional<Value> root = JSONReader::Read("\"\\u20ac3,14\"");
   ASSERT_TRUE(root);
   ASSERT_TRUE(root->is_string());
   EXPECT_EQ(
@@ -706,7 +706,7 @@
       "\"\\ud83d\\u1\"",     // No lower surrogate.
       "\"\\ud83\\u1\"",      // Invalid upper surrogate.
   };
-  absl::optional<Value> root;
+  std::optional<Value> root;
   for (auto* i : cases) {
     root = JSONReader::Read(i);
     EXPECT_FALSE(root) << i;
@@ -714,7 +714,7 @@
 }
 
 TEST_P(JSONReaderTest, LiteralRoots) {
-  absl::optional<Value> root = JSONReader::Read("null");
+  std::optional<Value> root = JSONReader::Read("null");
   ASSERT_TRUE(root);
   EXPECT_TRUE(root->is_none());
 
@@ -759,7 +759,7 @@
   Value list_value_1;
 
   {
-    absl::optional<Value> root = JSONReader::Read(
+    std::optional<Value> root = JSONReader::Read(
         "{"
         "  \"test\": {"
         "    \"foo\": true,"
@@ -854,8 +854,7 @@
   //
   // Nonetheless, we accept them, for backwards compatibility.
   const char json[] = {'"', 'a', '\0', 'b', '\n', 'c', '"'};
-  absl::optional<Value> root =
-      JSONReader::Read(std::string(json, sizeof(json)));
+  std::optional<Value> root = JSONReader::Read(std::string(json, sizeof(json)));
   ASSERT_TRUE(root);
   ASSERT_TRUE(root->is_string());
   EXPECT_EQ(5u, root->GetString().length());
@@ -872,7 +871,7 @@
   // should be able to handle. The UTF-8 encoding of U+1F607 SMILING FACE WITH
   // HALO is "\xF0\x9F\x98\x87".
   const char kUtf8Data[] = "[\"😇\",[],[],[],{\"google:suggesttype\":[]}]";
-  absl::optional<Value> root = JSONReader::Read(kUtf8Data, JSON_PARSE_RFC);
+  std::optional<Value> root = JSONReader::Read(kUtf8Data, JSON_PARSE_RFC);
   ASSERT_TRUE(root);
   Value::List* list = root->GetIfList();
   ASSERT_TRUE(list);
@@ -932,7 +931,7 @@
 TEST_P(JSONReaderTest, ReplaceInvalidCharacters) {
   // U+D800 is a lone high surrogate.
   const std::string invalid_high = "\"\xED\xA0\x80\"";
-  absl::optional<Value> value =
+  std::optional<Value> value =
       JSONReader::Read(invalid_high, JSON_REPLACE_INVALID_CHARACTERS);
   ASSERT_TRUE(value);
   ASSERT_TRUE(value->is_string());
@@ -951,7 +950,7 @@
 TEST_P(JSONReaderTest, ReplaceInvalidUTF16EscapeSequence) {
   // U+D800 is a lone high surrogate.
   const std::string invalid_high = "\"_\\uD800_\"";
-  absl::optional<Value> value =
+  std::optional<Value> value =
       JSONReader::Read(invalid_high, JSON_REPLACE_INVALID_CHARACTERS);
   ASSERT_TRUE(value);
   ASSERT_TRUE(value->is_string());
@@ -992,7 +991,7 @@
     StringPiece input =
         MakeNotNullTerminatedInput(test_case.input, &input_owner);
 
-    absl::optional<Value> result = JSONReader::Read(input);
+    std::optional<Value> result = JSONReader::Read(input);
     EXPECT_EQ(test_case.parse_success, result.has_value());
 
     if (!result)
diff --git a/base/json/json_value_converter_unittest.cc b/base/json/json_value_converter_unittest.cc
index f385486..9a95421 100644
--- a/base/json/json_value_converter_unittest.cc
+++ b/base/json/json_value_converter_unittest.cc
@@ -5,6 +5,7 @@
 #include "base/json/json_value_converter.h"
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -12,7 +13,6 @@
 #include "base/strings/string_piece.h"
 #include "base/values.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace {
@@ -106,7 +106,7 @@
       "  \"ints\": [1, 2]"
       "}\n";
 
-  absl::optional<Value> value = base::JSONReader::Read(normal_data);
+  std::optional<Value> value = base::JSONReader::Read(normal_data);
   ASSERT_TRUE(value);
   SimpleMessage message;
   base::JSONValueConverter<SimpleMessage> converter;
@@ -149,7 +149,7 @@
       "  }]\n"
       "}\n";
 
-  absl::optional<Value> value = base::JSONReader::Read(normal_data);
+  std::optional<Value> value = base::JSONReader::Read(normal_data);
   ASSERT_TRUE(value);
   NestedMessage message;
   base::JSONValueConverter<NestedMessage> converter;
@@ -192,7 +192,7 @@
       "  \"ints\": [1, 2]"
       "}\n";
 
-  absl::optional<Value> value = base::JSONReader::Read(normal_data);
+  std::optional<Value> value = base::JSONReader::Read(normal_data);
   ASSERT_TRUE(value);
   SimpleMessage message;
   base::JSONValueConverter<SimpleMessage> converter;
@@ -209,7 +209,7 @@
       "  \"ints\": [1, 2]"
       "}\n";
 
-  absl::optional<Value> value = base::JSONReader::Read(normal_data);
+  std::optional<Value> value = base::JSONReader::Read(normal_data);
   ASSERT_TRUE(value);
   SimpleMessage message;
   base::JSONValueConverter<SimpleMessage> converter;
@@ -233,7 +233,7 @@
       "  \"ints\": [1, 2]"
       "}\n";
 
-  absl::optional<Value> value = base::JSONReader::Read(normal_data);
+  std::optional<Value> value = base::JSONReader::Read(normal_data);
   ASSERT_TRUE(value);
   SimpleMessage message;
   base::JSONValueConverter<SimpleMessage> converter;
@@ -251,7 +251,7 @@
       "  \"ints\": [1, false]"
       "}\n";
 
-  absl::optional<Value> value = base::JSONReader::Read(normal_data);
+  std::optional<Value> value = base::JSONReader::Read(normal_data);
   ASSERT_TRUE(value);
   SimpleMessage message;
   base::JSONValueConverter<SimpleMessage> converter;
diff --git a/base/json/json_value_serializer_unittest.cc b/base/json/json_value_serializer_unittest.cc
index f9fc204..30ab7bc 100644
--- a/base/json/json_value_serializer_unittest.cc
+++ b/base/json/json_value_serializer_unittest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "base/files/file_util.h"
@@ -18,7 +19,6 @@
 #include "base/values.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -77,7 +77,7 @@
 }
 
 void ValidateJsonList(const std::string& json) {
-  absl::optional<Value> value = JSONReader::Read(json);
+  std::optional<Value> value = JSONReader::Read(json);
   ASSERT_TRUE(value);
   Value::List* list = value->GetIfList();
   ASSERT_TRUE(list);
@@ -370,7 +370,7 @@
   ValidateJsonList("[ 1 //// ,2\r\n ]");
 
   // It's ok to have a comment in a string.
-  absl::optional<Value> value = JSONReader::Read("[\"// ok\\n /* foo */ \"]");
+  std::optional<Value> value = JSONReader::Read("[\"// ok\\n /* foo */ \"]");
   ASSERT_TRUE(value);
   Value::List* list = value->GetIfList();
   ASSERT_TRUE(list);
diff --git a/base/json/json_writer.cc b/base/json/json_writer.cc
index 9195e64..a58ec155 100644
--- a/base/json/json_writer.cc
+++ b/base/json/json_writer.cc
@@ -215,21 +215,21 @@
   json_string_->append(depth * 3U, ' ');
 }
 
-absl::optional<std::string> WriteJson(ValueView node, size_t max_depth) {
+std::optional<std::string> WriteJson(ValueView node, size_t max_depth) {
   std::string result;
   if (!JSONWriter::Write(node, &result, max_depth)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return result;
 }
 
-absl::optional<std::string> WriteJsonWithOptions(ValueView node,
-                                                 uint32_t options,
-                                                 size_t max_depth) {
+std::optional<std::string> WriteJsonWithOptions(ValueView node,
+                                                uint32_t options,
+                                                size_t max_depth) {
   std::string result;
   if (!JSONWriter::WriteWithOptions(node, static_cast<int>(options), &result,
                                     max_depth)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return result;
 }
diff --git a/base/json/json_writer.h b/base/json/json_writer.h
index ddb943d9..05aef57 100644
--- a/base/json/json_writer.h
+++ b/base/json/json_writer.h
@@ -6,7 +6,9 @@
 #define BASE_JSON_JSON_WRITER_H_
 
 #include <stddef.h>
+
 #include <cstdint>
+#include <optional>
 #include <string>
 
 #include "base/base_export.h"
@@ -14,7 +16,6 @@
 #include "base/memory/raw_ptr.h"
 #include "base/strings/string_piece.h"
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -38,10 +39,10 @@
 
 // Given a root node, generates and returns a JSON string.
 //
-// Returns `absl::nullopt` if
+// Returns `std::nullopt` if
 //    * the nesting depth exceeds `max_depth`, or
 //    * the JSON contains binary values.
-BASE_EXPORT absl::optional<std::string> WriteJson(
+BASE_EXPORT std::optional<std::string> WriteJson(
     ValueView node,
     size_t max_depth = internal::kAbsoluteMaxDepth);
 
@@ -49,11 +50,11 @@
 // The string is formatted according to `options` which is a bitmask of
 // `JsonOptions`.
 //
-// Returns `absl::nullopt` if
+// Returns `std::nullopt` if
 //    * the nesting depth exceeds `max_depth,` or
 //    * the JSON contains binary values
 //      (unless `JsonOptions::OPTIONS_OMIT_BINARY_VALUES` is passed).
-BASE_EXPORT absl::optional<std::string> WriteJsonWithOptions(
+BASE_EXPORT std::optional<std::string> WriteJsonWithOptions(
     ValueView node,
     uint32_t options,
     size_t max_depth = internal::kAbsoluteMaxDepth);
diff --git a/base/json/json_writer_unittest.cc b/base/json/json_writer_unittest.cc
index 777b33e0..49d93dd 100644
--- a/base/json/json_writer_unittest.cc
+++ b/base/json/json_writer_unittest.cc
@@ -3,15 +3,16 @@
 // found in the LICENSE file.
 
 #include "base/json/json_writer.h"
-#include "base/json/json_reader.h"
+
+#include <optional>
 
 #include "base/containers/span.h"
+#include "base/json/json_reader.h"
 #include "base/strings/stringprintf.h"
 #include "base/test/gmock_expected_support.h"
 #include "base/values.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_WIN)
 #include "base/strings/string_util.h"
@@ -105,7 +106,7 @@
 
   // Binary values should return errors unless suppressed via the
   // `OPTIONS_OMIT_BINARY_VALUES` flag.
-  EXPECT_EQ(WriteJson(Value(kBinaryData)), absl::nullopt);
+  EXPECT_EQ(WriteJson(Value(kBinaryData)), std::nullopt);
   EXPECT_EQ(WriteJsonWithOptions(Value(kBinaryData),
                                  JsonOptions::OPTIONS_OMIT_BINARY_VALUES),
             "");
@@ -116,7 +117,7 @@
                          .Append(Value(kBinaryData))
                          .Append(2)
                          .Append(Value(kBinaryData));
-  EXPECT_EQ(WriteJson(binary_list), absl::nullopt);
+  EXPECT_EQ(WriteJson(binary_list), std::nullopt);
   EXPECT_EQ(
       WriteJsonWithOptions(binary_list, JSONWriter::OPTIONS_OMIT_BINARY_VALUES),
       "[5,2]");
@@ -127,7 +128,7 @@
                          .Set("c", Value(kBinaryData))
                          .Set("d", 2)
                          .Set("e", Value(kBinaryData));
-  EXPECT_EQ(WriteJson(binary_dict), absl::nullopt);
+  EXPECT_EQ(WriteJson(binary_dict), std::nullopt);
   EXPECT_EQ(
       WriteJsonWithOptions(binary_dict, JSONWriter::OPTIONS_OMIT_BINARY_VALUES),
       R"({"b":5,"d":2})");
@@ -153,10 +154,10 @@
   }
 
   Value deep_list_value(std::move(deep_list));
-  EXPECT_EQ(WriteJson(deep_list_value), absl::nullopt);
+  EXPECT_EQ(WriteJson(deep_list_value), std::nullopt);
   EXPECT_EQ(
       WriteJsonWithOptions(deep_list_value, JSONWriter::OPTIONS_PRETTY_PRINT),
-      absl::nullopt);
+      std::nullopt);
 
   // We cannot just let `deep_list` tear down since it
   // would cause a stack overflow. Therefore, we tear
diff --git a/base/json/values_util.cc b/base/json/values_util.cc
index 8f14256..f656db2 100644
--- a/base/json/values_util.cc
+++ b/base/json/values_util.cc
@@ -4,11 +4,12 @@
 
 #include "base/json/values_util.h"
 
+#include <optional>
+
 #include "base/files/file_path.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/time/time.h"
 #include "base/unguessable_token.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // Warning: The Values involved could be stored on persistent storage like files
 // on disks. Therefore, changes in implementation could lead to data corruption
@@ -36,17 +37,17 @@
   return Value(NumberToString(integer));
 }
 
-absl::optional<int64_t> ValueToInt64(const Value* value) {
-  return value ? ValueToInt64(*value) : absl::nullopt;
+std::optional<int64_t> ValueToInt64(const Value* value) {
+  return value ? ValueToInt64(*value) : std::nullopt;
 }
 
-absl::optional<int64_t> ValueToInt64(const Value& value) {
+std::optional<int64_t> ValueToInt64(const Value& value) {
   if (!value.is_string())
-    return absl::nullopt;
+    return std::nullopt;
 
   int64_t integer;
   if (!StringToInt64(value.GetString(), &integer))
-    return absl::nullopt;
+    return std::nullopt;
 
   return integer;
 }
@@ -55,14 +56,14 @@
   return Int64ToValue(time_delta.InMicroseconds());
 }
 
-absl::optional<TimeDelta> ValueToTimeDelta(const Value* value) {
-  return value ? ValueToTimeDelta(*value) : absl::nullopt;
+std::optional<TimeDelta> ValueToTimeDelta(const Value* value) {
+  return value ? ValueToTimeDelta(*value) : std::nullopt;
 }
 
-absl::optional<TimeDelta> ValueToTimeDelta(const Value& value) {
-  absl::optional<int64_t> integer = ValueToInt64(value);
+std::optional<TimeDelta> ValueToTimeDelta(const Value& value) {
+  std::optional<int64_t> integer = ValueToInt64(value);
   if (!integer)
-    return absl::nullopt;
+    return std::nullopt;
   return Microseconds(*integer);
 }
 
@@ -70,14 +71,14 @@
   return TimeDeltaToValue(time.ToDeltaSinceWindowsEpoch());
 }
 
-absl::optional<Time> ValueToTime(const Value* value) {
-  return value ? ValueToTime(*value) : absl::nullopt;
+std::optional<Time> ValueToTime(const Value* value) {
+  return value ? ValueToTime(*value) : std::nullopt;
 }
 
-absl::optional<Time> ValueToTime(const Value& value) {
-  absl::optional<TimeDelta> time_delta = ValueToTimeDelta(value);
+std::optional<Time> ValueToTime(const Value& value) {
+  std::optional<TimeDelta> time_delta = ValueToTimeDelta(value);
   if (!time_delta)
-    return absl::nullopt;
+    return std::nullopt;
   return Time::FromDeltaSinceWindowsEpoch(*time_delta);
 }
 
@@ -85,13 +86,13 @@
   return Value(file_path.AsUTF8Unsafe());
 }
 
-absl::optional<FilePath> ValueToFilePath(const Value* value) {
-  return value ? ValueToFilePath(*value) : absl::nullopt;
+std::optional<FilePath> ValueToFilePath(const Value* value) {
+  return value ? ValueToFilePath(*value) : std::nullopt;
 }
 
-absl::optional<FilePath> ValueToFilePath(const Value& value) {
+std::optional<FilePath> ValueToFilePath(const Value& value) {
   if (!value.is_string())
-    return absl::nullopt;
+    return std::nullopt;
   return FilePath::FromUTF8Unsafe(value.GetString());
 }
 
@@ -102,20 +103,20 @@
   return Value(HexEncode(repr.buffer, sizeof(repr.buffer)));
 }
 
-absl::optional<UnguessableToken> ValueToUnguessableToken(const Value* value) {
-  return value ? ValueToUnguessableToken(*value) : absl::nullopt;
+std::optional<UnguessableToken> ValueToUnguessableToken(const Value* value) {
+  return value ? ValueToUnguessableToken(*value) : std::nullopt;
 }
 
-absl::optional<UnguessableToken> ValueToUnguessableToken(const Value& value) {
+std::optional<UnguessableToken> ValueToUnguessableToken(const Value& value) {
   if (!value.is_string())
-    return absl::nullopt;
+    return std::nullopt;
   UnguessableTokenRepresentation repr;
   if (!HexStringToSpan(value.GetString(), repr.buffer))
-    return absl::nullopt;
-  absl::optional<base::UnguessableToken> token =
+    return std::nullopt;
+  std::optional<base::UnguessableToken> token =
       UnguessableToken::Deserialize(repr.field.high, repr.field.low);
   if (!token.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return token;
 }
diff --git a/base/json/values_util.h b/base/json/values_util.h
index 2c3722d..6fe4d155 100644
--- a/base/json/values_util.h
+++ b/base/json/values_util.h
@@ -5,9 +5,10 @@
 #ifndef BASE_JSON_VALUES_UTIL_H_
 #define BASE_JSON_VALUES_UTIL_H_
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class FilePath;
@@ -20,39 +21,39 @@
 // e.g. as JSON on disk.
 //
 // It is valid to pass nullptr to the ValueToEtc functions. They will just
-// return absl::nullopt.
+// return std::nullopt.
 
 // Converts between an int64_t and a string-flavored Value (a human
 // readable string of that number).
 BASE_EXPORT Value Int64ToValue(int64_t integer);
-BASE_EXPORT absl::optional<int64_t> ValueToInt64(const Value* value);
-BASE_EXPORT absl::optional<int64_t> ValueToInt64(const Value& value);
+BASE_EXPORT std::optional<int64_t> ValueToInt64(const Value* value);
+BASE_EXPORT std::optional<int64_t> ValueToInt64(const Value& value);
 
 // Converts between a TimeDelta (an int64_t number of microseconds) and a
 // string-flavored Value (a human readable string of that number).
 BASE_EXPORT Value TimeDeltaToValue(TimeDelta time_delta);
-BASE_EXPORT absl::optional<TimeDelta> ValueToTimeDelta(const Value* value);
-BASE_EXPORT absl::optional<TimeDelta> ValueToTimeDelta(const Value& value);
+BASE_EXPORT std::optional<TimeDelta> ValueToTimeDelta(const Value* value);
+BASE_EXPORT std::optional<TimeDelta> ValueToTimeDelta(const Value& value);
 
 // Converts between a Time (an int64_t number of microseconds since the
 // Windows epoch) and a string-flavored Value (a human readable string of
 // that number).
 BASE_EXPORT Value TimeToValue(Time time);
-BASE_EXPORT absl::optional<Time> ValueToTime(const Value* value);
-BASE_EXPORT absl::optional<Time> ValueToTime(const Value& value);
+BASE_EXPORT std::optional<Time> ValueToTime(const Value* value);
+BASE_EXPORT std::optional<Time> ValueToTime(const Value& value);
 
 // Converts between a FilePath (a std::string or std::u16string) and a
 // string-flavored Value (the UTF-8 representation).
 BASE_EXPORT Value FilePathToValue(FilePath file_path);
-BASE_EXPORT absl::optional<FilePath> ValueToFilePath(const Value* value);
-BASE_EXPORT absl::optional<FilePath> ValueToFilePath(const Value& value);
+BASE_EXPORT std::optional<FilePath> ValueToFilePath(const Value* value);
+BASE_EXPORT std::optional<FilePath> ValueToFilePath(const Value& value);
 
 // Converts between a UnguessableToken (128 bits) and a string-flavored
 // Value (32 hexadecimal digits).
 BASE_EXPORT Value UnguessableTokenToValue(UnguessableToken token);
-BASE_EXPORT absl::optional<UnguessableToken> ValueToUnguessableToken(
+BASE_EXPORT std::optional<UnguessableToken> ValueToUnguessableToken(
     const Value* value);
-BASE_EXPORT absl::optional<UnguessableToken> ValueToUnguessableToken(
+BASE_EXPORT std::optional<UnguessableToken> ValueToUnguessableToken(
     const Value& value);
 
 }  // namespace base
diff --git a/base/logging_unittest.cc b/base/logging_unittest.cc
index d7e3e6b..5857f3f 100644
--- a/base/logging_unittest.cc
+++ b/base/logging_unittest.cc
@@ -52,7 +52,7 @@
 #include <zircon/types.h>
 #endif  // BUILDFLAG(IS_FUCHSIA)
 
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include <optional>
 
 namespace logging {
 
diff --git a/base/memory/platform_shared_memory_mapper.h b/base/memory/platform_shared_memory_mapper.h
index 3e461d44..4135085c 100644
--- a/base/memory/platform_shared_memory_mapper.h
+++ b/base/memory/platform_shared_memory_mapper.h
@@ -15,10 +15,10 @@
 // address space of the process.
 class PlatformSharedMemoryMapper : public SharedMemoryMapper {
  public:
-  absl::optional<span<uint8_t>> Map(subtle::PlatformSharedMemoryHandle handle,
-                                    bool write_allowed,
-                                    uint64_t offset,
-                                    size_t size) override;
+  std::optional<span<uint8_t>> Map(subtle::PlatformSharedMemoryHandle handle,
+                                   bool write_allowed,
+                                   uint64_t offset,
+                                   size_t size) override;
 
   void Unmap(span<uint8_t> mapping) override;
 };
diff --git a/base/memory/platform_shared_memory_mapper_android.cc b/base/memory/platform_shared_memory_mapper_android.cc
index 858251b..3e5370f2 100644
--- a/base/memory/platform_shared_memory_mapper_android.cc
+++ b/base/memory/platform_shared_memory_mapper_android.cc
@@ -11,7 +11,7 @@
 
 namespace base {
 
-absl::optional<span<uint8_t>> PlatformSharedMemoryMapper::Map(
+std::optional<span<uint8_t>> PlatformSharedMemoryMapper::Map(
     subtle::PlatformSharedMemoryHandle handle,
     bool write_allowed,
     uint64_t offset,
@@ -25,7 +25,7 @@
 
   if (address == MAP_FAILED) {
     DPLOG(ERROR) << "mmap " << handle << " failed";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return make_span(static_cast<uint8_t*>(address), size);
diff --git a/base/memory/platform_shared_memory_mapper_apple.cc b/base/memory/platform_shared_memory_mapper_apple.cc
index 1f44c1e..39dafe6 100644
--- a/base/memory/platform_shared_memory_mapper_apple.cc
+++ b/base/memory/platform_shared_memory_mapper_apple.cc
@@ -11,7 +11,7 @@
 
 namespace base {
 
-absl::optional<span<uint8_t>> PlatformSharedMemoryMapper::Map(
+std::optional<span<uint8_t>> PlatformSharedMemoryMapper::Map(
     subtle::PlatformSharedMemoryHandle handle,
     bool write_allowed,
     uint64_t offset,
@@ -29,7 +29,7 @@
                             VM_INHERIT_NONE);
   if (kr != KERN_SUCCESS) {
     MACH_DLOG(ERROR, kr) << "vm_map";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return make_span(reinterpret_cast<uint8_t*>(address), size);
diff --git a/base/memory/platform_shared_memory_mapper_fuchsia.cc b/base/memory/platform_shared_memory_mapper_fuchsia.cc
index 357b3b3..8925593 100644
--- a/base/memory/platform_shared_memory_mapper_fuchsia.cc
+++ b/base/memory/platform_shared_memory_mapper_fuchsia.cc
@@ -11,7 +11,7 @@
 
 namespace base {
 
-absl::optional<span<uint8_t>> PlatformSharedMemoryMapper::Map(
+std::optional<span<uint8_t>> PlatformSharedMemoryMapper::Map(
     subtle::PlatformSharedMemoryHandle handle,
     bool write_allowed,
     uint64_t offset,
@@ -24,7 +24,7 @@
                                                   *handle, offset, size, &addr);
   if (status != ZX_OK) {
     ZX_DLOG(ERROR, status) << "zx_vmar_map";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return make_span(reinterpret_cast<uint8_t*>(addr), size);
diff --git a/base/memory/platform_shared_memory_mapper_posix.cc b/base/memory/platform_shared_memory_mapper_posix.cc
index 04aca9d..a4a2a8e 100644
--- a/base/memory/platform_shared_memory_mapper_posix.cc
+++ b/base/memory/platform_shared_memory_mapper_posix.cc
@@ -11,7 +11,7 @@
 
 namespace base {
 
-absl::optional<span<uint8_t>> PlatformSharedMemoryMapper::Map(
+std::optional<span<uint8_t>> PlatformSharedMemoryMapper::Map(
     subtle::PlatformSharedMemoryHandle handle,
     bool write_allowed,
     uint64_t offset,
@@ -22,7 +22,7 @@
 
   if (address == MAP_FAILED) {
     DPLOG(ERROR) << "mmap " << handle.fd << " failed";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return make_span(static_cast<uint8_t*>(address), size);
diff --git a/base/memory/platform_shared_memory_mapper_win.cc b/base/memory/platform_shared_memory_mapper_win.cc
index c277bcc..e7b125fd 100644
--- a/base/memory/platform_shared_memory_mapper_win.cc
+++ b/base/memory/platform_shared_memory_mapper_win.cc
@@ -23,7 +23,7 @@
 }
 }  // namespace
 
-absl::optional<span<uint8_t>> PlatformSharedMemoryMapper::Map(
+std::optional<span<uint8_t>> PlatformSharedMemoryMapper::Map(
     subtle::PlatformSharedMemoryHandle handle,
     bool write_allowed,
     uint64_t offset,
@@ -41,7 +41,7 @@
   }
   if (!address) {
     DPLOG(ERROR) << "Failed executing MapViewOfFile";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return make_span(static_cast<uint8_t*>(address),
diff --git a/base/memory/platform_shared_memory_region.cc b/base/memory/platform_shared_memory_region.cc
index 19691c6..884b4e4 100644
--- a/base/memory/platform_shared_memory_region.cc
+++ b/base/memory/platform_shared_memory_region.cc
@@ -39,26 +39,26 @@
   return std::move(handle_);
 }
 
-absl::optional<span<uint8_t>> PlatformSharedMemoryRegion::MapAt(
+std::optional<span<uint8_t>> PlatformSharedMemoryRegion::MapAt(
     uint64_t offset,
     size_t size,
     SharedMemoryMapper* mapper) const {
   if (!IsValid())
-    return absl::nullopt;
+    return std::nullopt;
 
   if (size == 0)
-    return absl::nullopt;
+    return std::nullopt;
 
   size_t end_byte;
   if (!CheckAdd(offset, size).AssignIfValid(&end_byte) || end_byte > size_) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // TODO(dcheng): Presumably the actual size of the mapping is rounded to
   // `SysInfo::VMAllocationGranularity()`. Should this accounting be done with
   // that in mind?
   if (!SharedMemorySecurityPolicy::AcquireReservationForMapping(size)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (!mapper)
diff --git a/base/memory/platform_shared_memory_region.h b/base/memory/platform_shared_memory_region.h
index 0766236..191af0e 100644
--- a/base/memory/platform_shared_memory_region.h
+++ b/base/memory/platform_shared_memory_region.h
@@ -5,6 +5,10 @@
 #ifndef BASE_MEMORY_PLATFORM_SHARED_MEMORY_REGION_H_
 #define BASE_MEMORY_PLATFORM_SHARED_MEMORY_REGION_H_
 
+#include <stdint.h>
+
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/containers/span.h"
 #include "base/gtest_prod_util.h"
@@ -12,9 +16,6 @@
 #include "base/memory/shared_memory_mapper.h"
 #include "base/unguessable_token.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
-
-#include <stdint.h>
 
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 namespace content {
@@ -191,12 +192,12 @@
   // |offset| into the caller's address space using the provided
   // |SharedMemoryMapper|. |offset| must be aligned to value of
   // |SysInfo::VMAllocationGranularity()|. Fails if requested bytes are out of
-  // the region limits. Returns the mapping as span on success, or absl::nullopt
+  // the region limits. Returns the mapping as span on success, or std::nullopt
   // on failure. The mapped address is guaranteed to have an alignment of at
   // least |kMapMinimumAlignment|.
-  absl::optional<span<uint8_t>> MapAt(uint64_t offset,
-                                      size_t size,
-                                      SharedMemoryMapper* mapper) const;
+  std::optional<span<uint8_t>> MapAt(uint64_t offset,
+                                     size_t size,
+                                     SharedMemoryMapper* mapper) const;
 
   // Unmaps the provided shared memory mapping, which must have previously been
   // created by calling |MapAt()| above.
diff --git a/base/memory/ref_counted.h b/base/memory/ref_counted.h
index a7b12e7..d6667292 100644
--- a/base/memory/ref_counted.h
+++ b/base/memory/ref_counted.h
@@ -449,7 +449,7 @@
   RefCountedData(const T& in_value) : data(in_value) {}
   RefCountedData(T&& in_value) : data(std::move(in_value)) {}
   template <typename... Args>
-  explicit RefCountedData(absl::in_place_t, Args&&... args)
+  explicit RefCountedData(std::in_place_t, Args&&... args)
       : data(std::forward<Args>(args)...) {}
 
   T data;
diff --git a/base/memory/safe_ref.h b/base/memory/safe_ref.h
index 479056f..9da1d25c 100644
--- a/base/memory/safe_ref.h
+++ b/base/memory/safe_ref.h
@@ -23,7 +23,7 @@
 // benign crash instead of as a Use-after-Free.
 //
 // SafeRef pointers cannot be null (as expressed by the "Ref" suffix instead of
-// "Ptr"). A SafeRef can be wrapped in an absl::optional if it should not always
+// "Ptr"). A SafeRef can be wrapped in an std::optional if it should not always
 // point to something valid. (A SafePtr sibling type can be introduced if this
 // is problematic, or if consuming moves are needed!)
 //
diff --git a/base/memory/safe_ref_unittest.cc b/base/memory/safe_ref_unittest.cc
index 96b4574..ca5e9d5 100644
--- a/base/memory/safe_ref_unittest.cc
+++ b/base/memory/safe_ref_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "base/memory/safe_ref.h"
 
+#include <optional>
 #include <utility>
 
 #include "base/functional/bind.h"
@@ -14,7 +15,6 @@
 #include "base/test/memory/dangling_ptr_instrumentation.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace {
@@ -83,14 +83,14 @@
 }
 
 TEST(SafeRefDeathTest, ArrowOperatorCrashIfBadPointer) {
-  absl::optional<WithWeak> with(absl::in_place);
+  std::optional<WithWeak> with(std::in_place);
   SafeRef<WithWeak> safe(with->factory.GetSafeRef());
   with.reset();
   EXPECT_CHECK_DEATH(safe.operator->());  // Will crash since not live.
 }
 
 TEST(SafeRefDeathTest, StarOperatorCrashIfBadPointer) {
-  absl::optional<WithWeak> with(absl::in_place);
+  std::optional<WithWeak> with(std::in_place);
   SafeRef<WithWeak> safe(with->factory.GetSafeRef());
   with.reset();
   EXPECT_CHECK_DEATH(safe.operator*());  // Will crash since not live.
diff --git a/base/memory/shared_memory_hooks_unittest.cc b/base/memory/shared_memory_hooks_unittest.cc
index 8ea4864..b477448 100644
--- a/base/memory/shared_memory_hooks_unittest.cc
+++ b/base/memory/shared_memory_hooks_unittest.cc
@@ -4,8 +4,9 @@
 
 #include "base/memory/shared_memory_hooks.h"
 
+#include <optional>
+
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -22,9 +23,9 @@
   }
 };
 
-absl::optional<size_t> requested_read_only_shmem_size;
-absl::optional<size_t> requested_unsafe_shmem_size;
-absl::optional<size_t> requested_writable_shmem_size;
+std::optional<size_t> requested_read_only_shmem_size;
+std::optional<size_t> requested_unsafe_shmem_size;
+std::optional<size_t> requested_writable_shmem_size;
 
 MappedReadOnlyRegion ReadOnlyShmemCreateHook(size_t size, SharedMemoryMapper* mapper) {
   requested_read_only_shmem_size = size;
diff --git a/base/memory/shared_memory_mapper.h b/base/memory/shared_memory_mapper.h
index ab45f370..39fb1fa87 100644
--- a/base/memory/shared_memory_mapper.h
+++ b/base/memory/shared_memory_mapper.h
@@ -5,12 +5,13 @@
 #ifndef BASE_MEMORY_SHARED_MEMORY_MAPPER_H_
 #define BASE_MEMORY_SHARED_MEMORY_MAPPER_H_
 
+#include <stdint.h>
+
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/containers/span.h"
 #include "base/memory/platform_shared_memory_handle.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
-
-#include <stdint.h>
 
 namespace base {
 
@@ -28,7 +29,7 @@
 
   // Maps the shared memory region identified through the provided platform
   // handle into the caller's address space.
-  virtual absl::optional<span<uint8_t>> Map(
+  virtual std::optional<span<uint8_t>> Map(
       subtle::PlatformSharedMemoryHandle handle,
       bool write_allowed,
       uint64_t offset,
diff --git a/base/memory/shared_memory_security_policy.cc b/base/memory/shared_memory_security_policy.cc
index 57d193b..915eb200 100644
--- a/base/memory/shared_memory_security_policy.cc
+++ b/base/memory/shared_memory_security_policy.cc
@@ -7,12 +7,12 @@
 #include <algorithm>
 #include <atomic>
 #include <limits>
+#include <optional>
 
 #include "base/bits.h"
 #include "base/memory/page_size.h"
 #include "base/numerics/checked_math.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -31,7 +31,7 @@
 
 static std::atomic_size_t total_mapped_size_;
 
-absl::optional<size_t> AlignWithPageSize(size_t size) {
+std::optional<size_t> AlignWithPageSize(size_t size) {
 #if BUILDFLAG(IS_WIN)
   // TODO(crbug.com/210609): Matches alignment requirements defined in
   // platform_shared_memory_region_win.cc:PlatformSharedMemoryRegion::Create.
@@ -45,7 +45,7 @@
 
   // Fail on overflow.
   if (rounded_size < size)
-    return absl::nullopt;
+    return std::nullopt;
 
   return rounded_size;
 }
@@ -58,7 +58,7 @@
       total_mapped_size_.load(std::memory_order_relaxed);
   size_t total_mapped_size;
 
-  absl::optional<size_t> page_aligned_size = AlignWithPageSize(size);
+  std::optional<size_t> page_aligned_size = AlignWithPageSize(size);
 
   if (!page_aligned_size)
     return false;
@@ -86,7 +86,7 @@
   // that's required.
   // Note #2: |size| should never overflow when aligned to page size, since
   // this should only be called if AcquireReservationForMapping() returned true.
-  absl::optional<size_t> page_aligned_size = AlignWithPageSize(size);
+  std::optional<size_t> page_aligned_size = AlignWithPageSize(size);
   total_mapped_size_.fetch_sub(*page_aligned_size, std::memory_order_relaxed);
 }
 
diff --git a/base/memory/shared_memory_tracker.cc b/base/memory/shared_memory_tracker.cc
index d1a87dd..91387ecde 100644
--- a/base/memory/shared_memory_tracker.cc
+++ b/base/memory/shared_memory_tracker.cc
@@ -11,9 +11,10 @@
 #include "base/tracing_buildflags.h"
 
 #if BUILDFLAG(ENABLE_BASE_TRACING)
+#include <optional>
+
 #include "base/trace_event/memory_dump_manager.h"  // no-presubmit-check
 #include "base/trace_event/process_memory_dump.h"  // no-presubmit-check
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
 
 namespace base {
@@ -107,7 +108,7 @@
   // If resident size is not available, a virtual size is used as fallback.
   size_t size = virtual_size;
 #if defined(COUNT_RESIDENT_BYTES_SUPPORTED)
-  absl::optional<size_t> resident_size =
+  std::optional<size_t> resident_size =
       trace_event::ProcessMemoryDump::CountResidentBytesInSharedMemory(
           mapped_memory, mapped_size);
   if (resident_size.has_value())
diff --git a/base/message_loop/message_pump_android.h b/base/message_loop/message_pump_android.h
index fd48075b7..415b05ee 100644
--- a/base/message_loop/message_pump_android.h
+++ b/base/message_loop/message_pump_android.h
@@ -6,7 +6,9 @@
 #define BASE_MESSAGE_LOOP_MESSAGE_PUMP_ANDROID_H_
 
 #include <jni.h>
+
 #include <memory>
+#include <optional>
 
 #include "base/android/scoped_java_ref.h"
 #include "base/base_export.h"
@@ -15,7 +17,6 @@
 #include "base/memory/raw_ptr.h"
 #include "base/message_loop/message_pump.h"
 #include "base/time/time.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 struct ALooper;
 
@@ -91,7 +92,7 @@
   // delayed task. This avoids redundantly scheduling |delayed_fd_| with the
   // same timeout when subsequent work phases all go idle on the same pending
   // delayed task; nullopt if no wakeup is currently scheduled.
-  absl::optional<TimeTicks> delayed_scheduled_time_;
+  std::optional<TimeTicks> delayed_scheduled_time_;
 
   // If set, a callback to fire when the message pump is quit.
   base::OnceClosure on_quit_callback_;
diff --git a/base/message_loop/message_pump_apple.h b/base/message_loop/message_pump_apple.h
index 2fe5b55..00c6435 100644
--- a/base/message_loop/message_pump_apple.h
+++ b/base/message_loop/message_pump_apple.h
@@ -30,18 +30,17 @@
 #ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_APPLE_H_
 #define BASE_MESSAGE_LOOP_MESSAGE_PUMP_APPLE_H_
 
-#include "base/message_loop/message_pump.h"
-
 #include <CoreFoundation/CoreFoundation.h>
 
 #include <memory>
+#include <optional>
 
 #include "base/apple/scoped_cftyperef.h"
 #include "base/containers/stack.h"
 #include "base/memory/raw_ptr.h"
+#include "base/message_loop/message_pump.h"
 #include "base/run_loop.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if defined(__OBJC__)
 #if BUILDFLAG(IS_IOS)
@@ -273,7 +272,7 @@
   // determined the loop is not processing a native event but the depth of the
   // stack should match |nesting_level_| at all times. A nullopt is also used
   // as a stand-in during delegateless operation.
-  base::stack<absl::optional<base::MessagePump::Delegate::ScopedDoWorkItem>>
+  base::stack<std::optional<base::MessagePump::Delegate::ScopedDoWorkItem>>
       stack_;
 };
 
@@ -340,7 +339,7 @@
   void Detach() override;
 
  private:
-  absl::optional<RunLoop> run_loop_;
+  std::optional<RunLoop> run_loop_;
 };
 
 #else
diff --git a/base/message_loop/message_pump_apple.mm b/base/message_loop/message_pump_apple.mm
index c599875..5e9d5f08 100644
--- a/base/message_loop/message_pump_apple.mm
+++ b/base/message_loop/message_pump_apple.mm
@@ -9,6 +9,7 @@
 #include <atomic>
 #include <limits>
 #include <memory>
+#include <optional>
 
 #include "base/apple/call_with_eh_frame.h"
 #include "base/apple/scoped_cftyperef.h"
@@ -26,7 +27,6 @@
 #include "base/threading/platform_thread.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if !BUILDFLAG(IS_IOS)
 #import <AppKit/AppKit.h>
@@ -78,7 +78,7 @@
   OptionalAutoreleasePool& operator=(const OptionalAutoreleasePool&) = delete;
 
  private:
-  absl::optional<base::apple::ScopedNSAutoreleasePool> pool_;
+  std::optional<base::apple::ScopedNSAutoreleasePool> pool_;
 };
 
 class MessagePumpCFRunLoopBase::ScopedModeEnabler {
@@ -385,7 +385,7 @@
   if (delegate_) {
     stack_.push(delegate_->BeginWorkItem());
   } else {
-    stack_.push(absl::nullopt);
+    stack_.push(std::nullopt);
   }
 }
 
diff --git a/base/message_loop/message_pump_epoll.cc b/base/message_loop/message_pump_epoll.cc
index 1c5a74d..52b9a41 100644
--- a/base/message_loop/message_pump_epoll.cc
+++ b/base/message_loop/message_pump_epoll.cc
@@ -10,6 +10,7 @@
 
 #include <cstddef>
 #include <cstdint>
+#include <optional>
 #include <utility>
 
 #include "base/auto_reset.h"
@@ -21,7 +22,6 @@
 #include "base/ranges/algorithm.h"
 #include "base/threading/thread_checker.h"
 #include "base/trace_event/base_tracing.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
diff --git a/base/message_loop/message_pump_glib.cc b/base/message_loop/message_pump_glib.cc
index d78c99a3..b0c8fadf 100644
--- a/base/message_loop/message_pump_glib.cc
+++ b/base/message_loop/message_pump_glib.cc
@@ -368,7 +368,7 @@
   // g_main_context_iteration() in Run(). nullopt if Run() is not calling
   // g_main_context_iteration(). Used to track whether the pump has forced a
   // nested state due to a native pump.
-  absl::optional<int> g_depth_on_iteration;
+  std::optional<int> g_depth_on_iteration;
 
   // Used to keep track of the native event work items processed by the message
   // pump.
diff --git a/base/message_loop/message_pump_win.h b/base/message_loop/message_pump_win.h
index 5ef2373..077d92f 100644
--- a/base/message_loop/message_pump_win.h
+++ b/base/message_loop/message_pump_win.h
@@ -9,6 +9,7 @@
 
 #include <atomic>
 #include <memory>
+#include <optional>
 
 #include "base/base_export.h"
 #include "base/compiler_specific.h"
@@ -20,7 +21,6 @@
 #include "base/time/time.h"
 #include "base/win/message_window.h"
 #include "base/win/scoped_handle.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -168,7 +168,7 @@
   // Non-nullopt if there's currently a native timer installed. If so, it
   // indicates when the timer is set to fire and can be used to avoid setting
   // redundant timers.
-  absl::optional<TimeTicks> installed_native_timer_;
+  std::optional<TimeTicks> installed_native_timer_;
 
   // This will become true when a native loop takes our kMsgHaveWork out of the
   // system queue. It will be reset to false whenever DoRunLoop regains control.
diff --git a/base/metrics/field_trial_params.cc b/base/metrics/field_trial_params.cc
index 2041180..78d14dc 100644
--- a/base/metrics/field_trial_params.cc
+++ b/base/metrics/field_trial_params.cc
@@ -4,6 +4,7 @@
 
 #include "base/metrics/field_trial_params.h"
 
+#include <optional>
 #include <set>
 #include <utility>
 #include <vector>
@@ -21,7 +22,6 @@
 #include "base/strings/string_split.h"
 #include "base/strings/stringprintf.h"
 #include "base/time/time_delta_from_string.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -214,7 +214,7 @@
   if (value_as_string.empty())
     return default_value;
 
-  absl::optional<base::TimeDelta> ret = TimeDeltaFromString(value_as_string);
+  std::optional<base::TimeDelta> ret = TimeDeltaFromString(value_as_string);
   if (!ret.has_value()) {
     LogInvalidValue(feature, "a base::TimeDelta", param_name, value_as_string,
                     base::NumberToString(default_value.InSecondsF()) + " s");
diff --git a/base/metrics/histogram_shared_memory.cc b/base/metrics/histogram_shared_memory.cc
index f4afd00..6d02d01 100644
--- a/base/metrics/histogram_shared_memory.cc
+++ b/base/metrics/histogram_shared_memory.cc
@@ -94,18 +94,18 @@
     HistogramSharedMemory::SharedMemory&&) = default;
 
 // static
-absl::optional<HistogramSharedMemory::SharedMemory>
+std::optional<HistogramSharedMemory::SharedMemory>
 HistogramSharedMemory::Create(int process_id,
                               const HistogramSharedMemory::Config& config) {
   auto region = UnsafeSharedMemoryRegion::Create(config.memory_size_bytes);
   if (!region.IsValid()) {
     DVLOG(1) << "Failed to create shared memory region.";
-    return absl::nullopt;
+    return std::nullopt;
   }
   auto mapping = region.Map();
   if (!mapping.IsValid()) {
     DVLOG(1) << "Failed to create shared memory mapping.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return SharedMemory{std::move(region),
diff --git a/base/metrics/histogram_shared_memory.h b/base/metrics/histogram_shared_memory.h
index 56b6089..88f39fa6 100644
--- a/base/metrics/histogram_shared_memory.h
+++ b/base/metrics/histogram_shared_memory.h
@@ -5,6 +5,7 @@
 #ifndef BASE_METRICS_HISTOGRAM_SHARED_MEMORY_H_
 #define BASE_METRICS_HISTOGRAM_SHARED_MEMORY_H_
 
+#include <optional>
 #include <string_view>
 
 #include "base/base_export.h"
@@ -14,7 +15,6 @@
 #include "base/metrics/persistent_memory_allocator.h"
 #include "base/process/launch.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_APPLE)
 #include "base/files/platform_file.h"
@@ -76,8 +76,8 @@
   // |process_id| based on |config|. On success, returns true and updates
   // the values of |memory_region| and |allocator|. On failure, returns false
   // and |memory_region| and |allocator| are unchanged.
-  static absl::optional<SharedMemory> Create(int process_id,
-                                             const Config& config);
+  static std::optional<SharedMemory> Create(int process_id,
+                                            const Config& config);
 
 #if BUILDFLAG(IS_APPLE)
   // Exposed for testing.
diff --git a/base/metrics/histogram_unittest.cc b/base/metrics/histogram_unittest.cc
index cf96563..c748b109 100644
--- a/base/metrics/histogram_unittest.cc
+++ b/base/metrics/histogram_unittest.cc
@@ -1021,16 +1021,16 @@
   // Check the first bucket.
   const base::Value::Dict* bucket1 = buckets_list[0].GetIfDict();
   ASSERT_TRUE(bucket1 != nullptr);
-  EXPECT_EQ(bucket1->FindInt("low"), absl::optional<int>(20));
-  EXPECT_EQ(bucket1->FindInt("high"), absl::optional<int>(21));
-  EXPECT_EQ(bucket1->FindInt("count"), absl::optional<int>(30));
+  EXPECT_EQ(bucket1->FindInt("low"), std::optional<int>(20));
+  EXPECT_EQ(bucket1->FindInt("high"), std::optional<int>(21));
+  EXPECT_EQ(bucket1->FindInt("count"), std::optional<int>(30));
 
   // Check the second bucket.
   const base::Value::Dict* bucket2 = buckets_list[1].GetIfDict();
   ASSERT_TRUE(bucket2 != nullptr);
-  EXPECT_EQ(bucket2->FindInt("low"), absl::optional<int>(30));
-  EXPECT_EQ(bucket2->FindInt("high"), absl::optional<int>(31));
-  EXPECT_EQ(bucket2->FindInt("count"), absl::optional<int>(28));
+  EXPECT_EQ(bucket2->FindInt("low"), std::optional<int>(30));
+  EXPECT_EQ(bucket2->FindInt("high"), std::optional<int>(31));
+  EXPECT_EQ(bucket2->FindInt("count"), std::optional<int>(28));
 }
 
 TEST_P(HistogramTest, WriteAscii) {
diff --git a/base/metrics/persistent_histogram_allocator.cc b/base/metrics/persistent_histogram_allocator.cc
index 35b827f4..03d59f47 100644
--- a/base/metrics/persistent_histogram_allocator.cc
+++ b/base/metrics/persistent_histogram_allocator.cc
@@ -184,7 +184,7 @@
 std::vector<PersistentMemoryAllocator::Reference>
 PersistentSparseHistogramDataManager::LoadRecords(
     PersistentSampleMapRecords* sample_map_records,
-    absl::optional<HistogramBase::Sample> until_value) {
+    std::optional<HistogramBase::Sample> until_value) {
   // DataManager must be locked in order to access the |sample_records_|
   // vectors.
   base::AutoLock auto_lock(lock_);
@@ -262,7 +262,7 @@
 
 std::vector<PersistentMemoryAllocator::Reference>
 PersistentSampleMapRecords::GetNextRecords(
-    absl::optional<HistogramBase::Sample> until_value) {
+    std::optional<HistogramBase::Sample> until_value) {
   auto references = data_manager_->LoadRecords(this, until_value);
   seen_ += references.size();
   return references;
diff --git a/base/metrics/persistent_histogram_allocator.h b/base/metrics/persistent_histogram_allocator.h
index a611ef5..40b2afe 100644
--- a/base/metrics/persistent_histogram_allocator.h
+++ b/base/metrics/persistent_histogram_allocator.h
@@ -8,6 +8,7 @@
 #include <atomic>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -20,7 +21,6 @@
 #include "base/strings/string_piece.h"
 #include "base/synchronization/lock.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -86,7 +86,7 @@
   // |sample_map_records| has seen all its records.
   std::vector<PersistentMemoryAllocator::Reference> LoadRecords(
       PersistentSampleMapRecords* sample_map_records,
-      absl::optional<HistogramBase::Sample> until_value);
+      std::optional<HistogramBase::Sample> until_value);
 
   // Weak-pointer to the allocator used by the sparse histograms.
   raw_ptr<PersistentMemoryAllocator> allocator_;
@@ -134,7 +134,7 @@
   // vector is returned, which definitely means that |this| has seen all its
   // records.
   std::vector<PersistentMemoryAllocator::Reference> GetNextRecords(
-      absl::optional<HistogramBase::Sample> until_value);
+      std::optional<HistogramBase::Sample> until_value);
 
   // Creates a new persistent sample-map record for sample |value| and returns
   // a reference to it.
diff --git a/base/metrics/persistent_memory_allocator.cc b/base/metrics/persistent_memory_allocator.cc
index c73ecf4..09226e0 100644
--- a/base/metrics/persistent_memory_allocator.cc
+++ b/base/metrics/persistent_memory_allocator.cc
@@ -8,6 +8,7 @@
 
 #include <algorithm>
 #include <atomic>
+#include <optional>
 
 #include "base/bits.h"
 #include "base/containers/contains.h"
@@ -27,7 +28,6 @@
 #include "base/system/sys_info.h"
 #include "base/threading/scoped_blocking_call.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_WIN)
 #include <windows.h>
@@ -1209,7 +1209,7 @@
   if (IsReadonly())
     return;
 
-  absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
+  std::optional<base::ScopedBlockingCall> scoped_blocking_call;
   if (sync)
     scoped_blocking_call.emplace(FROM_HERE, base::BlockingType::MAY_BLOCK);
 
diff --git a/base/metrics/persistent_sample_map.cc b/base/metrics/persistent_sample_map.cc
index adf9367..4ff1d05c 100644
--- a/base/metrics/persistent_sample_map.cc
+++ b/base/metrics/persistent_sample_map.cc
@@ -147,7 +147,7 @@
   // Have to override "const" in order to make sure all samples have been
   // loaded before trying to iterate over the map.
   const_cast<PersistentSampleMap*>(this)->ImportSamples(
-      /*until_value=*/absl::nullopt);
+      /*until_value=*/std::nullopt);
 
   Count count = 0;
   for (const auto& entry : sample_counts_) {
@@ -160,14 +160,14 @@
   // Have to override "const" in order to make sure all samples have been
   // loaded before trying to iterate over the map.
   const_cast<PersistentSampleMap*>(this)->ImportSamples(
-      /*until_value=*/absl::nullopt);
+      /*until_value=*/std::nullopt);
   return std::make_unique<PersistentSampleMapIterator>(sample_counts_);
 }
 
 std::unique_ptr<SampleCountIterator> PersistentSampleMap::ExtractingIterator() {
   // Make sure all samples have been loaded before trying to iterate over the
   // map.
-  ImportSamples(/*until_value=*/absl::nullopt);
+  ImportSamples(/*until_value=*/std::nullopt);
   return std::make_unique<ExtractingPersistentSampleMapIterator>(
       sample_counts_);
 }
@@ -304,7 +304,7 @@
   return records_.get();
 }
 
-Count* PersistentSampleMap::ImportSamples(absl::optional<Sample> until_value) {
+Count* PersistentSampleMap::ImportSamples(std::optional<Sample> until_value) {
   std::vector<PersistentMemoryAllocator::Reference> refs;
   PersistentSampleMapRecords* records = GetRecords();
   while (!(refs = records->GetNextRecords(until_value)).empty()) {
diff --git a/base/metrics/persistent_sample_map.h b/base/metrics/persistent_sample_map.h
index d3eb4c3..fcf3b51 100644
--- a/base/metrics/persistent_sample_map.h
+++ b/base/metrics/persistent_sample_map.h
@@ -13,6 +13,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 
 #include "base/base_export.h"
 #include "base/compiler_specific.h"
@@ -20,7 +21,6 @@
 #include "base/metrics/histogram_base.h"
 #include "base/metrics/histogram_samples.h"
 #include "base/metrics/persistent_memory_allocator.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -93,7 +93,7 @@
   // |until_value| to force the importing of all available samples (null will
   // always be returned in this case).
   HistogramBase::Count* ImportSamples(
-      absl::optional<HistogramBase::Sample> until_value);
+      std::optional<HistogramBase::Sample> until_value);
 
   // All created/loaded sample values and their associated counts. The storage
   // for the actual Count numbers is owned by the |records_| object and its
diff --git a/base/metrics/sparse_histogram_unittest.cc b/base/metrics/sparse_histogram_unittest.cc
index 835f8af3..572c3c7 100644
--- a/base/metrics/sparse_histogram_unittest.cc
+++ b/base/metrics/sparse_histogram_unittest.cc
@@ -487,16 +487,16 @@
   // Check the first bucket.
   const base::Value::Dict* bucket1 = buckets_list[0].GetIfDict();
   ASSERT_TRUE(bucket1 != nullptr);
-  EXPECT_EQ(bucket1->FindInt("low"), absl::optional<int>(100));
-  EXPECT_EQ(bucket1->FindInt("high"), absl::optional<int>(101));
-  EXPECT_EQ(bucket1->FindInt("count"), absl::optional<int>(10));
+  EXPECT_EQ(bucket1->FindInt("low"), std::optional<int>(100));
+  EXPECT_EQ(bucket1->FindInt("high"), std::optional<int>(101));
+  EXPECT_EQ(bucket1->FindInt("count"), std::optional<int>(10));
 
   // Check the second bucket.
   const base::Value::Dict* bucket2 = buckets_list[1].GetIfDict();
   ASSERT_TRUE(bucket2 != nullptr);
-  EXPECT_EQ(bucket2->FindInt("low"), absl::optional<int>(200));
-  EXPECT_EQ(bucket2->FindInt("high"), absl::optional<int>(201));
-  EXPECT_EQ(bucket2->FindInt("count"), absl::optional<int>(15));
+  EXPECT_EQ(bucket2->FindInt("low"), std::optional<int>(200));
+  EXPECT_EQ(bucket2->FindInt("high"), std::optional<int>(201));
+  EXPECT_EQ(bucket2->FindInt("count"), std::optional<int>(15));
 }
 
 TEST_P(SparseHistogramTest, WriteAscii) {
diff --git a/base/metrics/statistics_recorder_unittest.cc b/base/metrics/statistics_recorder_unittest.cc
index 0f8f993..91813830 100644
--- a/base/metrics/statistics_recorder_unittest.cc
+++ b/base/metrics/statistics_recorder_unittest.cc
@@ -7,6 +7,7 @@
 #include <stddef.h>
 
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -24,7 +25,6 @@
 #include "base/values.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -364,7 +364,7 @@
   std::string json(StatisticsRecorder::ToJSON(JSON_VERBOSITY_LEVEL_FULL));
 
   // Check for valid JSON.
-  absl::optional<Value> root = JSONReader::Read(json);
+  std::optional<Value> root = JSONReader::Read(json);
   ASSERT_TRUE(root);
   Value::Dict* root_dict = root->GetIfDict();
   ASSERT_TRUE(root_dict);
@@ -403,7 +403,7 @@
 
   std::string json =
       StatisticsRecorder::ToJSON(JSON_VERBOSITY_LEVEL_OMIT_BUCKETS);
-  absl::optional<Value> root = JSONReader::Read(json);
+  std::optional<Value> root = JSONReader::Read(json);
   ASSERT_TRUE(root);
   Value::Dict* root_dict = root->GetIfDict();
   ASSERT_TRUE(root_dict);
diff --git a/base/observer_list_threadsafe_unittest.cc b/base/observer_list_threadsafe_unittest.cc
index f236b22..1145a83 100644
--- a/base/observer_list_threadsafe_unittest.cc
+++ b/base/observer_list_threadsafe_unittest.cc
@@ -5,6 +5,7 @@
 #include "base/observer_list_threadsafe.h"
 
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -28,7 +29,6 @@
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace {
@@ -369,7 +369,7 @@
 }
 
 TEST(ObserverListThreadSafeTest, OutlivesTaskEnvironment) {
-  absl::optional<test::TaskEnvironment> task_environment(absl::in_place);
+  std::optional<test::TaskEnvironment> task_environment(std::in_place);
   auto observer_list = base::MakeRefCounted<ObserverListThreadSafe<Foo>>();
 
   Adder a(1);
@@ -381,7 +381,7 @@
 }
 
 TEST(ObserverListThreadSafeTest, OutlivesTaskEnvironmentRemovalRestricted) {
-  absl::optional<test::TaskEnvironment> task_environment(absl::in_place);
+  std::optional<test::TaskEnvironment> task_environment(std::in_place);
   auto observer_list = base::MakeRefCounted<
       ObserverListThreadSafe<Foo, RemoveObserverPolicy::kAddingSequenceOnly>>();
 
diff --git a/base/observer_list_unittest.cc b/base/observer_list_unittest.cc
index d75b7d9..325f186 100644
--- a/base/observer_list_unittest.cc
+++ b/base/observer_list_unittest.cc
@@ -5,6 +5,7 @@
 #include "base/observer_list.h"
 
 #include <memory>
+#include <optional>
 
 #include "base/memory/raw_ptr.h"
 #include "base/strings/string_piece.h"
@@ -13,7 +14,6 @@
 #include "build/build_config.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace {
@@ -122,7 +122,7 @@
 class ObserverListCreator : public DelegateSimpleThread::Delegate {
  public:
   std::unique_ptr<ObserverListType> Create(
-      absl::optional<base::ObserverListPolicy> policy = absl::nullopt) {
+      std::optional<base::ObserverListPolicy> policy = std::nullopt) {
     policy_ = policy;
     DelegateSimpleThread thread(this, "ListCreator");
     thread.Start();
@@ -140,7 +140,7 @@
   }
 
   std::unique_ptr<ObserverListType> observer_list_;
-  absl::optional<base::ObserverListPolicy> policy_;
+  std::optional<base::ObserverListPolicy> policy_;
 };
 
 }  // namespace
diff --git a/base/pickle.cc b/base/pickle.cc
index 711775e..f249a5f 100644
--- a/base/pickle.cc
+++ b/base/pickle.cc
@@ -206,12 +206,12 @@
   return ReadBytes(data, *length);
 }
 
-absl::optional<base::span<const uint8_t>> PickleIterator::ReadData() {
+std::optional<base::span<const uint8_t>> PickleIterator::ReadData() {
   const char* ptr;
   size_t length;
 
   if (!ReadData(&ptr, &length))
-    return absl::nullopt;
+    return std::nullopt;
 
   return base::as_bytes(base::make_span(ptr, length));
 }
diff --git a/base/pickle.h b/base/pickle.h
index 79807b36..d990e58 100644
--- a/base/pickle.h
+++ b/base/pickle.h
@@ -8,6 +8,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <string_view>
 
@@ -18,7 +19,6 @@
 #include "base/memory/raw_ptr_exclusion.h"
 #include "base/memory/ref_counted.h"
 #include "base/strings/string_piece.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -59,7 +59,7 @@
   [[nodiscard]] bool ReadData(const char** data, size_t* length);
 
   // Similar, but using base::span for convenience.
-  [[nodiscard]] absl::optional<base::span<const uint8_t>> ReadData();
+  [[nodiscard]] std::optional<base::span<const uint8_t>> ReadData();
 
   // A pointer to the data will be placed in |*data|. The caller specifies the
   // number of bytes to read, and ReadBytes will validate this length. The
diff --git a/base/posix/sysctl.cc b/base/posix/sysctl.cc
index a6f6d0d..02c65fb 100644
--- a/base/posix/sysctl.cc
+++ b/base/posix/sysctl.cc
@@ -7,28 +7,28 @@
 #include <sys/sysctl.h>
 
 #include <initializer_list>
+#include <optional>
 #include <string>
 
 #include "base/check_op.h"
 #include "base/functional/function_ref.h"
 #include "base/numerics/safe_conversions.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
-absl::optional<std::string> StringSysctlImpl(
+std::optional<std::string> StringSysctlImpl(
     base::FunctionRef<int(char* /*out*/, size_t* /*out_len*/)> sysctl_func) {
   size_t buf_len;
   int result = sysctl_func(nullptr, &buf_len);
   if (result < 0 || buf_len < 1) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   std::string value(buf_len - 1, '\0');
   result = sysctl_func(&value[0], &buf_len);
   if (result < 0) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   CHECK_LE(buf_len - 1, value.size());
   CHECK_EQ(value[buf_len - 1], '\0');
@@ -40,8 +40,7 @@
 
 namespace base {
 
-absl::optional<std::string> StringSysctl(
-    const std::initializer_list<int>& mib) {
+std::optional<std::string> StringSysctl(const std::initializer_list<int>& mib) {
   return StringSysctlImpl([mib](char* out, size_t* out_len) {
     return sysctl(const_cast<int*>(std::data(mib)),
                   checked_cast<unsigned int>(std::size(mib)), out, out_len,
@@ -50,7 +49,7 @@
 }
 
 #if !BUILDFLAG(IS_OPENBSD)
-absl::optional<std::string> StringSysctlByName(const char* name) {
+std::optional<std::string> StringSysctlByName(const char* name) {
   return StringSysctlImpl([name](char* out, size_t* out_len) {
     return sysctlbyname(name, out, out_len, nullptr, 0);
   });
diff --git a/base/posix/sysctl.h b/base/posix/sysctl.h
index cb08e52..139ded2 100644
--- a/base/posix/sysctl.h
+++ b/base/posix/sysctl.h
@@ -6,11 +6,11 @@
 #define BASE_POSIX_SYSCTL_H_
 
 #include <initializer_list>
+#include <optional>
 #include <string>
 
 #include "base/base_export.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // NB: While a BSD utility file, this lives in /base/posix/ for simplicity as
 // there is no /base/bsd/.
@@ -18,13 +18,13 @@
 namespace base {
 
 // Returns the value returned by `sysctl` as a std::string, or nullopt on error.
-BASE_EXPORT absl::optional<std::string> StringSysctl(
+BASE_EXPORT std::optional<std::string> StringSysctl(
     const std::initializer_list<int>& mib);
 
 #if !BUILDFLAG(IS_OPENBSD)
 // Returns the value returned by `sysctlbyname` as a std::string, or nullopt
 // on error.
-BASE_EXPORT absl::optional<std::string> StringSysctlByName(const char* name);
+BASE_EXPORT std::optional<std::string> StringSysctlByName(const char* name);
 #endif
 
 }  // namespace base
diff --git a/base/posix/sysctl_unittest.cc b/base/posix/sysctl_unittest.cc
index c0b3690..310308a 100644
--- a/base/posix/sysctl_unittest.cc
+++ b/base/posix/sysctl_unittest.cc
@@ -16,11 +16,11 @@
 using SysctlTest = testing::Test;
 
 TEST(SysctlTest, MibSuccess) {
-  absl::optional<std::string> result1 = StringSysctl({CTL_HW, HW_MACHINE});
+  std::optional<std::string> result1 = StringSysctl({CTL_HW, HW_MACHINE});
   EXPECT_TRUE(result1);
 
 #if !BUILDFLAG(IS_OPENBSD)
-  absl::optional<std::string> result2 = StringSysctlByName("hw.machine");
+  std::optional<std::string> result2 = StringSysctlByName("hw.machine");
   EXPECT_TRUE(result2);
 
   EXPECT_EQ(result1, result2);
@@ -28,7 +28,7 @@
 }
 
 TEST(SysctlTest, MibFailure) {
-  absl::optional<std::string> result = StringSysctl({-1});
+  std::optional<std::string> result = StringSysctl({-1});
   EXPECT_FALSE(result);
 
 #if !BUILDFLAG(IS_OPENBSD)
diff --git a/base/power_monitor/battery_level_provider.h b/base/power_monitor/battery_level_provider.h
index 7c5f969..2a38ff31 100644
--- a/base/power_monitor/battery_level_provider.h
+++ b/base/power_monitor/battery_level_provider.h
@@ -6,13 +6,14 @@
 #define BASE_POWER_MONITOR_BATTERY_LEVEL_PROVIDER_H_
 
 #include <stdint.h>
+
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "base/functional/callback.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -43,18 +44,18 @@
     bool is_external_power_connected = false;
 
     // Current battery capacity. nullopt if `battery_count` != 1.
-    absl::optional<uint64_t> current_capacity;
+    std::optional<uint64_t> current_capacity;
 
     // Fully charged battery capacity. nullopt if `battery_count` != 1.
-    absl::optional<uint64_t> full_charged_capacity;
+    std::optional<uint64_t> full_charged_capacity;
 
     // The voltage of the battery. Only available on MacOS. nullopt if
     // `battery_count` != 1.
-    absl::optional<uint64_t> voltage_mv;
+    std::optional<uint64_t> voltage_mv;
 
     // The unit of the battery's charge. Usually kMWh (milliwatt-hour) but can
     // be relative on Windows. nullopt if `battery_count` != 1.
-    absl::optional<BatteryLevelUnit> charge_unit;
+    std::optional<BatteryLevelUnit> charge_unit;
 
     // The time at which the battery state capture took place.
     base::TimeTicks capture_time;
@@ -65,7 +66,7 @@
     // the current capacity, in milliwatt-hours. Only available on
     // Windows, and if a battery is present. This value is populated by the
     // manufacturer and is not guaranteed to be available or accurate.
-    absl::optional<uint32_t> battery_discharge_granularity;
+    std::optional<uint32_t> battery_discharge_granularity;
 #endif  // BUILDFLAG(IS_WIN)
   };
 
@@ -82,7 +83,7 @@
   // (forwards nullopt on retrieval error). `callback` will not be invoked if
   // the BatteryLevelProvider is destroyed.
   virtual void GetBatteryState(
-      base::OnceCallback<void(const absl::optional<BatteryState>&)>
+      base::OnceCallback<void(const std::optional<BatteryState>&)>
           callback) = 0;
 
  protected:
@@ -99,7 +100,7 @@
     uint64_t full_charged_capacity;
 
     // The voltage of the battery. Only available on MacOS.
-    absl::optional<uint64_t> voltage_mv;
+    std::optional<uint64_t> voltage_mv;
 
     // The battery's unit of charge.
     BatteryLevelUnit charge_unit;
@@ -109,13 +110,13 @@
     // percent. Only available on Windows, and if a battery is present. This
     // value is populated by the manufacturer and is not guaranteed to be
     // available or accurate.
-    absl::optional<uint32_t> battery_discharge_granularity;
+    std::optional<uint32_t> battery_discharge_granularity;
 
     // The most coarse granularity among all the reporting scales of the
     // battery, in hundredths of a percent. Only available on Windows, and if a
     // battery is present. This value is populated by the manufacturer and is
     // not guaranteed to be available or accurate.
-    absl::optional<uint32_t> max_battery_discharge_granularity;
+    std::optional<uint32_t> max_battery_discharge_granularity;
 #endif  // BUILDFLAG(IS_WIN)
   };
 
diff --git a/base/power_monitor/battery_level_provider_mac.mm b/base/power_monitor/battery_level_provider_mac.mm
index cf8390de..f30fe9be6 100644
--- a/base/power_monitor/battery_level_provider_mac.mm
+++ b/base/power_monitor/battery_level_provider_mac.mm
@@ -18,8 +18,8 @@
 // Returns the value corresponding to |key| in the dictionary |description|.
 // Returns |default_value| if the dictionary does not contain |key|, the
 // corresponding value is nullptr or it could not be converted to SInt64.
-absl::optional<SInt64> GetValueAsSInt64(CFDictionaryRef description,
-                                        CFStringRef key) {
+std::optional<SInt64> GetValueAsSInt64(CFDictionaryRef description,
+                                       CFStringRef key) {
   CFNumberRef number_ref =
       base::apple::GetValueFromDictionary<CFNumberRef>(description, key);
 
@@ -27,15 +27,15 @@
   if (number_ref && CFNumberGetValue(number_ref, kCFNumberSInt64Type, &value))
     return value;
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<bool> GetValueAsBoolean(CFDictionaryRef description,
-                                       CFStringRef key) {
+std::optional<bool> GetValueAsBoolean(CFDictionaryRef description,
+                                      CFStringRef key) {
   CFBooleanRef boolean =
       base::apple::GetValueFromDictionary<CFBooleanRef>(description, key);
   if (!boolean)
-    return absl::nullopt;
+    return std::nullopt;
   return CFBooleanGetValue(boolean);
 }
 
@@ -47,20 +47,20 @@
   ~BatteryLevelProviderMac() override = default;
 
   void GetBatteryState(
-      base::OnceCallback<void(const absl::optional<BatteryState>&)> callback)
+      base::OnceCallback<void(const std::optional<BatteryState>&)> callback)
       override {
     std::move(callback).Run(GetBatteryStateImpl());
   }
 
  private:
-  absl::optional<BatteryState> GetBatteryStateImpl();
+  std::optional<BatteryState> GetBatteryStateImpl();
 };
 
 std::unique_ptr<BatteryLevelProvider> BatteryLevelProvider::Create() {
   return std::make_unique<BatteryLevelProviderMac>();
 }
 
-absl::optional<BatteryLevelProviderMac::BatteryState>
+std::optional<BatteryLevelProviderMac::BatteryState>
 BatteryLevelProviderMac::GetBatteryStateImpl() {
   const base::mac::ScopedIOObject<io_service_t> service(
       IOServiceGetMatchingService(kIOMasterPortDefault,
@@ -78,14 +78,14 @@
 
   if (result != KERN_SUCCESS) {
     // Failing to retrieve the dictionary is unexpected.
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  absl::optional<bool> battery_installed =
+  std::optional<bool> battery_installed =
       GetValueAsBoolean(dict.get(), CFSTR("BatteryInstalled"));
   if (!battery_installed.has_value()) {
     // Failing to access the BatteryInstalled property is unexpected.
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (!battery_installed.value()) {
@@ -93,29 +93,29 @@
     return MakeBatteryState(/* battery_details=*/{});
   }
 
-  absl::optional<bool> external_connected =
+  std::optional<bool> external_connected =
       GetValueAsBoolean(dict.get(), CFSTR("ExternalConnected"));
   if (!external_connected.has_value()) {
     // Failing to access the ExternalConnected property is unexpected.
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  absl::optional<SInt64> current_capacity =
+  std::optional<SInt64> current_capacity =
       GetValueAsSInt64(dict.get(), CFSTR("AppleRawCurrentCapacity"));
   if (!current_capacity.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  absl::optional<SInt64> max_capacity =
+  std::optional<SInt64> max_capacity =
       GetValueAsSInt64(dict.get(), CFSTR("AppleRawMaxCapacity"));
   if (!max_capacity.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  absl::optional<SInt64> voltage_mv =
+  std::optional<SInt64> voltage_mv =
       GetValueAsSInt64(dict.get(), CFSTR(kIOPSVoltageKey));
   if (!voltage_mv.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   DCHECK_GE(*current_capacity, 0);
diff --git a/base/power_monitor/battery_level_provider_unittest.cc b/base/power_monitor/battery_level_provider_unittest.cc
index 9906631..252e6f3 100644
--- a/base/power_monitor/battery_level_provider_unittest.cc
+++ b/base/power_monitor/battery_level_provider_unittest.cc
@@ -68,8 +68,8 @@
                        .full_charged_capacity = 100})});
   EXPECT_EQ(2, state.battery_count);
   EXPECT_TRUE(state.is_external_power_connected);
-  EXPECT_EQ(absl::nullopt, state.current_capacity);
-  EXPECT_EQ(absl::nullopt, state.full_charged_capacity);
+  EXPECT_EQ(std::nullopt, state.current_capacity);
+  EXPECT_EQ(std::nullopt, state.full_charged_capacity);
   EXPECT_NE(base::TimeTicks(), state.capture_time);
 }
 
@@ -83,8 +83,8 @@
                        .full_charged_capacity = 100})});
   EXPECT_EQ(2, state.battery_count);
   EXPECT_FALSE(state.is_external_power_connected);
-  EXPECT_EQ(absl::nullopt, state.current_capacity);
-  EXPECT_EQ(absl::nullopt, state.full_charged_capacity);
+  EXPECT_EQ(std::nullopt, state.current_capacity);
+  EXPECT_EQ(std::nullopt, state.full_charged_capacity);
   EXPECT_NE(base::TimeTicks(), state.capture_time);
 }
 
diff --git a/base/power_monitor/battery_level_provider_win.cc b/base/power_monitor/battery_level_provider_win.cc
index 3c3a4ee7..4e0d9f6 100644
--- a/base/power_monitor/battery_level_provider_win.cc
+++ b/base/power_monitor/battery_level_provider_win.cc
@@ -68,7 +68,7 @@
 // no battery present in this interface or nullopt on retrieval error.
 // See
 // https://docs.microsoft.com/en-us/windows/win32/power/ioctl-battery-query-tag
-absl::optional<ULONG> GetBatteryTag(HANDLE battery) {
+std::optional<ULONG> GetBatteryTag(HANDLE battery) {
   ULONG battery_tag = 0;
   ULONG wait = 0;
   DWORD bytes_returned = 0;
@@ -85,7 +85,7 @@
       return battery_tag;
     }
     // Retrieval error.
-    return absl::nullopt;
+    return std::nullopt;
   }
   return battery_tag;
 }
@@ -93,8 +93,8 @@
 // Returns BATTERY_INFORMATION structure containing battery information, given
 // battery handle and tag, or nullopt if the request failed. Battery handle and
 // tag are obtained with GetBatteryHandle() and GetBatteryTag(), respectively.
-absl::optional<BATTERY_INFORMATION> GetBatteryInformation(HANDLE battery,
-                                                          ULONG battery_tag) {
+std::optional<BATTERY_INFORMATION> GetBatteryInformation(HANDLE battery,
+                                                         ULONG battery_tag) {
   BATTERY_QUERY_INFORMATION query_information = {};
   query_information.BatteryTag = battery_tag;
   query_information.InformationLevel = BatteryInformation;
@@ -105,12 +105,12 @@
       sizeof(query_information), &battery_information,
       sizeof(battery_information), &bytes_returned, nullptr);
   if (!success)
-    return absl::nullopt;
+    return std::nullopt;
   return battery_information;
 }
 
 // Returns the granularity of the battery discharge.
-absl::optional<uint32_t> GetBatteryBatteryDischargeGranularity(
+std::optional<uint32_t> GetBatteryBatteryDischargeGranularity(
     HANDLE battery,
     ULONG battery_tag,
     ULONG current_capacity,
@@ -133,12 +133,12 @@
       sizeof(query_information), &battery_reporting_scales,
       sizeof(battery_reporting_scales), &bytes_returned, nullptr);
   if (!success)
-    return absl::nullopt;
+    return std::nullopt;
 
   ptrdiff_t nb_elements = base::checked_cast<ptrdiff_t>(
       bytes_returned / sizeof(BATTERY_REPORTING_SCALE));
   if (!nb_elements)
-    return absl::nullopt;
+    return std::nullopt;
 
   // The granularities are ordered from the highest capacity to the lowest
   // capacity, or from the most coarse granularity to the most precise
@@ -165,8 +165,8 @@
 // Returns BATTERY_STATUS structure containing battery state, given battery
 // handle and tag, or nullopt if the request failed. Battery handle and tag are
 // obtained with GetBatteryHandle() and GetBatteryTag(), respectively.
-absl::optional<BATTERY_STATUS> GetBatteryStatus(HANDLE battery,
-                                                ULONG battery_tag) {
+std::optional<BATTERY_STATUS> GetBatteryStatus(HANDLE battery,
+                                               ULONG battery_tag) {
   BATTERY_WAIT_STATUS wait_status = {};
   wait_status.BatteryTag = battery_tag;
   BATTERY_STATUS battery_status;
@@ -175,7 +175,7 @@
       battery, IOCTL_BATTERY_QUERY_STATUS, &wait_status, sizeof(wait_status),
       &battery_status, sizeof(battery_status), &bytes_returned, nullptr);
   if (!success)
-    return absl::nullopt;
+    return std::nullopt;
   return battery_status;
 }
 
@@ -187,7 +187,7 @@
   ~BatteryLevelProviderWin() override = default;
 
   void GetBatteryState(
-      base::OnceCallback<void(const absl::optional<BatteryState>&)> callback)
+      base::OnceCallback<void(const std::optional<BatteryState>&)> callback)
       override {
     // This is run on |blocking_task_runner_| since `GetBatteryStateImpl()` has
     // blocking calls and can take several seconds to complete.
@@ -199,11 +199,11 @@
   }
 
  private:
-  static absl::optional<BatteryState> GetBatteryStateImpl();
+  static std::optional<BatteryState> GetBatteryStateImpl();
 
   void OnBatteryStateObtained(
-      base::OnceCallback<void(const absl::optional<BatteryState>&)> callback,
-      const absl::optional<BatteryState>& battery_state) {
+      base::OnceCallback<void(const std::optional<BatteryState>&)> callback,
+      const std::optional<BatteryState>& battery_state) {
     std::move(callback).Run(battery_state);
   }
 
@@ -222,7 +222,7 @@
 }
 
 // static
-absl::optional<BatteryLevelProvider::BatteryState>
+std::optional<BatteryLevelProvider::BatteryState>
 BatteryLevelProviderWin::GetBatteryStateImpl() {
   // Proactively mark as blocking to fail early, since calls below may also
   // trigger ScopedBlockingCall.
@@ -235,7 +235,7 @@
   base::win::ScopedDevInfo devices(::SetupDiGetClassDevs(
       &GUID_DEVICE_BATTERY, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE));
   if (!devices.is_valid()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   std::vector<BatteryDetails> battery_details_list;
@@ -256,17 +256,17 @@
       if (::GetLastError() == ERROR_NO_MORE_ITEMS)
         break;
       // Error.
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     base::win::ScopedHandle battery =
         GetBatteryHandle(devices.get(), &interface_data);
     if (!battery.IsValid())
-      return absl::nullopt;
+      return std::nullopt;
 
-    absl::optional<ULONG> battery_tag = GetBatteryTag(battery.Get());
+    std::optional<ULONG> battery_tag = GetBatteryTag(battery.Get());
     if (!battery_tag.has_value()) {
-      return absl::nullopt;
+      return std::nullopt;
     } else if (battery_tag.value() == BATTERY_TAG_INVALID) {
       // No battery present in this interface.
       continue;
@@ -275,15 +275,15 @@
     auto battery_information =
         GetBatteryInformation(battery.Get(), *battery_tag);
     if (!battery_information.has_value()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     auto battery_status = GetBatteryStatus(battery.Get(), *battery_tag);
     if (!battery_status.has_value()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
-    absl::optional<uint32_t> battery_discharge_granularity =
+    std::optional<uint32_t> battery_discharge_granularity =
         GetBatteryBatteryDischargeGranularity(
             battery.Get(), *battery_tag, battery_status->Capacity,
             battery_information->DesignedCapacity);
diff --git a/base/power_monitor/battery_state_sampler.cc b/base/power_monitor/battery_state_sampler.cc
index 48d0854..e1a9278 100644
--- a/base/power_monitor/battery_state_sampler.cc
+++ b/base/power_monitor/battery_state_sampler.cc
@@ -108,7 +108,7 @@
 #endif  // !BUILDFLAG(IS_MAC)
 
 void BatteryStateSampler::OnInitialBatteryStateSampled(
-    const absl::optional<BatteryLevelProvider::BatteryState>& battery_state) {
+    const std::optional<BatteryLevelProvider::BatteryState>& battery_state) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   DCHECK(!has_last_battery_state_);
@@ -128,7 +128,7 @@
 }
 
 void BatteryStateSampler::OnBatteryStateSampled(
-    const absl::optional<BatteryLevelProvider::BatteryState>& battery_state) {
+    const std::optional<BatteryLevelProvider::BatteryState>& battery_state) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   DCHECK(has_last_battery_state_);
diff --git a/base/power_monitor/battery_state_sampler.h b/base/power_monitor/battery_state_sampler.h
index eaa532a7..5359c63b 100644
--- a/base/power_monitor/battery_state_sampler.h
+++ b/base/power_monitor/battery_state_sampler.h
@@ -6,6 +6,7 @@
 #define BASE_POWER_MONITOR_BATTERY_STATE_SAMPLER_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "base/base_export.h"
@@ -15,7 +16,6 @@
 #include "base/power_monitor/power_monitor_buildflags.h"
 #include "base/power_monitor/sampling_event_source.h"
 #include "base/sequence_checker.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -29,7 +29,7 @@
     // that want to ignore those stale samples should ignore the first call to
     // OnBatteryStateSampled.
     virtual void OnBatteryStateSampled(
-        const absl::optional<BatteryLevelProvider::BatteryState>&
+        const std::optional<BatteryLevelProvider::BatteryState>&
             battery_state) = 0;
   };
 
@@ -74,14 +74,14 @@
   // Called when the first battery sampled is obtained. Notifies current
   // observers as they are waiting on the cached battery state.
   void OnInitialBatteryStateSampled(
-      const absl::optional<BatteryLevelProvider::BatteryState>& battery_state);
+      const std::optional<BatteryLevelProvider::BatteryState>& battery_state);
 
   // Triggers the sampling of the battery state.
   void OnSamplingEvent();
 
   // Notifies observers of the sampled battery state.
   void OnBatteryStateSampled(
-      const absl::optional<BatteryLevelProvider::BatteryState>& battery_state);
+      const std::optional<BatteryLevelProvider::BatteryState>& battery_state);
 
   std::unique_ptr<SamplingEventSource> sampling_event_source_
       GUARDED_BY_CONTEXT(sequence_checker_);
@@ -97,7 +97,7 @@
   bool has_last_battery_state_ GUARDED_BY_CONTEXT(sequence_checker_) = false;
 
   // The value of the last sample taken.
-  absl::optional<BatteryLevelProvider::BatteryState> last_battery_state_
+  std::optional<BatteryLevelProvider::BatteryState> last_battery_state_
       GUARDED_BY_CONTEXT(sequence_checker_);
 
   SEQUENCE_CHECKER(sequence_checker_);
diff --git a/base/power_monitor/battery_state_sampler_unittest.cc b/base/power_monitor/battery_state_sampler_unittest.cc
index 605a606e..78b8e23 100644
--- a/base/power_monitor/battery_state_sampler_unittest.cc
+++ b/base/power_monitor/battery_state_sampler_unittest.cc
@@ -24,7 +24,7 @@
   TestBatteryLevelProvider() = default;
   ~TestBatteryLevelProvider() override = default;
 
-  void GetBatteryState(OnceCallback<void(const absl::optional<BatteryState>&)>
+  void GetBatteryState(OnceCallback<void(const std::optional<BatteryState>&)>
                            callback) override {
     DCHECK(!battery_states_.empty());
 
@@ -34,12 +34,12 @@
     std::move(callback).Run(next_battery_state);
   }
 
-  void PushBatteryState(const absl::optional<BatteryState>& battery_state) {
+  void PushBatteryState(const std::optional<BatteryState>& battery_state) {
     battery_states_.push(battery_state);
   }
 
  protected:
-  std::queue<absl::optional<BatteryState>> battery_states_;
+  std::queue<std::optional<BatteryState>> battery_states_;
 };
 
 class TestBatteryLevelProviderAsync : public TestBatteryLevelProvider {
@@ -47,7 +47,7 @@
   TestBatteryLevelProviderAsync() = default;
   ~TestBatteryLevelProviderAsync() override = default;
 
-  void GetBatteryState(OnceCallback<void(const absl::optional<BatteryState>&)>
+  void GetBatteryState(OnceCallback<void(const std::optional<BatteryState>&)>
                            callback) override {
     DCHECK(!battery_states_.empty());
 
@@ -70,36 +70,36 @@
   ~TestObserver() override = default;
 
   void OnBatteryStateSampled(
-      const absl::optional<BatteryLevelProvider::BatteryState>& battery_state)
+      const std::optional<BatteryLevelProvider::BatteryState>& battery_state)
       override {
     battery_state_ = battery_state;
   }
 
-  absl::optional<BatteryLevelProvider::BatteryState> battery_state() const {
+  std::optional<BatteryLevelProvider::BatteryState> battery_state() const {
     return battery_state_;
   }
 
  private:
-  absl::optional<BatteryLevelProvider::BatteryState> battery_state_;
+  std::optional<BatteryLevelProvider::BatteryState> battery_state_;
 };
 
 // Those test battery states just need to be different. The actual values don't
 // matter.
-const absl::optional<BatteryLevelProvider::BatteryState> kTestBatteryState1 =
+const std::optional<BatteryLevelProvider::BatteryState> kTestBatteryState1 =
     BatteryLevelProvider::BatteryState{
         .battery_count = 1,
         .is_external_power_connected = false,
         .current_capacity = 10000,
         .full_charged_capacity = 10000,
         .charge_unit = BatteryLevelProvider::BatteryLevelUnit::kMWh};
-const absl::optional<BatteryLevelProvider::BatteryState> kTestBatteryState2 =
+const std::optional<BatteryLevelProvider::BatteryState> kTestBatteryState2 =
     BatteryLevelProvider::BatteryState{
         .battery_count = 1,
         .is_external_power_connected = false,
         .current_capacity = 5000,
         .full_charged_capacity = 10000,
         .charge_unit = BatteryLevelProvider::BatteryLevelUnit::kMWh};
-const absl::optional<BatteryLevelProvider::BatteryState> kTestBatteryState3 =
+const std::optional<BatteryLevelProvider::BatteryState> kTestBatteryState3 =
     BatteryLevelProvider::BatteryState{
         .battery_count = 1,
         .is_external_power_connected = true,
@@ -259,7 +259,7 @@
 
   TestObserver observer;
   battery_state_sampler.AddObserver(&observer);
-  EXPECT_EQ(observer.battery_state(), absl::nullopt);
+  EXPECT_EQ(observer.battery_state(), std::nullopt);
 
   RunLoop().RunUntilIdle();
   EXPECT_EQ(observer.battery_state(), kTestBatteryState1);
diff --git a/base/power_monitor/power_monitor_device_source.h b/base/power_monitor/power_monitor_device_source.h
index d03e4d5..daccb49 100644
--- a/base/power_monitor/power_monitor_device_source.h
+++ b/base/power_monitor/power_monitor_device_source.h
@@ -128,7 +128,7 @@
   // Retrieves the current battery state to update `is_on_battery_`.
   void GetBatteryState();
   void OnBatteryStateReceived(
-      const absl::optional<BatteryLevelProvider::BatteryState>& battery_state);
+      const std::optional<BatteryLevelProvider::BatteryState>& battery_state);
 
   // Reference to the system IOPMrootDomain port.
   io_connect_t power_manager_port_ = IO_OBJECT_NULL;
diff --git a/base/power_monitor/power_monitor_device_source_mac.mm b/base/power_monitor/power_monitor_device_source_mac.mm
index f385178..2e76da6a 100644
--- a/base/power_monitor/power_monitor_device_source_mac.mm
+++ b/base/power_monitor/power_monitor_device_source_mac.mm
@@ -38,7 +38,7 @@
 }
 
 void PowerMonitorDeviceSource::OnBatteryStateReceived(
-    const absl::optional<BatteryLevelProvider::BatteryState>& battery_state) {
+    const std::optional<BatteryLevelProvider::BatteryState>& battery_state) {
   is_on_battery_ =
       battery_state.has_value() && !battery_state->is_external_power_connected;
   PowerMonitorSource::ProcessPowerEvent(PowerMonitorSource::POWER_STATE_EVENT);
diff --git a/base/power_monitor/power_monitor_unittest.cc b/base/power_monitor/power_monitor_unittest.cc
index 88109dd..a5ff7ae 100644
--- a/base/power_monitor/power_monitor_unittest.cc
+++ b/base/power_monitor/power_monitor_unittest.cc
@@ -4,10 +4,11 @@
 
 #include "base/power_monitor/power_monitor.h"
 
+#include <optional>
+
 #include "base/test/power_monitor_test.h"
 #include "base/test/task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace test {
@@ -28,7 +29,7 @@
 
  private:
   TaskEnvironment task_environment_;
-  absl::optional<ScopedPowerMonitorTestSource> power_monitor_source_;
+  std::optional<ScopedPowerMonitorTestSource> power_monitor_source_;
 };
 
 // PowerMonitorSource is tightly coupled with the PowerMonitor, so this test
diff --git a/base/process/launch.h b/base/process/launch.h
index a6ac8d2b2..55e588f 100644
--- a/base/process/launch.h
+++ b/base/process/launch.h
@@ -111,7 +111,7 @@
   // for a good overview of Windows handle inheritance.
   //
   // Implementation note: it might be nice to implement in terms of
-  // absl::optional<>, but then the natural default state (vector not present)
+  // std::optional<>, but then the natural default state (vector not present)
   // would be "all inheritable handles" while we want "no inheritance."
   enum class Inherit {
     // Only those handles in |handles_to_inherit| vector are inherited. If the
diff --git a/base/process/process_handle_freebsd.cc b/base/process/process_handle_freebsd.cc
index 07449df..ef5e930c9 100644
--- a/base/process/process_handle_freebsd.cc
+++ b/base/process/process_handle_freebsd.cc
@@ -11,9 +11,10 @@
 #include <sys/user.h>
 #include <unistd.h>
 
+#include <optional>
+
 #include "base/files/file_path.h"
 #include "base/posix/sysctl.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -29,7 +30,7 @@
 }
 
 FilePath GetProcessExecutablePath(ProcessHandle process) {
-  absl::optional<std::string> pathname =
+  std::optional<std::string> pathname =
       base::StringSysctl({CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, process});
 
   return FilePath(pathname.value_or(std::string{}));
diff --git a/base/process/process_info_win.cc b/base/process/process_info_win.cc
index a70bbf3..9210fcc19 100644
--- a/base/process/process_info_win.cc
+++ b/base/process/process_info_win.cc
@@ -6,15 +6,16 @@
 
 #include <windows.h>
 
+#include <optional>
+
 #include "base/logging.h"
 #include "base/notreached.h"
 #include "base/win/access_token.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
 IntegrityLevel GetCurrentProcessIntegrityLevel() {
-  absl::optional<base::win::AccessToken> token =
+  std::optional<base::win::AccessToken> token =
       base::win::AccessToken::FromCurrentProcess();
   if (!token) {
     PLOG(ERROR) << "AccessToken::FromCurrentProcess() failed";
@@ -39,7 +40,7 @@
 }
 
 bool IsCurrentProcessElevated() {
-  absl::optional<base::win::AccessToken> token =
+  std::optional<base::win::AccessToken> token =
       base::win::AccessToken::FromCurrentProcess();
   if (!token) {
     PLOG(ERROR) << "AccessToken::FromCurrentProcess() failed";
@@ -49,7 +50,7 @@
 }
 
 bool IsCurrentProcessInAppContainer() {
-  absl::optional<base::win::AccessToken> token =
+  std::optional<base::win::AccessToken> token =
       base::win::AccessToken::FromCurrentProcess();
   if (!token) {
     PLOG(ERROR) << "AccessToken::FromCurrentProcess() failed";
diff --git a/base/process/process_mac.cc b/base/process/process_mac.cc
index f7b0e750..8d7ce9ea 100644
--- a/base/process/process_mac.cc
+++ b/base/process/process_mac.cc
@@ -13,12 +13,12 @@
 
 #include <iterator>
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "base/apple/mach_logging.h"
 #include "base/feature_list.h"
 #include "base/memory/free_deleter.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -31,7 +31,7 @@
              FEATURE_ENABLED_BY_DEFAULT);
 
 // Returns the `task_role_t` of the process whose task port is `task_port`.
-absl::optional<task_role_t> GetTaskCategoryPolicyRole(mach_port_t task_port) {
+std::optional<task_role_t> GetTaskCategoryPolicyRole(mach_port_t task_port) {
   task_category_policy_data_t category_policy;
   mach_msg_type_number_t task_info_count = TASK_CATEGORY_POLICY_COUNT;
   boolean_t get_default = FALSE;
@@ -42,7 +42,7 @@
                       &task_info_count, &get_default);
   if (result != KERN_SUCCESS) {
     MACH_LOG(ERROR, result) << "task_policy_get TASK_CATEGORY_POLICY";
-    return absl::nullopt;
+    return std::nullopt;
   }
   CHECK(!get_default);
   return category_policy.role;
@@ -170,7 +170,7 @@
     return Priority::kUserBlocking;
   }
 
-  absl::optional<task_role_t> task_role = GetTaskCategoryPolicyRole(task_port);
+  std::optional<task_role_t> task_role = GetTaskCategoryPolicyRole(task_port);
   if (!task_role) {
     // Upon failure, return the default value.
     return Priority::kUserBlocking;
diff --git a/base/process/process_metrics_linux.cc b/base/process/process_metrics_linux.cc
index 8fd27a5..7cf88d3 100644
--- a/base/process/process_metrics_linux.cc
+++ b/base/process/process_metrics_linux.cc
@@ -14,6 +14,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <optional>
 #include <utility>
 
 #include "base/cpu.h"
@@ -36,7 +37,6 @@
 #include "base/values.h"
 #include "build/build_config.h"
 #include "third_party/abseil-cpp/absl/strings/ascii.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -799,7 +799,7 @@
   // Since ZRAM update, it shows the usage data in different places.
   // If file "/sys/block/zram0/mm_stat" exists, use the new way, otherwise,
   // use the old way.
-  static absl::optional<bool> use_new_zram_interface;
+  static std::optional<bool> use_new_zram_interface;
   FilePath zram_mm_stat_file("/sys/block/zram0/mm_stat");
   if (!use_new_zram_interface.has_value()) {
     use_new_zram_interface = PathExists(zram_mm_stat_file);
diff --git a/base/profiler/chrome_unwinder_android.cc b/base/profiler/chrome_unwinder_android.cc
index a13f2d1..2a4afa1 100644
--- a/base/profiler/chrome_unwinder_android.cc
+++ b/base/profiler/chrome_unwinder_android.cc
@@ -96,7 +96,7 @@
     const uintptr_t instruction_byte_offset_from_text_section_start =
         pc - text_section_start_address_;
 
-    const absl::optional<FunctionOffsetTableIndex> function_offset_table_index =
+    const std::optional<FunctionOffsetTableIndex> function_offset_table_index =
         GetFunctionTableIndexFromInstructionOffset(
             unwind_info_.page_table, unwind_info_.function_table,
             instruction_byte_offset_from_text_section_start);
@@ -299,7 +299,7 @@
   return 0;
 }
 
-const absl::optional<FunctionOffsetTableIndex>
+const std::optional<FunctionOffsetTableIndex>
 GetFunctionTableIndexFromInstructionOffset(
     span<const uint32_t> page_start_instructions,
     span<const FunctionTableEntry> function_offset_table_indices,
@@ -320,7 +320,7 @@
   // Invalid instruction_byte_offset_from_text_section_start:
   // instruction_byte_offset_from_text_section_start falls after the last page.
   if (page_number >= page_start_instructions.size()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   const span<const FunctionTableEntry>::iterator function_table_entry_start =
diff --git a/base/profiler/chrome_unwinder_android.h b/base/profiler/chrome_unwinder_android.h
index 7f8fdc5..c1e1c20 100644
--- a/base/profiler/chrome_unwinder_android.h
+++ b/base/profiler/chrome_unwinder_android.h
@@ -7,13 +7,14 @@
 
 #include <stdint.h>
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/containers/span.h"
 #include "base/profiler/chrome_unwind_info_android.h"
 #include "base/profiler/module_cache.h"
 #include "base/profiler/register_context.h"
 #include "base/profiler/unwinder.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -103,7 +104,7 @@
 //    `ChromeUnwindInfoAndroid::function_table` for details.
 //  instruction_byte_offset_from_text_section_start: The distance in bytes
 //    between the instruction of interest and text section start.
-BASE_EXPORT const absl::optional<FunctionOffsetTableIndex>
+BASE_EXPORT const std::optional<FunctionOffsetTableIndex>
 GetFunctionTableIndexFromInstructionOffset(
     span<const uint32_t> page_start_instructions,
     span<const FunctionTableEntry> function_offset_table_indices,
diff --git a/base/profiler/chrome_unwinder_android_unittest.cc b/base/profiler/chrome_unwinder_android_unittest.cc
index 8995b9c..731b60b2 100644
--- a/base/profiler/chrome_unwinder_android_unittest.cc
+++ b/base/profiler/chrome_unwinder_android_unittest.cc
@@ -759,7 +759,7 @@
         page_start_instructions, function_offset_table_indices,
         /* instruction_offset */ (page_instruction_offset << 1) +
             (page_number << 17));
-    ASSERT_NE(absl::nullopt, entry_found);
+    ASSERT_NE(std::nullopt, entry_found);
     EXPECT_EQ(0, entry_found->instruction_offset_from_function_start);
     EXPECT_EQ(40ul, entry_found->function_offset_table_byte_index);
   }
@@ -771,7 +771,7 @@
         page_start_instructions, function_offset_table_indices,
         /* instruction_offset */ (page_instruction_offset << 1) +
             (page_number << 17));
-    ASSERT_NE(absl::nullopt, entry_found);
+    ASSERT_NE(std::nullopt, entry_found);
     EXPECT_EQ(46, entry_found->instruction_offset_from_function_start);
     EXPECT_EQ(40ul, entry_found->function_offset_table_byte_index);
   }
@@ -784,7 +784,7 @@
         page_start_instructions, function_offset_table_indices,
         /* instruction_offset */ (page_instruction_offset << 1) +
             (page_number << 17));
-    ASSERT_NE(absl::nullopt, entry_found);
+    ASSERT_NE(std::nullopt, entry_found);
     // 0xffff - 6 = 0xfff9.
     EXPECT_EQ(0xfff9, entry_found->instruction_offset_from_function_start);
     EXPECT_EQ(70ul, entry_found->function_offset_table_byte_index);
@@ -813,7 +813,7 @@
       page_start_instructions, function_offset_table_indices,
       /* instruction_offset */ (page_instruction_offset << 1) +
           (page_number << 17));
-  ASSERT_NE(absl::nullopt, entry_found);
+  ASSERT_NE(std::nullopt, entry_found);
   EXPECT_EQ(0x10004, entry_found->instruction_offset_from_function_start);
   EXPECT_EQ(20ul, entry_found->function_offset_table_byte_index);
 }
@@ -842,7 +842,7 @@
         page_start_instructions, function_offset_table_indices,
         /* instruction_offset */ (page_instruction_offset << 1) +
             (page_number << 17));
-    ASSERT_EQ(absl::nullopt, entry_found);
+    ASSERT_EQ(std::nullopt, entry_found);
   }
   {
     const uint32_t page_number = 2;
@@ -851,7 +851,7 @@
         page_start_instructions, function_offset_table_indices,
         /* instruction_offset */ (page_instruction_offset << 1) +
             (page_number << 17));
-    ASSERT_EQ(absl::nullopt, entry_found);
+    ASSERT_EQ(std::nullopt, entry_found);
   }
 }
 
@@ -881,7 +881,7 @@
       page_start_instructions, function_offset_table_indices,
       /* instruction_offset */ (page_instruction_offset << 1) +
           (page_number << 17));
-  ASSERT_NE(absl::nullopt, entry_found);
+  ASSERT_NE(std::nullopt, entry_found);
   EXPECT_EQ(0x10004, entry_found->instruction_offset_from_function_start);
   EXPECT_EQ(20ul, entry_found->function_offset_table_byte_index);
 }
@@ -912,7 +912,7 @@
         page_start_instructions, function_offset_table_indices,
         /* instruction_offset */ (page_instruction_offset << 1) +
             (page_number << 17));
-    ASSERT_NE(absl::nullopt, entry_found);
+    ASSERT_NE(std::nullopt, entry_found);
     EXPECT_EQ(0x4, entry_found->instruction_offset_from_function_start);
     EXPECT_EQ(20ul, entry_found->function_offset_table_byte_index);
   }
@@ -923,7 +923,7 @@
         page_start_instructions, function_offset_table_indices,
         /* instruction_offset */ (page_instruction_offset << 1) +
             (page_number << 17));
-    ASSERT_NE(absl::nullopt, entry_found);
+    ASSERT_NE(std::nullopt, entry_found);
     EXPECT_EQ(0x10004, entry_found->instruction_offset_from_function_start);
     EXPECT_EQ(20ul, entry_found->function_offset_table_byte_index);
   }
@@ -934,7 +934,7 @@
         page_start_instructions, function_offset_table_indices,
         /* instruction_offset */ (page_instruction_offset << 1) +
             (page_number << 17));
-    ASSERT_NE(absl::nullopt, entry_found);
+    ASSERT_NE(std::nullopt, entry_found);
     EXPECT_EQ(0x20004, entry_found->instruction_offset_from_function_start);
     EXPECT_EQ(20ul, entry_found->function_offset_table_byte_index);
   }
@@ -945,7 +945,7 @@
         page_start_instructions, function_offset_table_indices,
         /* instruction_offset */ (page_instruction_offset << 1) +
             (page_number << 17));
-    ASSERT_NE(absl::nullopt, entry_found);
+    ASSERT_NE(std::nullopt, entry_found);
     EXPECT_EQ(0x30004, entry_found->instruction_offset_from_function_start);
     EXPECT_EQ(20ul, entry_found->function_offset_table_byte_index);
   }
diff --git a/base/profiler/metadata_recorder.cc b/base/profiler/metadata_recorder.cc
index 9f4d2af..4888d9c 100644
--- a/base/profiler/metadata_recorder.cc
+++ b/base/profiler/metadata_recorder.cc
@@ -4,16 +4,17 @@
 
 #include "base/profiler/metadata_recorder.h"
 
+#include <optional>
+
 #include "base/metrics/histogram_macros.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
 const size_t MetadataRecorder::MAX_METADATA_COUNT;
 
 MetadataRecorder::Item::Item(uint64_t name_hash,
-                             absl::optional<int64_t> key,
-                             absl::optional<PlatformThreadId> thread_id,
+                             std::optional<int64_t> key,
+                             std::optional<PlatformThreadId> thread_id,
                              int64_t value)
     : name_hash(name_hash), key(key), thread_id(thread_id), value(value) {}
 
@@ -37,8 +38,8 @@
 MetadataRecorder::~MetadataRecorder() = default;
 
 void MetadataRecorder::Set(uint64_t name_hash,
-                           absl::optional<int64_t> key,
-                           absl::optional<PlatformThreadId> thread_id,
+                           std::optional<int64_t> key,
+                           std::optional<PlatformThreadId> thread_id,
                            int64_t value) {
   AutoLock lock(write_lock_);
 
@@ -86,8 +87,8 @@
 }
 
 void MetadataRecorder::Remove(uint64_t name_hash,
-                              absl::optional<int64_t> key,
-                              absl::optional<PlatformThreadId> thread_id) {
+                              std::optional<int64_t> key,
+                              std::optional<PlatformThreadId> thread_id) {
   AutoLock lock(write_lock_);
 
   size_t item_slots_used = item_slots_used_.load(std::memory_order_relaxed);
diff --git a/base/profiler/metadata_recorder.h b/base/profiler/metadata_recorder.h
index b0f8c36..e902843 100644
--- a/base/profiler/metadata_recorder.h
+++ b/base/profiler/metadata_recorder.h
@@ -7,6 +7,7 @@
 
 #include <array>
 #include <atomic>
+#include <optional>
 #include <utility>
 
 #include "base/base_export.h"
@@ -14,7 +15,6 @@
 #include "base/synchronization/lock.h"
 #include "base/thread_annotations.h"
 #include "base/threading/platform_thread.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -132,8 +132,8 @@
 
   struct BASE_EXPORT Item {
     Item(uint64_t name_hash,
-         absl::optional<int64_t> key,
-         absl::optional<PlatformThreadId> thread_id,
+         std::optional<int64_t> key,
+         std::optional<PlatformThreadId> thread_id,
          int64_t value);
     Item();
 
@@ -143,10 +143,10 @@
     // The hash of the metadata name, as produced by HashMetricName().
     uint64_t name_hash;
     // The key if specified when setting the item.
-    absl::optional<int64_t> key;
+    std::optional<int64_t> key;
     // The thread_id is captured from the current thread for a thread-scoped
     // item.
-    absl::optional<PlatformThreadId> thread_id;
+    std::optional<PlatformThreadId> thread_id;
     // The value of the metadata item.
     int64_t value;
   };
@@ -157,15 +157,15 @@
   // value previously set for the tuple. Nullopt keys are treated as just
   // another key state for the purpose of associating values.
   void Set(uint64_t name_hash,
-           absl::optional<int64_t> key,
-           absl::optional<PlatformThreadId> thread_id,
+           std::optional<int64_t> key,
+           std::optional<PlatformThreadId> thread_id,
            int64_t value);
 
   // Removes the item with the specified name hash and optional key. Has no
   // effect if such an item does not exist.
   void Remove(uint64_t name_hash,
-              absl::optional<int64_t> key,
-              absl::optional<PlatformThreadId> thread_id);
+              std::optional<int64_t> key,
+              std::optional<PlatformThreadId> thread_id);
 
   // An object that provides access to a MetadataRecorder's items and holds the
   // necessary exclusive read lock until the object is destroyed. Reclaiming of
@@ -235,8 +235,8 @@
     // we're guaranteed that |name_hash|, |key| and |thread_id| will be finished
     // writing before |is_active| is set to true.
     uint64_t name_hash;
-    absl::optional<int64_t> key;
-    absl::optional<PlatformThreadId> thread_id;
+    std::optional<int64_t> key;
+    std::optional<PlatformThreadId> thread_id;
 
     // Requires atomic reads and writes to avoid word tearing when updating an
     // existing item unsynchronized. Does not require acquire/release semantics
diff --git a/base/profiler/metadata_recorder_unittest.cc b/base/profiler/metadata_recorder_unittest.cc
index c41b7c6..889d8ff 100644
--- a/base/profiler/metadata_recorder_unittest.cc
+++ b/base/profiler/metadata_recorder_unittest.cc
@@ -4,11 +4,12 @@
 
 #include "base/profiler/metadata_recorder.h"
 
+#include <optional>
+
 #include "base/ranges/algorithm.h"
 #include "base/test/gtest_util.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -37,7 +38,7 @@
 TEST(MetadataRecorderTest, Set_NewNameHash) {
   MetadataRecorder recorder;
 
-  recorder.Set(10, absl::nullopt, absl::nullopt, 20);
+  recorder.Set(10, std::nullopt, std::nullopt, 20);
 
   MetadataRecorder::ItemArray items;
   size_t item_count;
@@ -52,7 +53,7 @@
     EXPECT_EQ(20, items[0].value);
   }
 
-  recorder.Set(20, absl::nullopt, absl::nullopt, 30);
+  recorder.Set(20, std::nullopt, std::nullopt, 30);
 
   {
     item_count = MetadataRecorder::MetadataProvider(&recorder,
@@ -68,8 +69,8 @@
 
 TEST(MetadataRecorderTest, Set_ExistingNameNash) {
   MetadataRecorder recorder;
-  recorder.Set(10, absl::nullopt, absl::nullopt, 20);
-  recorder.Set(10, absl::nullopt, absl::nullopt, 30);
+  recorder.Set(10, std::nullopt, std::nullopt, 20);
+  recorder.Set(10, std::nullopt, std::nullopt, 30);
 
   MetadataRecorder::ItemArray items;
   size_t item_count =
@@ -87,16 +88,16 @@
   MetadataRecorder::ItemArray items;
   std::vector<MetadataRecorder::Item> expected;
   for (size_t i = 0; i < items.size(); ++i) {
-    expected.emplace_back(i, absl::nullopt, absl::nullopt, 0);
-    recorder.Set(i, absl::nullopt, absl::nullopt, 0);
+    expected.emplace_back(i, std::nullopt, std::nullopt, 0);
+    recorder.Set(i, std::nullopt, std::nullopt, 0);
   }
 
   // By removing an item from a full recorder, re-setting the same item, and
   // verifying that the item is returned, we can verify that the recorder is
   // reusing the inactive slot for the same name hash instead of trying (and
   // failing) to allocate a new slot.
-  recorder.Remove(3, absl::nullopt, absl::nullopt);
-  recorder.Set(3, absl::nullopt, absl::nullopt, 0);
+  recorder.Remove(3, std::nullopt, std::nullopt);
+  recorder.Set(3, std::nullopt, std::nullopt, 0);
 
   size_t item_count =
       MetadataRecorder::MetadataProvider(&recorder, PlatformThread::CurrentId())
@@ -109,17 +110,17 @@
   MetadataRecorder recorder;
   MetadataRecorder::ItemArray items;
   for (size_t i = 0; i < items.size(); ++i) {
-    recorder.Set(i, absl::nullopt, absl::nullopt, 0);
+    recorder.Set(i, std::nullopt, std::nullopt, 0);
   }
 
   // This should fail silently.
-  recorder.Set(items.size(), absl::nullopt, absl::nullopt, 0);
+  recorder.Set(items.size(), std::nullopt, std::nullopt, 0);
 }
 
 TEST(MetadataRecorderTest, Set_NulloptKeyIsIndependentOfNonNulloptKey) {
   MetadataRecorder recorder;
 
-  recorder.Set(10, 100, absl::nullopt, 20);
+  recorder.Set(10, 100, std::nullopt, 20);
 
   MetadataRecorder::ItemArray items;
   size_t item_count;
@@ -134,7 +135,7 @@
     EXPECT_EQ(20, items[0].value);
   }
 
-  recorder.Set(10, absl::nullopt, absl::nullopt, 30);
+  recorder.Set(10, std::nullopt, std::nullopt, 30);
 
   {
     item_count = MetadataRecorder::MetadataProvider(&recorder,
@@ -156,7 +157,7 @@
 TEST(MetadataRecorderTest, Set_ThreadIdIsScoped) {
   MetadataRecorder recorder;
 
-  recorder.Set(10, absl::nullopt, PlatformThread::CurrentId(), 20);
+  recorder.Set(10, std::nullopt, PlatformThread::CurrentId(), 20);
 
   MetadataRecorder::ItemArray items;
   size_t item_count;
@@ -181,8 +182,8 @@
 TEST(MetadataRecorderTest, Set_NulloptThreadAndNonNulloptThread) {
   MetadataRecorder recorder;
 
-  recorder.Set(10, absl::nullopt, PlatformThread::CurrentId(), 20);
-  recorder.Set(10, absl::nullopt, absl::nullopt, 30);
+  recorder.Set(10, std::nullopt, PlatformThread::CurrentId(), 20);
+  recorder.Set(10, std::nullopt, std::nullopt, 30);
 
   MetadataRecorder::ItemArray items;
   size_t item_count =
@@ -203,10 +204,10 @@
 
 TEST(MetadataRecorderTest, Remove) {
   MetadataRecorder recorder;
-  recorder.Set(10, absl::nullopt, absl::nullopt, 20);
-  recorder.Set(30, absl::nullopt, absl::nullopt, 40);
-  recorder.Set(50, absl::nullopt, absl::nullopt, 60);
-  recorder.Remove(30, absl::nullopt, absl::nullopt);
+  recorder.Set(10, std::nullopt, std::nullopt, 20);
+  recorder.Set(30, std::nullopt, std::nullopt, 40);
+  recorder.Set(50, std::nullopt, std::nullopt, 60);
+  recorder.Remove(30, std::nullopt, std::nullopt);
 
   MetadataRecorder::ItemArray items;
   size_t item_count =
@@ -223,8 +224,8 @@
 
 TEST(MetadataRecorderTest, Remove_DoesntExist) {
   MetadataRecorder recorder;
-  recorder.Set(10, absl::nullopt, absl::nullopt, 20);
-  recorder.Remove(20, absl::nullopt, absl::nullopt);
+  recorder.Set(10, std::nullopt, std::nullopt, 20);
+  recorder.Remove(20, std::nullopt, std::nullopt);
 
   MetadataRecorder::ItemArray items;
   size_t item_count =
@@ -239,10 +240,10 @@
 TEST(MetadataRecorderTest, Remove_NulloptKeyIsIndependentOfNonNulloptKey) {
   MetadataRecorder recorder;
 
-  recorder.Set(10, 100, absl::nullopt, 20);
-  recorder.Set(10, absl::nullopt, absl::nullopt, 30);
+  recorder.Set(10, 100, std::nullopt, 20);
+  recorder.Set(10, std::nullopt, std::nullopt, 30);
 
-  recorder.Remove(10, absl::nullopt, absl::nullopt);
+  recorder.Remove(10, std::nullopt, std::nullopt);
 
   MetadataRecorder::ItemArray items;
   size_t item_count =
@@ -259,10 +260,10 @@
      Remove_NulloptThreadIsIndependentOfNonNulloptThread) {
   MetadataRecorder recorder;
 
-  recorder.Set(10, absl::nullopt, PlatformThread::CurrentId(), 20);
-  recorder.Set(10, absl::nullopt, absl::nullopt, 30);
+  recorder.Set(10, std::nullopt, PlatformThread::CurrentId(), 20);
+  recorder.Set(10, std::nullopt, std::nullopt, 30);
 
-  recorder.Remove(10, absl::nullopt, absl::nullopt);
+  recorder.Remove(10, std::nullopt, std::nullopt);
 
   MetadataRecorder::ItemArray items;
   size_t item_count =
@@ -282,25 +283,25 @@
   std::set<MetadataRecorder::Item> items_set;
   // Fill up the metadata map.
   for (size_t i = 0; i < MetadataRecorder::MAX_METADATA_COUNT; ++i) {
-    recorder.Set(i, absl::nullopt, absl::nullopt, i);
-    items_set.insert(MetadataRecorder::Item{i, absl::nullopt, absl::nullopt,
+    recorder.Set(i, std::nullopt, std::nullopt, i);
+    items_set.insert(MetadataRecorder::Item{i, std::nullopt, std::nullopt,
                                             static_cast<int64_t>(i)});
   }
 
   // Remove every fourth entry to fragment the data.
   size_t entries_removed = 0;
   for (size_t i = 3; i < MetadataRecorder::MAX_METADATA_COUNT; i += 4) {
-    recorder.Remove(i, absl::nullopt, absl::nullopt);
+    recorder.Remove(i, std::nullopt, std::nullopt);
     ++entries_removed;
-    items_set.erase(MetadataRecorder::Item{i, absl::nullopt, absl::nullopt,
+    items_set.erase(MetadataRecorder::Item{i, std::nullopt, std::nullopt,
                                            static_cast<int64_t>(i)});
   }
 
   // Ensure that the inactive slots are reclaimed to make room for more entries.
   for (size_t i = 1; i <= entries_removed; ++i) {
-    recorder.Set(i * 100, absl::nullopt, absl::nullopt, i * 100);
-    items_set.insert(MetadataRecorder::Item{
-        i * 100, absl::nullopt, absl::nullopt, static_cast<int64_t>(i * 100)});
+    recorder.Set(i * 100, std::nullopt, std::nullopt, i * 100);
+    items_set.insert(MetadataRecorder::Item{i * 100, std::nullopt, std::nullopt,
+                                            static_cast<int64_t>(i * 100)});
   }
 
   MetadataRecorder::ItemArray items_arr;
diff --git a/base/profiler/module_cache_posix.cc b/base/profiler/module_cache_posix.cc
index e00b0b58..f0a819b 100644
--- a/base/profiler/module_cache_posix.cc
+++ b/base/profiler/module_cache_posix.cc
@@ -7,10 +7,11 @@
 #include <dlfcn.h>
 #include <elf.h>
 
+#include <optional>
+
 #include "base/debug/elf_reader.h"
 #include "base/strings/string_piece.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_ANDROID)
 extern "C" {
@@ -72,7 +73,7 @@
   // Preferentially identify the library using its soname on Android. Libraries
   // mapped directly from apks have the apk filename in |dl_info.dli_fname|, and
   // this doesn't distinguish the particular library.
-  absl::optional<StringPiece> library_name =
+  std::optional<StringPiece> library_name =
       debug::ReadElfLibraryName(base_address);
   if (library_name)
     return FilePath(*library_name);
diff --git a/base/profiler/sample_metadata.cc b/base/profiler/sample_metadata.cc
index f93b364..e4feaa4 100644
--- a/base/profiler/sample_metadata.cc
+++ b/base/profiler/sample_metadata.cc
@@ -4,20 +4,21 @@
 
 #include "base/profiler/sample_metadata.h"
 
+#include <optional>
+
 #include "base/metrics/metrics_hashes.h"
 #include "base/no_destructor.h"
 #include "base/profiler/stack_sampling_profiler.h"
 #include "base/threading/thread_local.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
 namespace {
 
-absl::optional<PlatformThreadId> GetPlatformThreadIdForScope(
+std::optional<PlatformThreadId> GetPlatformThreadIdForScope(
     SampleMetadataScope scope) {
   if (scope == SampleMetadataScope::kProcess)
-    return absl::nullopt;
+    return std::nullopt;
   return PlatformThread::CurrentId();
 }
 
@@ -27,7 +28,7 @@
     : name_hash_(HashMetricName(name)), scope_(scope) {}
 
 void SampleMetadata::Set(int64_t value) {
-  GetSampleMetadataRecorder()->Set(name_hash_, absl::nullopt,
+  GetSampleMetadataRecorder()->Set(name_hash_, std::nullopt,
                                    GetPlatformThreadIdForScope(scope_), value);
 }
 
@@ -37,7 +38,7 @@
 }
 
 void SampleMetadata::Remove() {
-  GetSampleMetadataRecorder()->Remove(name_hash_, absl::nullopt,
+  GetSampleMetadataRecorder()->Remove(name_hash_, std::nullopt,
                                       GetPlatformThreadIdForScope(scope_));
 }
 
@@ -51,8 +52,7 @@
                                            SampleMetadataScope scope)
     : name_hash_(HashMetricName(name)),
       thread_id_(GetPlatformThreadIdForScope(scope)) {
-  GetSampleMetadataRecorder()->Set(name_hash_, absl::nullopt, thread_id_,
-                                   value);
+  GetSampleMetadataRecorder()->Set(name_hash_, std::nullopt, thread_id_, value);
 }
 
 ScopedSampleMetadata::ScopedSampleMetadata(StringPiece name,
@@ -71,13 +71,12 @@
 
 // This function is friended by StackSamplingProfiler so must live directly in
 // the base namespace.
-void ApplyMetadataToPastSamplesImpl(
-    TimeTicks period_start,
-    TimeTicks period_end,
-    uint64_t name_hash,
-    absl::optional<int64_t> key,
-    int64_t value,
-    absl::optional<PlatformThreadId> thread_id) {
+void ApplyMetadataToPastSamplesImpl(TimeTicks period_start,
+                                    TimeTicks period_end,
+                                    uint64_t name_hash,
+                                    std::optional<int64_t> key,
+                                    int64_t value,
+                                    std::optional<PlatformThreadId> thread_id) {
   StackSamplingProfiler::ApplyMetadataToPastSamples(
       period_start, period_end, name_hash, key, value, thread_id);
 }
@@ -88,7 +87,7 @@
                                 int64_t value,
                                 SampleMetadataScope scope) {
   return ApplyMetadataToPastSamplesImpl(
-      period_start, period_end, HashMetricName(name), absl::nullopt, value,
+      period_start, period_end, HashMetricName(name), std::nullopt, value,
       GetPlatformThreadIdForScope(scope));
 }
 
@@ -106,7 +105,7 @@
 void AddProfileMetadataImpl(uint64_t name_hash,
                             int64_t key,
                             int64_t value,
-                            absl::optional<PlatformThreadId> thread_id) {
+                            std::optional<PlatformThreadId> thread_id) {
   StackSamplingProfiler::AddProfileMetadata(name_hash, key, value, thread_id);
 }
 
diff --git a/base/profiler/sample_metadata.h b/base/profiler/sample_metadata.h
index 48fb0e8..e0a34e0a 100644
--- a/base/profiler/sample_metadata.h
+++ b/base/profiler/sample_metadata.h
@@ -5,11 +5,12 @@
 #ifndef BASE_PROFILER_SAMPLE_METADATA_H_
 #define BASE_PROFILER_SAMPLE_METADATA_H_
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/profiler/metadata_recorder.h"
 #include "base/strings/string_piece.h"
 #include "base/threading/platform_thread.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // -----------------------------------------------------------------------------
 // Usage documentation
@@ -138,8 +139,8 @@
 
  private:
   const uint64_t name_hash_;
-  absl::optional<int64_t> key_;
-  absl::optional<PlatformThreadId> thread_id_;
+  std::optional<int64_t> key_;
+  std::optional<PlatformThreadId> thread_id_;
 };
 
 // Applies the specified metadata to samples already recorded between
diff --git a/base/profiler/sampling_profiler_thread_token.cc b/base/profiler/sampling_profiler_thread_token.cc
index 8186e673..5ef3ec4 100644
--- a/base/profiler/sampling_profiler_thread_token.cc
+++ b/base/profiler/sampling_profiler_thread_token.cc
@@ -19,7 +19,7 @@
 #if BUILDFLAG(IS_ANDROID)
   return {id, pthread_self()};
 #elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
-  absl::optional<uintptr_t> maybe_stack_base =
+  std::optional<uintptr_t> maybe_stack_base =
       GetThreadStackBaseAddress(id, pthread_self());
   return {id, maybe_stack_base};
 #else
diff --git a/base/profiler/sampling_profiler_thread_token.h b/base/profiler/sampling_profiler_thread_token.h
index 43ca395..c2e9ef1b 100644
--- a/base/profiler/sampling_profiler_thread_token.h
+++ b/base/profiler/sampling_profiler_thread_token.h
@@ -5,10 +5,11 @@
 #ifndef BASE_PROFILER_SAMPLING_PROFILER_THREAD_TOKEN_H_
 #define BASE_PROFILER_SAMPLING_PROFILER_THREAD_TOKEN_H_
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/threading/platform_thread.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_ANDROID)
 #include <pthread.h>
@@ -30,7 +31,7 @@
   // Due to the sandbox, we can only retrieve the stack base address for the
   // current thread. We must grab it during
   // GetSamplingProfilerCurrentThreadToken() and not try to get it later.
-  absl::optional<uintptr_t> stack_base_address;
+  std::optional<uintptr_t> stack_base_address;
 #endif
 };
 
diff --git a/base/profiler/stack_base_address_posix.cc b/base/profiler/stack_base_address_posix.cc
index c49b1bb..082106f8 100644
--- a/base/profiler/stack_base_address_posix.cc
+++ b/base/profiler/stack_base_address_posix.cc
@@ -26,12 +26,12 @@
 namespace {
 
 #if BUILDFLAG(IS_ANDROID)
-absl::optional<uintptr_t> GetAndroidMainThreadStackBaseAddressImpl() {
+std::optional<uintptr_t> GetAndroidMainThreadStackBaseAddressImpl() {
   char line[1024];
   base::ScopedFILE fp(base::OpenFile(base::FilePath("/proc/self/maps"), "r"));
   uintptr_t stack_addr = reinterpret_cast<uintptr_t>(line);
   if (!fp)
-    return absl::nullopt;
+    return std::nullopt;
   while (fgets(line, sizeof(line), fp.get()) != nullptr) {
     uintptr_t start, end;
     if (sscanf(line, "%" SCNxPTR "-%" SCNxPTR, &start, &end) == 2) {
@@ -39,7 +39,7 @@
         return end;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 #endif
 
@@ -71,14 +71,14 @@
 
 }  // namespace
 
-absl::optional<uintptr_t> GetThreadStackBaseAddress(PlatformThreadId id,
-                                                    pthread_t pthread_id) {
+std::optional<uintptr_t> GetThreadStackBaseAddress(PlatformThreadId id,
+                                                   pthread_t pthread_id) {
 #if BUILDFLAG(IS_LINUX)
   // We don't currently support Linux; pthread_getattr_np() fails for the main
   // thread after zygote forks. https://crbug.com/1394278. Since we don't
   // support stack profiling at all on Linux, we just return nullopt instead of
   // trying to work around the problem.
-  return absl::nullopt;
+  return std::nullopt;
 #else
   const bool is_main_thread = id == GetCurrentProcId();
   if (is_main_thread) {
@@ -88,7 +88,7 @@
     // read or parse the file. So, try to read the maps to get the main thread
     // stack base and cache the result. Other thread base addresses are sourced
     // from pthread state so are cheap to get.
-    static const absl::optional<uintptr_t> main_thread_base_address =
+    static const std::optional<uintptr_t> main_thread_base_address =
         GetAndroidMainThreadStackBaseAddressImpl();
     return main_thread_base_address;
 #elif BUILDFLAG(IS_CHROMEOS)
diff --git a/base/profiler/stack_base_address_posix.h b/base/profiler/stack_base_address_posix.h
index 9769c036..04c4e8a5 100644
--- a/base/profiler/stack_base_address_posix.h
+++ b/base/profiler/stack_base_address_posix.h
@@ -8,9 +8,10 @@
 #include <pthread.h>
 #include <stdint.h>
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/threading/platform_thread.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -25,7 +26,7 @@
 //
 // May return nullopt on Android if the thread's memory range is not found in
 // /proc/self/maps.
-BASE_EXPORT absl::optional<uintptr_t> GetThreadStackBaseAddress(
+BASE_EXPORT std::optional<uintptr_t> GetThreadStackBaseAddress(
     PlatformThreadId id,
     pthread_t pthread_id);
 
diff --git a/base/profiler/stack_base_address_posix_unittest.cc b/base/profiler/stack_base_address_posix_unittest.cc
index 498df04..6c602ad6 100644
--- a/base/profiler/stack_base_address_posix_unittest.cc
+++ b/base/profiler/stack_base_address_posix_unittest.cc
@@ -28,7 +28,7 @@
 #define MAYBE_CurrentThread CurrentThread
 #endif
 TEST(GetThreadStackBaseAddressTest, MAYBE_CurrentThread) {
-  absl::optional<uintptr_t> base =
+  std::optional<uintptr_t> base =
       GetThreadStackBaseAddress(PlatformThread::CurrentId(), pthread_self());
   EXPECT_THAT(base, Optional(Gt(0u)));
   uintptr_t stack_addr = reinterpret_cast<uintptr_t>(&base);
@@ -41,7 +41,7 @@
 TEST(GetThreadStackBaseAddressTest, MainThread) {
   // GetThreadStackBaseAddress does not use pthread_id for main thread on these
   // platforms.
-  absl::optional<uintptr_t> base =
+  std::optional<uintptr_t> base =
       GetThreadStackBaseAddress(GetCurrentProcId(), pthread_t());
   EXPECT_THAT(base, Optional(Gt(0u)));
 }
diff --git a/base/profiler/stack_copier_signal.cc b/base/profiler/stack_copier_signal.cc
index 36bc79e..6ad2353 100644
--- a/base/profiler/stack_copier_signal.cc
+++ b/base/profiler/stack_copier_signal.cc
@@ -13,6 +13,7 @@
 
 #include <atomic>
 #include <cstring>
+#include <optional>
 
 #include "base/memory/raw_ptr.h"
 #include "base/memory/raw_ptr_exclusion.h"
@@ -23,7 +24,6 @@
 #include "base/time/time_override.h"
 #include "base/trace_event/base_tracing.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -129,7 +129,7 @@
   RAW_PTR_EXCLUSION const uint8_t** stack_copy_bottom;
 
   // The timestamp when the stack was copied.
-  RAW_PTR_EXCLUSION absl::optional<TimeTicks>* maybe_timestamp;
+  RAW_PTR_EXCLUSION std::optional<TimeTicks>* maybe_timestamp;
 
   // The delegate provided to the StackCopier.
   RAW_PTR_EXCLUSION StackCopier::Delegate* stack_copier_delegate;
@@ -148,7 +148,7 @@
 
   // MaybeTimeTicksNowIgnoringOverride() is implemented in terms of
   // clock_gettime on Linux, which is signal safe per the signal-safety(7) man
-  // page, but is not garanteed to succeed, in which case absl::nullopt is
+  // page, but is not garanteed to succeed, in which case std::nullopt is
   // returned. TimeTicks::Now() can't be used because it expects clock_gettime
   // to always succeed and is thus not signal-safe.
   *params->maybe_timestamp = subtle::MaybeTimeTicksNowIgnoringOverride();
@@ -234,7 +234,7 @@
   bool copied = false;
   const uint8_t* stack_copy_bottom = nullptr;
   const uintptr_t stack_base_address = thread_delegate_->GetStackBaseAddress();
-  absl::optional<TimeTicks> maybe_timestamp;
+  std::optional<TimeTicks> maybe_timestamp;
   HandlerParams params = {stack_base_address, &wait_event,  &copied,
                           thread_context,     stack_buffer, &stack_copy_bottom,
                           &maybe_timestamp,   delegate};
diff --git a/base/profiler/stack_sampling_profiler.cc b/base/profiler/stack_sampling_profiler.cc
index 7697ef6..d6d3070 100644
--- a/base/profiler/stack_sampling_profiler.cc
+++ b/base/profiler/stack_sampling_profiler.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 #include <cmath>
 #include <map>
+#include <optional>
 #include <utility>
 
 #include "base/atomic_sequence_num.h"
@@ -30,7 +31,6 @@
 #include "base/time/time.h"
 #include "base/trace_event/base_tracing.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_WIN)
 #include "base/win/static_constants.h"
@@ -180,16 +180,16 @@
   void ApplyMetadataToPastSamples(base::TimeTicks period_start,
                                   base::TimeTicks period_end,
                                   uint64_t name_hash,
-                                  absl::optional<int64_t> key,
+                                  std::optional<int64_t> key,
                                   int64_t value,
-                                  absl::optional<PlatformThreadId> thread_id);
+                                  std::optional<PlatformThreadId> thread_id);
 
   // Adds the metadata as profile metadata. Profile metadata stores metadata
   // global to the profile.
   void AddProfileMetadata(uint64_t name_hash,
-                          absl::optional<int64_t> key,
+                          std::optional<int64_t> key,
                           int64_t value,
-                          absl::optional<PlatformThreadId> thread_id);
+                          std::optional<PlatformThreadId> thread_id);
 
   // Removes an active collection based on its collection id, forcing it to run
   // its callback if any data has been collected. This can be called externally
@@ -246,13 +246,13 @@
       base::TimeTicks period_start,
       base::TimeTicks period_end,
       uint64_t name_hash,
-      absl::optional<int64_t> key,
+      std::optional<int64_t> key,
       int64_t value,
-      absl::optional<PlatformThreadId> thread_id);
+      std::optional<PlatformThreadId> thread_id);
   void AddProfileMetadataTask(uint64_t name_hash,
-                              absl::optional<int64_t> key,
+                              std::optional<int64_t> key,
                               int64_t value,
-                              absl::optional<PlatformThreadId> thread_id);
+                              std::optional<PlatformThreadId> thread_id);
   void RemoveCollectionTask(int collection_id);
   void RecordSampleTask(int collection_id);
   void ShutdownTask(int add_events);
@@ -418,9 +418,9 @@
     base::TimeTicks period_start,
     base::TimeTicks period_end,
     uint64_t name_hash,
-    absl::optional<int64_t> key,
+    std::optional<int64_t> key,
     int64_t value,
-    absl::optional<PlatformThreadId> thread_id) {
+    std::optional<PlatformThreadId> thread_id) {
   ThreadExecutionState state;
   scoped_refptr<SingleThreadTaskRunner> task_runner = GetTaskRunner(&state);
   if (state != RUNNING)
@@ -434,9 +434,9 @@
 
 void StackSamplingProfiler::SamplingThread::AddProfileMetadata(
     uint64_t name_hash,
-    absl::optional<int64_t> key,
+    std::optional<int64_t> key,
     int64_t value,
-    absl::optional<PlatformThreadId> thread_id) {
+    std::optional<PlatformThreadId> thread_id) {
   ThreadExecutionState state;
   scoped_refptr<SingleThreadTaskRunner> task_runner = GetTaskRunner(&state);
   if (state != RUNNING) {
@@ -603,9 +603,9 @@
     base::TimeTicks period_start,
     base::TimeTicks period_end,
     uint64_t name_hash,
-    absl::optional<int64_t> key,
+    std::optional<int64_t> key,
     int64_t value,
-    absl::optional<PlatformThreadId> thread_id) {
+    std::optional<PlatformThreadId> thread_id) {
   DCHECK_EQ(GetThreadId(), PlatformThread::CurrentId());
   MetadataRecorder::Item item(name_hash, key, thread_id, value);
   for (auto& id_collection_pair : active_collections_) {
@@ -618,9 +618,9 @@
 
 void StackSamplingProfiler::SamplingThread::AddProfileMetadataTask(
     uint64_t name_hash,
-    absl::optional<int64_t> key,
+    std::optional<int64_t> key,
     int64_t value,
-    absl::optional<PlatformThreadId> thread_id) {
+    std::optional<PlatformThreadId> thread_id) {
   DCHECK_EQ(GetThreadId(), PlatformThread::CurrentId());
   MetadataRecorder::Item item(name_hash, key, thread_id, value);
   for (auto& id_collection_pair : active_collections_) {
@@ -938,9 +938,9 @@
     base::TimeTicks period_start,
     base::TimeTicks period_end,
     uint64_t name_hash,
-    absl::optional<int64_t> key,
+    std::optional<int64_t> key,
     int64_t value,
-    absl::optional<PlatformThreadId> thread_id) {
+    std::optional<PlatformThreadId> thread_id) {
   SamplingThread::GetInstance()->ApplyMetadataToPastSamples(
       period_start, period_end, name_hash, key, value, thread_id);
 }
@@ -950,7 +950,7 @@
     uint64_t name_hash,
     int64_t key,
     int64_t value,
-    absl::optional<PlatformThreadId> thread_id) {
+    std::optional<PlatformThreadId> thread_id) {
   SamplingThread::GetInstance()->AddProfileMetadata(name_hash, key, value,
                                                     thread_id);
 }
diff --git a/base/profiler/stack_sampling_profiler.h b/base/profiler/stack_sampling_profiler.h
index f8d27fe1..c5f428b2 100644
--- a/base/profiler/stack_sampling_profiler.h
+++ b/base/profiler/stack_sampling_profiler.h
@@ -6,6 +6,7 @@
 #define BASE_PROFILER_STACK_SAMPLING_PROFILER_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "base/base_export.h"
@@ -15,7 +16,6 @@
 #include "base/synchronization/waitable_event.h"
 #include "base/threading/platform_thread.h"
 #include "base/time/time.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -180,14 +180,13 @@
       TimeTicks period_start,
       TimeTicks period_end,
       uint64_t name_hash,
-      absl::optional<int64_t> key,
+      std::optional<int64_t> key,
       int64_t value,
-      absl::optional<PlatformThreadId> thread_id);
-  friend void AddProfileMetadataImpl(
-      uint64_t name_hash,
-      int64_t key,
-      int64_t value,
-      absl::optional<PlatformThreadId> thread_id);
+      std::optional<PlatformThreadId> thread_id);
+  friend void AddProfileMetadataImpl(uint64_t name_hash,
+                                     int64_t key,
+                                     int64_t value,
+                                     std::optional<PlatformThreadId> thread_id);
 
   // Apply metadata to already recorded samples. See the
   // ApplyMetadataToPastSamples() docs in sample_metadata.h.
@@ -195,15 +194,15 @@
       TimeTicks period_start,
       TimeTicks period_end,
       uint64_t name_hash,
-      absl::optional<int64_t> key,
+      std::optional<int64_t> key,
       int64_t value,
-      absl::optional<PlatformThreadId> thread_id);
+      std::optional<PlatformThreadId> thread_id);
 
   // Adds metadata as metadata global to the sampling profile.
   static void AddProfileMetadata(uint64_t name_hash,
                                  int64_t key,
                                  int64_t value,
-                                 absl::optional<PlatformThreadId> thread_id);
+                                 std::optional<PlatformThreadId> thread_id);
 
   // The thread whose stack will be sampled.
   SamplingProfilerThreadToken thread_token_;
diff --git a/base/profiler/thread_delegate_posix.cc b/base/profiler/thread_delegate_posix.cc
index d70413aa..cc08595 100644
--- a/base/profiler/thread_delegate_posix.cc
+++ b/base/profiler/thread_delegate_posix.cc
@@ -8,10 +8,11 @@
 #include <pthread.h>
 #include <stdio.h>
 
+#include <optional>
+
 #include "base/memory/ptr_util.h"
 #include "base/process/process_handle.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if !(BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS))
 #include "base/profiler/stack_base_address_posix.h"
@@ -21,7 +22,7 @@
 // static
 std::unique_ptr<ThreadDelegatePosix> ThreadDelegatePosix::Create(
     SamplingProfilerThreadToken thread_token) {
-  absl::optional<uintptr_t> base_address;
+  std::optional<uintptr_t> base_address;
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
   base_address = thread_token.stack_base_address;
 #else
diff --git a/base/stl_util_unittest.cc b/base/stl_util_unittest.cc
index 0c99567a..64c89513 100644
--- a/base/stl_util_unittest.cc
+++ b/base/stl_util_unittest.cc
@@ -11,6 +11,7 @@
 #include <initializer_list>
 #include <iterator>
 #include <list>
+#include <optional>
 #include <queue>
 #include <set>
 #include <stack>
@@ -23,7 +24,6 @@
 #include "base/containers/queue.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace {
diff --git a/base/strings/string_number_conversions_internal.h b/base/strings/string_number_conversions_internal.h
index 983c9cd..a7981e66 100644
--- a/base/strings/string_number_conversions_internal.h
+++ b/base/strings/string_number_conversions_internal.h
@@ -9,6 +9,7 @@
 #include <stdlib.h>
 
 #include <limits>
+#include <optional>
 #include <string_view>
 
 #include "base/check.h"
@@ -16,7 +17,6 @@
 #include "base/numerics/safe_math.h"
 #include "base/strings/string_util.h"
 #include "base/third_party/double_conversion/double-conversion/double-conversion.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -57,7 +57,7 @@
 
 // Utility to convert a character to a digit in a given base
 template <int BASE, typename CHAR>
-absl::optional<uint8_t> CharToDigit(CHAR c) {
+std::optional<uint8_t> CharToDigit(CHAR c) {
   static_assert(1 <= BASE && BASE <= 36, "BASE needs to be in [1, 36]");
   if (c >= '0' && c < '0' + std::min(BASE, 10))
     return static_cast<uint8_t>(c - '0');
@@ -68,7 +68,7 @@
   if (c >= 'A' && c < 'A' + BASE - 10)
     return static_cast<uint8_t>(c - 'A' + 10);
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 template <typename Number, int kBase>
@@ -106,7 +106,7 @@
       }
 
       for (Iter current = begin; current != end; ++current) {
-        absl::optional<uint8_t> new_digit = CharToDigit<kBase>(*current);
+        std::optional<uint8_t> new_digit = CharToDigit<kBase>(*current);
 
         if (!new_digit) {
           return {value, false};
@@ -262,9 +262,9 @@
     return false;
   for (uintptr_t i = 0; i < count / 2; ++i) {
     // most significant 4 bits
-    absl::optional<uint8_t> msb = CharToDigit<16>(input[i * 2]);
+    std::optional<uint8_t> msb = CharToDigit<16>(input[i * 2]);
     // least significant 4 bits
-    absl::optional<uint8_t> lsb = CharToDigit<16>(input[i * 2 + 1]);
+    std::optional<uint8_t> lsb = CharToDigit<16>(input[i * 2 + 1]);
     if (!msb || !lsb) {
       return false;
     }
diff --git a/base/strings/string_util.cc b/base/strings/string_util.cc
index 89477b6..ca5d9ff 100644
--- a/base/strings/string_util.cc
+++ b/base/strings/string_util.cc
@@ -15,6 +15,7 @@
 #include <wchar.h>
 
 #include <limits>
+#include <optional>
 #include <string_view>
 #include <type_traits>
 #include <vector>
@@ -28,7 +29,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/third_party/icu/icu_utf.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -391,7 +391,7 @@
     StringPiece16 format_string,
     const std::vector<std::u16string>& subst,
     std::vector<size_t>* offsets) {
-  absl::optional<std::u16string> replacement =
+  std::optional<std::u16string> replacement =
       internal::DoReplaceStringPlaceholders(
           format_string, subst,
           /*placeholder_prefix*/ u'$',
@@ -405,7 +405,7 @@
 std::string ReplaceStringPlaceholders(StringPiece format_string,
                                       const std::vector<std::string>& subst,
                                       std::vector<size_t>* offsets) {
-  absl::optional<std::string> replacement =
+  std::optional<std::string> replacement =
       internal::DoReplaceStringPlaceholders(
           format_string, subst,
           /*placeholder_prefix*/ '$',
diff --git a/base/strings/string_util_impl_helpers.h b/base/strings/string_util_impl_helpers.h
index 8c264dd0..96140e82 100644
--- a/base/strings/string_util_impl_helpers.h
+++ b/base/strings/string_util_impl_helpers.h
@@ -6,6 +6,7 @@
 #define BASE_STRINGS_STRING_UTIL_IMPL_HELPERS_H_
 
 #include <algorithm>
+#include <optional>
 #include <string_view>
 
 #include "base/check.h"
@@ -15,7 +16,6 @@
 #include "base/ranges/algorithm.h"
 #include "base/strings/string_piece.h"
 #include "base/third_party/icu/icu_utf.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base::internal {
 
@@ -508,11 +508,11 @@
 //   instance, with `%` as the `placeholder_prefix`: %%->%, %%%%->%%, etc.
 // * `is_strict_mode`:
 //   * If this parameter is `true`, error handling is stricter. The function
-//   returns `absl::nullopt` if:
+//   returns `std::nullopt` if:
 //     * a placeholder %N is encountered where N > substitutions.size().
 //     * a literal `%` is not escaped with a `%`.
 template <typename T, typename CharT = typename T::value_type>
-absl::optional<std::basic_string<CharT>> DoReplaceStringPlaceholders(
+std::optional<std::basic_string<CharT>> DoReplaceStringPlaceholders(
     T format_string,
     const std::vector<std::basic_string<CharT>>& subst,
     const CharT placeholder_prefix,
@@ -548,7 +548,7 @@
               DLOG(ERROR) << "Invalid placeholder after placeholder prefix: "
                           << std::basic_string<CharT>(1, placeholder_prefix)
                           << std::basic_string<CharT>(1, *i);
-              return absl::nullopt;
+              return std::nullopt;
             }
 
             continue;
@@ -565,12 +565,12 @@
           } else if (is_strict_mode) {
             DLOG(ERROR) << "index out of range: " << index << ": "
                         << substitutions;
-            return absl::nullopt;
+            return std::nullopt;
           }
         }
       } else if (is_strict_mode) {
         DLOG(ERROR) << "unexpected placeholder prefix at end of string";
-        return absl::nullopt;
+        return std::nullopt;
       }
     } else {
       formatted.push_back(*i);
diff --git a/base/strings/string_util_win.cc b/base/strings/string_util_win.cc
index 52e2116..7723fa8 100644
--- a/base/strings/string_util_win.cc
+++ b/base/strings/string_util_win.cc
@@ -4,11 +4,11 @@
 
 #include "base/strings/string_util_win.h"
 
+#include <optional>
 #include <string_view>
 
 #include "base/ranges/algorithm.h"
 #include "base/strings/string_util_impl_helpers.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -133,7 +133,7 @@
 std::wstring ReplaceStringPlaceholders(std::wstring_view format_string,
                                        const std::vector<std::wstring>& subst,
                                        std::vector<size_t>* offsets) {
-  absl::optional<std::wstring> replacement =
+  std::optional<std::wstring> replacement =
       internal::DoReplaceStringPlaceholders(
           format_string, subst,
           /*placeholder_prefix*/ L'$',
diff --git a/base/strings/utf_string_conversion_utils.cc b/base/strings/utf_string_conversion_utils.cc
index a651e1b8..38d54b9a 100644
--- a/base/strings/utf_string_conversion_utils.cc
+++ b/base/strings/utf_string_conversion_utils.cc
@@ -11,14 +11,14 @@
 
 // CountUnicodeCharacters ------------------------------------------------------
 
-absl::optional<size_t> CountUnicodeCharacters(std::string_view text,
-                                              size_t limit) {
+std::optional<size_t> CountUnicodeCharacters(std::string_view text,
+                                             size_t limit) {
   base_icu::UChar32 unused = 0;
   size_t count = 0;
   for (size_t index = 0; count < limit && index < text.size();
        ++count, ++index) {
     if (!ReadUnicodeCharacter(text.data(), text.size(), &index, &unused)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
   return count;
diff --git a/base/strings/utf_string_conversion_utils.h b/base/strings/utf_string_conversion_utils.h
index 3223909..eb43408 100644
--- a/base/strings/utf_string_conversion_utils.h
+++ b/base/strings/utf_string_conversion_utils.h
@@ -12,13 +12,13 @@
 #include <stdint.h>
 
 #include <limits>
+#include <optional>
 #include <string>
 #include <string_view>
 
 #include "base/base_export.h"
 #include "base/third_party/icu/icu_utf.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -46,7 +46,7 @@
 
 // Returns the number of Unicode characters in `text`, up to the supplied
 // `limit`, if `text` contains valid UTF-8. Returns `nullopt` otherwise.
-BASE_EXPORT absl::optional<size_t> CountUnicodeCharacters(
+BASE_EXPORT std::optional<size_t> CountUnicodeCharacters(
     std::string_view text,
     size_t limit = std::numeric_limits<size_t>::max());
 
diff --git a/base/strings/utf_string_conversion_utils_unittest.cc b/base/strings/utf_string_conversion_utils_unittest.cc
index 557eb5e..b2b0822 100644
--- a/base/strings/utf_string_conversion_utils_unittest.cc
+++ b/base/strings/utf_string_conversion_utils_unittest.cc
@@ -15,7 +15,7 @@
   const struct TestCase {
     std::string value;
     size_t limit;
-    absl::optional<size_t> count;
+    std::optional<size_t> count;
   } test_cases[] = {
       {"", 0, 0},
       {"abc", 1, 1},
@@ -26,7 +26,7 @@
       // trigger linter errors about invalid ascii values.
       {reinterpret_cast<const char*>(u8"abc\U0001F4A9"), 4, 4},
       {reinterpret_cast<const char*>(u8"\U0001F4A9"), 1, 1},
-      {{1, static_cast<char>(-1)}, 5, absl::nullopt},
+      {{1, static_cast<char>(-1)}, 5, std::nullopt},
   };
   for (const auto& test_case : test_cases) {
     EXPECT_EQ(CountUnicodeCharacters(test_case.value, test_case.limit),
diff --git a/base/supports_user_data_unittest.cc b/base/supports_user_data_unittest.cc
index d8be714..b638066 100644
--- a/base/supports_user_data_unittest.cc
+++ b/base/supports_user_data_unittest.cc
@@ -134,7 +134,7 @@
     raw_ref<TestSupportsUserData> supports_user_data_;
   };
   {
-    absl::optional<TestSupportsUserData> supports_user_data;
+    std::optional<TestSupportsUserData> supports_user_data;
     supports_user_data.emplace();
     // This awkward construction is required since death tests are typically
     // implemented using `fork()`, so calling `SetUserData()` outside the
diff --git a/base/synchronization/condition_variable_posix.cc b/base/synchronization/condition_variable_posix.cc
index c497ea5..7c0ff41 100644
--- a/base/synchronization/condition_variable_posix.cc
+++ b/base/synchronization/condition_variable_posix.cc
@@ -8,12 +8,13 @@
 #include <stdint.h>
 #include <sys/time.h>
 
+#include <optional>
+
 #include "base/synchronization/lock.h"
 #include "base/threading/scoped_blocking_call.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_APPLE)
 #include <atomic>
@@ -94,7 +95,7 @@
 #endif
 
 void ConditionVariable::Wait() {
-  absl::optional<internal::ScopedBlockingCallWithBaseSyncPrimitives>
+  std::optional<internal::ScopedBlockingCallWithBaseSyncPrimitives>
       scoped_blocking_call;
   if (waiting_is_blocking_)
     scoped_blocking_call.emplace(FROM_HERE, BlockingType::MAY_BLOCK);
@@ -110,7 +111,7 @@
 }
 
 void ConditionVariable::TimedWait(const TimeDelta& max_time) {
-  absl::optional<internal::ScopedBlockingCallWithBaseSyncPrimitives>
+  std::optional<internal::ScopedBlockingCallWithBaseSyncPrimitives>
       scoped_blocking_call;
   if (waiting_is_blocking_)
     scoped_blocking_call.emplace(FROM_HERE, BlockingType::MAY_BLOCK);
diff --git a/base/synchronization/condition_variable_win.cc b/base/synchronization/condition_variable_win.cc
index 9e46acb0..77c5016 100644
--- a/base/synchronization/condition_variable_win.cc
+++ b/base/synchronization/condition_variable_win.cc
@@ -4,14 +4,15 @@
 
 #include "base/synchronization/condition_variable.h"
 
+#include <windows.h>
+
+#include <optional>
+
 #include "base/numerics/safe_conversions.h"
 #include "base/synchronization/lock.h"
 #include "base/threading/scoped_blocking_call.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/time/time.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
-
-#include <windows.h>
 
 namespace base {
 
@@ -32,7 +33,7 @@
 }
 
 void ConditionVariable::TimedWait(const TimeDelta& max_time) {
-  absl::optional<internal::ScopedBlockingCallWithBaseSyncPrimitives>
+  std::optional<internal::ScopedBlockingCallWithBaseSyncPrimitives>
       scoped_blocking_call;
   if (waiting_is_blocking_)
     scoped_blocking_call.emplace(FROM_HERE, BlockingType::MAY_BLOCK);
diff --git a/base/synchronization/lock.h b/base/synchronization/lock.h
index 60ecf17..bfe3bcb 100644
--- a/base/synchronization/lock.h
+++ b/base/synchronization/lock.h
@@ -124,13 +124,13 @@
 using AutoUnlock = internal::BasicAutoUnlock<Lock>;
 
 // Like AutoLock but is a no-op when the provided Lock* is null. Inspired from
-// absl::MutexLockMaybe. Use this instead of absl::optional<base::AutoLock> to
+// absl::MutexLockMaybe. Use this instead of std::optional<base::AutoLock> to
 // get around -Wthread-safety-analysis warnings for conditional locking.
 using AutoLockMaybe = internal::BasicAutoLockMaybe<Lock>;
 
 // Like AutoLock but permits Release() of its mutex before destruction.
 // Release() may be called at most once. Inspired from
-// absl::ReleasableMutexLock. Use this instead of absl::optional<base::AutoLock>
+// absl::ReleasableMutexLock. Use this instead of std::optional<base::AutoLock>
 // to get around -Wthread-safety-analysis warnings for AutoLocks that are
 // explicitly released early (prefer proper scoping to this).
 using ReleasableAutoLock = internal::BasicReleasableAutoLock<Lock>;
diff --git a/base/synchronization/waitable_event.cc b/base/synchronization/waitable_event.cc
index b5a022668..08a9cbf 100644
--- a/base/synchronization/waitable_event.cc
+++ b/base/synchronization/waitable_event.cc
@@ -30,7 +30,7 @@
 
   // Consider this thread blocked for scheduling purposes. Ignore this for
   // non-blocking WaitableEvents.
-  absl::optional<internal::ScopedBlockingCallWithBaseSyncPrimitives>
+  std::optional<internal::ScopedBlockingCallWithBaseSyncPrimitives>
       scoped_blocking_call;
   if (!only_used_while_idle_) {
     scoped_blocking_call.emplace(FROM_HERE, BlockingType::MAY_BLOCK);
diff --git a/base/synchronization/waitable_event_posix.cc b/base/synchronization/waitable_event_posix.cc
index bb290d3..a327528d 100644
--- a/base/synchronization/waitable_event_posix.cc
+++ b/base/synchronization/waitable_event_posix.cc
@@ -2,9 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/synchronization/waitable_event.h"
+
 #include <stddef.h>
 
 #include <limits>
+#include <optional>
 #include <vector>
 
 #include "base/check_op.h"
@@ -12,12 +15,10 @@
 #include "base/ranges/algorithm.h"
 #include "base/synchronization/condition_variable.h"
 #include "base/synchronization/lock.h"
-#include "base/synchronization/waitable_event.h"
 #include "base/threading/scoped_blocking_call.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/time/time.h"
 #include "base/time/time_override.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // -----------------------------------------------------------------------------
 // A WaitableEvent on POSIX is implemented as a wait-list. Currently we don't
diff --git a/base/synchronization/waitable_event_win.cc b/base/synchronization/waitable_event_win.cc
index 5d4f1f6b..232dfa3 100644
--- a/base/synchronization/waitable_event_win.cc
+++ b/base/synchronization/waitable_event_win.cc
@@ -4,11 +4,11 @@
 
 #include "base/synchronization/waitable_event.h"
 
+#include <stddef.h>
 #include <windows.h>
 
-#include <stddef.h>
-
 #include <algorithm>
+#include <optional>
 #include <utility>
 
 #include "base/compiler_specific.h"
@@ -20,7 +20,6 @@
 #include "base/threading/thread_restrictions.h"
 #include "base/time/time.h"
 #include "base/time/time_override.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
diff --git a/base/system/sys_info.cc b/base/system/sys_info.cc
index eaddeabc..9717bdf 100644
--- a/base/system/sys_info.cc
+++ b/base/system/sys_info.cc
@@ -29,7 +29,7 @@
 constexpr uint64_t kLowMemoryDeviceThresholdMB = 2048;
 #endif
 
-absl::optional<uint64_t> g_amount_of_physical_memory_mb_for_testing;
+std::optional<uint64_t> g_amount_of_physical_memory_mb_for_testing;
 }  // namespace
 
 // static
@@ -263,9 +263,9 @@
 }
 
 // static
-absl::optional<uint64_t> SysInfo::SetAmountOfPhysicalMemoryMbForTesting(
+std::optional<uint64_t> SysInfo::SetAmountOfPhysicalMemoryMbForTesting(
     const uint64_t amount_of_memory_mb) {
-  absl::optional<uint64_t> current = g_amount_of_physical_memory_mb_for_testing;
+  std::optional<uint64_t> current = g_amount_of_physical_memory_mb_for_testing;
   g_amount_of_physical_memory_mb_for_testing.emplace(amount_of_memory_mb);
   return current;
 }
diff --git a/base/system/sys_info.h b/base/system/sys_info.h
index 548dec5..9a609a8 100644
--- a/base/system/sys_info.h
+++ b/base/system/sys_info.h
@@ -9,6 +9,7 @@
 #include <stdint.h>
 
 #include <map>
+#include <optional>
 #include <string>
 #include <string_view>
 
@@ -18,7 +19,6 @@
 #include "base/metrics/field_trial_params.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_MAC)
 #include "base/feature_list.h"
@@ -154,7 +154,7 @@
   // Do not add any further callers! When the aforementioned 2022-era hardware
   // is the minimum requirement for Chromium, remove this function and adjust
   // all callers appropriately.
-  static absl::optional<HardwareModelNameSplit> SplitHardwareModelNameDoNotUse(
+  static std::optional<HardwareModelNameSplit> SplitHardwareModelNameDoNotUse(
       std::string_view name);
 #endif
 
@@ -337,7 +337,7 @@
 
   // Sets the amount of physical memory in MB for testing, thus allowing tests
   // to run irrespective of the host machine's configuration.
-  static absl::optional<uint64_t> SetAmountOfPhysicalMemoryMbForTesting(
+  static std::optional<uint64_t> SetAmountOfPhysicalMemoryMbForTesting(
       uint64_t amount_of_memory_mb);
   static void ClearAmountOfPhysicalMemoryMbForTesting();
 };
diff --git a/base/system/sys_info_apple.mm b/base/system/sys_info_apple.mm
index a47f7742..15a1a26 100644
--- a/base/system/sys_info_apple.mm
+++ b/base/system/sys_info_apple.mm
@@ -14,13 +14,13 @@
 namespace internal {
 
 // Queries sysctlbyname() for the given key and returns the 32 bit integer value
-// from the system or absl::nullopt on failure.
+// from the system or std::nullopt on failure.
 // https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/sys/sysctl.h#L1224-L1225
-absl::optional<int> GetSysctlIntValue(const char* key_name) {
+std::optional<int> GetSysctlIntValue(const char* key_name) {
   int value;
   size_t len = sizeof(value);
   if (sysctlbyname(key_name, &value, &len, nullptr, 0) != 0) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   DCHECK_EQ(len, sizeof(value));
   return value;
diff --git a/base/system/sys_info_internal.h b/base/system/sys_info_internal.h
index 0c23b6d3..c4e42c4 100644
--- a/base/system/sys_info_internal.h
+++ b/base/system/sys_info_internal.h
@@ -9,7 +9,7 @@
 #include "build/build_config.h"
 
 #if BUILDFLAG(IS_APPLE)
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include <optional>
 #endif
 
 namespace base {
@@ -34,18 +34,18 @@
 
 #if BUILDFLAG(IS_MAC)
 // Exposed for testing.
-BASE_EXPORT absl::optional<int> NumberOfPhysicalProcessors();
+BASE_EXPORT std::optional<int> NumberOfPhysicalProcessors();
 
 // When CPU security mitigation is enabled, return number of "physical"
 // cores and not the number of "logical" cores. CPU security mitigations
 // disables hyper-threading for the current application, which effectively
 // limits the number of concurrently executing threads to the number of
 // physical cores.
-absl::optional<int> NumberOfProcessorsWhenCpuSecurityMitigationEnabled();
+std::optional<int> NumberOfProcessorsWhenCpuSecurityMitigationEnabled();
 #endif
 
 #if BUILDFLAG(IS_APPLE)
-absl::optional<int> GetSysctlIntValue(const char* key_name);
+std::optional<int> GetSysctlIntValue(const char* key_name);
 #endif
 
 }  // namespace internal
diff --git a/base/system/sys_info_ios.mm b/base/system/sys_info_ios.mm
index be5788d..b8faad3 100644
--- a/base/system/sys_info_ios.mm
+++ b/base/system/sys_info_ios.mm
@@ -80,7 +80,7 @@
 
 // static
 std::string SysInfo::GetIOSBuildNumber() {
-  absl::optional<std::string> build_number =
+  std::optional<std::string> build_number =
       StringSysctl({CTL_KERN, KERN_OSVERSION});
   return build_number.value();
 }
diff --git a/base/system/sys_info_mac.mm b/base/system/sys_info_mac.mm
index 60ead0c..ee5ba58 100644
--- a/base/system/sys_info_mac.mm
+++ b/base/system/sys_info_mac.mm
@@ -12,6 +12,7 @@
 #include <sys/sysctl.h>
 #include <sys/types.h>
 
+#include <optional>
 #include <string_view>
 
 #include "base/apple/scoped_mach_port.h"
@@ -29,7 +30,6 @@
 #include "base/strings/stringprintf.h"
 #include "base/synchronization/lock.h"
 #include "base/system/sys_info_internal.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -46,16 +46,16 @@
 
 namespace internal {
 
-absl::optional<int> NumberOfPhysicalProcessors() {
+std::optional<int> NumberOfPhysicalProcessors() {
   return GetSysctlIntValue("hw.physicalcpu_max");
 }
 
-absl::optional<int> NumberOfProcessorsWhenCpuSecurityMitigationEnabled() {
+std::optional<int> NumberOfProcessorsWhenCpuSecurityMitigationEnabled() {
   g_is_cpu_security_mitigation_enabled_read = true;
 
   if (!g_is_cpu_security_mitigation_enabled ||
       !FeatureList::IsEnabled(kNumberOfCoresWithCpuSecurityMitigation)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return NumberOfPhysicalProcessors();
 }
@@ -145,22 +145,22 @@
 }
 
 // static
-absl::optional<SysInfo::HardwareModelNameSplit>
+std::optional<SysInfo::HardwareModelNameSplit>
 SysInfo::SplitHardwareModelNameDoNotUse(std::string_view name) {
   size_t number_loc = name.find_first_of("0123456789");
   if (number_loc == std::string::npos) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   size_t comma_loc = name.find(',', number_loc);
   if (comma_loc == std::string::npos) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   HardwareModelNameSplit split;
   if (!StringToInt(name.substr(0u, comma_loc).substr(number_loc),
                    &split.model) ||
       !StringToInt(name.substr(comma_loc + 1), &split.variant)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   split.category = name.substr(0u, number_loc);
   return split;
diff --git a/base/system/sys_info_mac_unittest.mm b/base/system/sys_info_mac_unittest.mm
index 68442a9e8..38baa5a0 100644
--- a/base/system/sys_info_mac_unittest.mm
+++ b/base/system/sys_info_mac_unittest.mm
@@ -15,15 +15,15 @@
 using SysInfoMacTest = testing::Test;
 
 TEST_F(SysInfoMacTest, SplitHardwareModelName) {
-  absl::optional<SysInfo::HardwareModelNameSplit> split_name =
+  std::optional<SysInfo::HardwareModelNameSplit> split_name =
       SysInfo::SplitHardwareModelNameDoNotUse("");
-  EXPECT_EQ(absl::nullopt, split_name);
+  EXPECT_EQ(std::nullopt, split_name);
 
   split_name = SysInfo::SplitHardwareModelNameDoNotUse("FooBar");
-  EXPECT_EQ(absl::nullopt, split_name);
+  EXPECT_EQ(std::nullopt, split_name);
 
   split_name = SysInfo::SplitHardwareModelNameDoNotUse("BarFoo77");
-  EXPECT_EQ(absl::nullopt, split_name);
+  EXPECT_EQ(std::nullopt, split_name);
 
   split_name = SysInfo::SplitHardwareModelNameDoNotUse("MacPro4,1");
   EXPECT_EQ("MacPro", split_name.value().category);
diff --git a/base/system/sys_info_posix.cc b/base/system/sys_info_posix.cc
index 69cf95c..3c3b445 100644
--- a/base/system/sys_info_posix.cc
+++ b/base/system/sys_info_posix.cc
@@ -42,7 +42,7 @@
 #endif
 
 #if BUILDFLAG(IS_MAC)
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include <optional>
 #endif
 
 namespace {
@@ -122,7 +122,7 @@
 // static
 int SysInfo::NumberOfProcessors() {
 #if BUILDFLAG(IS_MAC)
-  absl::optional<int> number_of_physical_cores =
+  std::optional<int> number_of_physical_cores =
       internal::NumberOfProcessorsWhenCpuSecurityMitigationEnabled();
   if (number_of_physical_cores.has_value()) {
     return number_of_physical_cores.value();
diff --git a/base/system/sys_info_unittest.cc b/base/system/sys_info_unittest.cc
index 499d2a0c..49a87b4 100644
--- a/base/system/sys_info_unittest.cc
+++ b/base/system/sys_info_unittest.cc
@@ -2,8 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/system/sys_info.h"
+
 #include <stdint.h>
 
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -19,7 +22,6 @@
 #include "base/strings/string_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/system/sys_info.h"
 #include "base/test/scoped_chromeos_version_info.h"
 #include "base/test/scoped_running_on_chromeos.h"
 #include "base/test/task_environment.h"
@@ -30,7 +32,6 @@
 #include "testing/gtest/include/gtest/gtest-death-test.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_WIN)
 #include "base/win/com_init_util.h"
@@ -249,10 +250,10 @@
 
 TEST_F(SysInfoTest, GetHardwareInfo) {
   test::TaskEnvironment task_environment;
-  absl::optional<SysInfo::HardwareInfo> hardware_info;
+  std::optional<SysInfo::HardwareInfo> hardware_info;
 
   auto callback = base::BindOnce(
-      [](absl::optional<SysInfo::HardwareInfo>* target_info,
+      [](std::optional<SysInfo::HardwareInfo>* target_info,
          SysInfo::HardwareInfo info) { *target_info = std::move(info); },
       &hardware_info);
   SysInfo::GetHardwareInfo(std::move(callback));
@@ -276,10 +277,10 @@
 TEST_F(SysInfoTest, GetHardwareInfoWMIMatchRegistry) {
   base::win::ScopedCOMInitializer com_initializer;
   test::TaskEnvironment task_environment;
-  absl::optional<SysInfo::HardwareInfo> hardware_info;
+  std::optional<SysInfo::HardwareInfo> hardware_info;
 
   auto callback = base::BindOnce(
-      [](absl::optional<SysInfo::HardwareInfo>* target_info,
+      [](std::optional<SysInfo::HardwareInfo>* target_info,
          SysInfo::HardwareInfo info) { *target_info = std::move(info); },
       &hardware_info);
   SysInfo::GetHardwareInfo(std::move(callback));
diff --git a/base/task/common/lazy_now.cc b/base/task/common/lazy_now.cc
index 2fbceaa..177dbca 100644
--- a/base/task/common/lazy_now.cc
+++ b/base/task/common/lazy_now.cc
@@ -4,15 +4,16 @@
 
 #include "base/task/common/lazy_now.h"
 
+#include <optional>
+
 #include "base/check.h"
 #include "base/time/tick_clock.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
 LazyNow::LazyNow(TimeTicks now) : now_(now), tick_clock_(nullptr) {}
 
-LazyNow::LazyNow(absl::optional<TimeTicks> now, const TickClock* tick_clock)
+LazyNow::LazyNow(std::optional<TimeTicks> now, const TickClock* tick_clock)
     : now_(now), tick_clock_(tick_clock) {
   DCHECK(tick_clock);
 }
@@ -24,7 +25,7 @@
 LazyNow::LazyNow(LazyNow&& move_from) noexcept
     : now_(move_from.now_), tick_clock_(move_from.tick_clock_) {
   move_from.tick_clock_ = nullptr;
-  move_from.now_ = absl::nullopt;
+  move_from.now_ = std::nullopt;
 }
 
 TimeTicks LazyNow::Now() {
diff --git a/base/task/common/lazy_now.h b/base/task/common/lazy_now.h
index 65db382..1862e15 100644
--- a/base/task/common/lazy_now.h
+++ b/base/task/common/lazy_now.h
@@ -5,10 +5,11 @@
 #ifndef BASE_TASK_COMMON_LAZY_NOW_H_
 #define BASE_TASK_COMMON_LAZY_NOW_H_
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/memory/raw_ptr_exclusion.h"
 #include "base/time/time.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -20,7 +21,7 @@
 class BASE_EXPORT LazyNow {
  public:
   explicit LazyNow(TimeTicks now);
-  explicit LazyNow(absl::optional<TimeTicks> now, const TickClock* tick_clock);
+  explicit LazyNow(std::optional<TimeTicks> now, const TickClock* tick_clock);
   explicit LazyNow(const TickClock* tick_clock);
   LazyNow(const LazyNow&) = delete;
   LazyNow& operator=(const LazyNow&) = delete;
@@ -33,7 +34,7 @@
   bool has_value() const { return !!now_; }
 
  private:
-  absl::optional<TimeTicks> now_;
+  std::optional<TimeTicks> now_;
   // RAW_PTR_EXCLUSION: The pointee doesn't need UaF protection (it has the same
   // lifetime as the thread/sequence).
   RAW_PTR_EXCLUSION const TickClock* tick_clock_;  // Not owned.
diff --git a/base/task/common/task_annotator.cc b/base/task/common/task_annotator.cc
index faa8e8f..37c93874 100644
--- a/base/task/common/task_annotator.cc
+++ b/base/task/common/task_annotator.cc
@@ -390,7 +390,7 @@
   // base::ModuleCache::CreateModuleForAddress is not implemented for it.
   // Thus the below code must be included on a conditional basis.
   const auto ipc_method_address = reinterpret_cast<uintptr_t>(ipc_method_info_);
-  const absl::optional<size_t> location_iid =
+  const std::optional<size_t> location_iid =
       base::trace_event::InternedUnsymbolizedSourceLocation::Get(
           &ctx, ipc_method_address);
   if (location_iid) {
diff --git a/base/task/job_perftest.cc b/base/task/job_perftest.cc
index 1368516..429df71 100644
--- a/base/task/job_perftest.cc
+++ b/base/task/job_perftest.cc
@@ -3,7 +3,9 @@
 // found in the LICENSE file.
 
 #include <stddef.h>
+
 #include <atomic>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -17,7 +19,6 @@
 #include "base/test/task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/perf/perf_result_reporter.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -73,7 +74,7 @@
   IndexGenerator(const IndexGenerator&) = delete;
   IndexGenerator& operator=(const IndexGenerator&) = delete;
 
-  absl::optional<size_t> GetNext() {
+  std::optional<size_t> GetNext() {
     AutoLock auto_lock(lock_);
     if (!pending_indices_.empty()) {
       // Return any pending index first.
@@ -82,7 +83,7 @@
       return index;
     }
     if (ranges_to_split_.empty())
-      return absl::nullopt;
+      return std::nullopt;
 
     // Split the oldest running range in 2 and return the middle index as
     // starting point.
@@ -301,7 +302,7 @@
                WaitableEvent* complete, JobDelegate* delegate) {
               while (work_list->NumIncompleteWorkItems(0) != 0 &&
                      !delegate->ShouldYield()) {
-                absl::optional<size_t> index = generator->GetNext();
+                std::optional<size_t> index = generator->GetNext();
                 if (!index)
                   return;
                 for (size_t i = *index; i < work_list->NumWorkItems(); ++i) {
@@ -358,7 +359,7 @@
                 BindRepeating(
                     [](IndexGenerator* generator, WorkList* work_list,
                        WaitableEvent* complete, JobDelegate* delegate) {
-                      absl::optional<size_t> index = generator->GetNext();
+                      std::optional<size_t> index = generator->GetNext();
                       if (!index)
                         return;
                       size_t i = *index;
diff --git a/base/task/sequence_manager/associated_thread_id.h b/base/task/sequence_manager/associated_thread_id.h
index 18a2bec..a5a9ffc 100644
--- a/base/task/sequence_manager/associated_thread_id.h
+++ b/base/task/sequence_manager/associated_thread_id.h
@@ -7,6 +7,7 @@
 
 #include <atomic>
 #include <memory>
+#include <optional>
 
 #include "base/base_export.h"
 #include "base/memory/ref_counted.h"
@@ -15,7 +16,6 @@
 #include "base/threading/platform_thread.h"
 #include "base/threading/platform_thread_ref.h"
 #include "base/threading/thread_checker.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace sequence_manager {
diff --git a/base/task/sequence_manager/sequence_manager.h b/base/task/sequence_manager/sequence_manager.h
index 85f86aa2..c2c184f 100644
--- a/base/task/sequence_manager/sequence_manager.h
+++ b/base/task/sequence_manager/sequence_manager.h
@@ -247,7 +247,7 @@
   // Returns a wake-up for the next delayed task which is not ripe for
   // execution. If there are no such tasks (immediate tasks don't count),
   // returns nullopt.
-  virtual absl::optional<WakeUp> GetNextDelayedWakeUp() const = 0;
+  virtual std::optional<WakeUp> GetNextDelayedWakeUp() const = 0;
 
   // Sets the SingleThreadTaskRunner that will be returned by
   // SingleThreadTaskRunner::GetCurrentDefault on the main thread.
diff --git a/base/task/sequence_manager/sequence_manager_impl.cc b/base/task/sequence_manager/sequence_manager_impl.cc
index 536b4f6..2813990 100644
--- a/base/task/sequence_manager/sequence_manager_impl.cc
+++ b/base/task/sequence_manager/sequence_manager_impl.cc
@@ -6,6 +6,7 @@
 
 #include <array>
 #include <atomic>
+#include <optional>
 #include <queue>
 #include <vector>
 
@@ -39,7 +40,6 @@
 #include "base/trace_event/base_tracing.h"
 #include "build/build_config.h"
 #include "third_party/abseil-cpp/absl/base/attributes.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace sequence_manager {
@@ -491,7 +491,7 @@
 }
 
 void SequenceManagerImpl::SetNextWakeUp(LazyNow* lazy_now,
-                                        absl::optional<WakeUp> wake_up) {
+                                        std::optional<WakeUp> wake_up) {
   auto next_wake_up = AdjustWakeUp(wake_up, lazy_now);
   if (next_wake_up && next_wake_up->is_immediate()) {
     ScheduleWork();
@@ -524,10 +524,10 @@
   work_tracker_.SetRunTaskSynchronouslyAllowed(can_run_tasks_synchronously);
 }
 
-absl::optional<SequenceManagerImpl::SelectedTask>
+std::optional<SequenceManagerImpl::SelectedTask>
 SequenceManagerImpl::SelectNextTask(LazyNow& lazy_now,
                                     SelectTaskOption option) {
-  absl::optional<SelectedTask> selected_task =
+  std::optional<SelectedTask> selected_task =
       SelectNextTaskImpl(lazy_now, option);
 
   if (selected_task.has_value()) {
@@ -591,7 +591,7 @@
 }
 #endif  // DCHECK_IS_ON() && !BUILDFLAG(IS_NACL)
 
-absl::optional<SequenceManagerImpl::SelectedTask>
+std::optional<SequenceManagerImpl::SelectedTask>
 SequenceManagerImpl::SelectNextTaskImpl(LazyNow& lazy_now,
                                         SelectTaskOption option) {
   DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker);
@@ -618,7 +618,7 @@
                                             /* force_verbose */ false));
 
     if (!work_queue)
-      return absl::nullopt;
+      return std::nullopt;
 
     // If the head task was canceled, remove it and run the selector again.
     if (UNLIKELY(work_queue->RemoveAllCanceledTasksFromFront()))
@@ -686,7 +686,7 @@
           lazy_now);
 }
 
-absl::optional<WakeUp> SequenceManagerImpl::GetPendingWakeUp(
+std::optional<WakeUp> SequenceManagerImpl::GetPendingWakeUp(
     LazyNow* lazy_now,
     SelectTaskOption option) {
   DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker);
@@ -716,26 +716,26 @@
   return AdjustWakeUp(GetNextDelayedWakeUpWithOption(option), lazy_now);
 }
 
-absl::optional<WakeUp> SequenceManagerImpl::GetNextDelayedWakeUp() const {
+std::optional<WakeUp> SequenceManagerImpl::GetNextDelayedWakeUp() const {
   DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker);
   return main_thread_only().wake_up_queue->GetNextDelayedWakeUp();
 }
 
-absl::optional<WakeUp> SequenceManagerImpl::GetNextDelayedWakeUpWithOption(
+std::optional<WakeUp> SequenceManagerImpl::GetNextDelayedWakeUpWithOption(
     SelectTaskOption option) const {
   DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker);
 
   if (option == SelectTaskOption::kSkipDelayedTask)
-    return absl::nullopt;
+    return std::nullopt;
   return GetNextDelayedWakeUp();
 }
 
-absl::optional<WakeUp> SequenceManagerImpl::AdjustWakeUp(
-    absl::optional<WakeUp> wake_up,
+std::optional<WakeUp> SequenceManagerImpl::AdjustWakeUp(
+    std::optional<WakeUp> wake_up,
     LazyNow* lazy_now) const {
   DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker);
   if (!wake_up)
-    return absl::nullopt;
+    return std::nullopt;
   // Overdue work needs to be run immediately.
   if (lazy_now->Now() >= wake_up->earliest_time())
     return WakeUp{};
@@ -744,7 +744,7 @@
   // appearing idle and |time_domain| will decide what to do in
   // MaybeFastForwardToWakeUp().
   if (main_thread_only().time_domain)
-    return absl::nullopt;
+    return std::nullopt;
   return *wake_up;
 }
 
@@ -761,7 +761,7 @@
   // |non_waking_wake_up_queue|).
 #if BUILDFLAG(IS_WIN)
   if (g_explicit_high_resolution_timer_win) {
-    absl::optional<WakeUp> wake_up =
+    std::optional<WakeUp> wake_up =
         main_thread_only().wake_up_queue->GetNextDelayedWakeUp();
     if (!wake_up)
       return false;
diff --git a/base/task/sequence_manager/sequence_manager_impl.h b/base/task/sequence_manager/sequence_manager_impl.h
index 005129d1..89f476e 100644
--- a/base/task/sequence_manager/sequence_manager_impl.h
+++ b/base/task/sequence_manager/sequence_manager_impl.h
@@ -8,6 +8,7 @@
 #include <deque>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
@@ -45,7 +46,6 @@
 #include "base/types/pass_key.h"
 #include "base/values.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -130,17 +130,17 @@
   void PrioritizeYieldingToNative(base::TimeTicks prioritize_until) override;
   void AddTaskObserver(TaskObserver* task_observer) override;
   void RemoveTaskObserver(TaskObserver* task_observer) override;
-  absl::optional<WakeUp> GetNextDelayedWakeUp() const override;
+  std::optional<WakeUp> GetNextDelayedWakeUp() const override;
   TaskQueue::QueuePriority GetPriorityCount() const override;
 
   // SequencedTaskSource implementation:
   void SetRunTaskSynchronouslyAllowed(
       bool can_run_tasks_synchronously) override;
-  absl::optional<SelectedTask> SelectNextTask(
+  std::optional<SelectedTask> SelectNextTask(
       LazyNow& lazy_now,
       SelectTaskOption option = SelectTaskOption::kDefault) override;
   void DidRunTask(LazyNow& lazy_now) override;
-  absl::optional<WakeUp> GetPendingWakeUp(
+  std::optional<WakeUp> GetPendingWakeUp(
       LazyNow* lazy_now,
       SelectTaskOption option = SelectTaskOption::kDefault) override;
   bool HasPendingHighResolutionTasks() override;
@@ -304,7 +304,7 @@
     std::array<char, static_cast<size_t>(debug::CrashKeySize::Size64)>
         async_stack_buffer = {};
 
-    absl::optional<base::MetricsSubSampler> metrics_subsampler;
+    std::optional<base::MetricsSubSampler> metrics_subsampler;
 
     internal::TaskQueueSelector selector;
     ObserverList<TaskObserver>::Unchecked task_observers;
@@ -364,9 +364,9 @@
   void OnExitNestedRunLoop() override;
 
   // Schedules next wake-up at the given time, canceling any previous requests.
-  // Use absl::nullopt to cancel a wake-up. Must be called on the thread this
+  // Use std::nullopt to cancel a wake-up. Must be called on the thread this
   // class was created on.
-  void SetNextWakeUp(LazyNow* lazy_now, absl::optional<WakeUp> wake_up);
+  void SetNextWakeUp(LazyNow* lazy_now, std::optional<WakeUp> wake_up);
 
   // Called before TaskQueue requests to reload its empty immediate work queue.
   void WillRequestReloadImmediateWorkQueue();
@@ -435,21 +435,21 @@
 
   // Helper to terminate all scoped trace events to allow starting new ones
   // in SelectNextTask().
-  absl::optional<SelectedTask> SelectNextTaskImpl(LazyNow& lazy_now,
-                                                  SelectTaskOption option);
+  std::optional<SelectedTask> SelectNextTaskImpl(LazyNow& lazy_now,
+                                                 SelectTaskOption option);
 
   // Returns a wake-up for the next delayed task which is not ripe for
   // execution, or nullopt if `option` is `kSkipDelayedTask` or there
   // are no such tasks (immediate tasks don't count).
-  absl::optional<WakeUp> GetNextDelayedWakeUpWithOption(
+  std::optional<WakeUp> GetNextDelayedWakeUpWithOption(
       SelectTaskOption option) const;
 
   // Given a `wake_up` describing when the next delayed task should run, returns
   // a wake up that should be scheduled on the thread. `is_immediate()` if the
   // wake up should run immediately. `nullopt` if no wake up is required because
   // `wake_up` is `nullopt` or a `time_domain` is used.
-  absl::optional<WakeUp> AdjustWakeUp(absl::optional<WakeUp> wake_up,
-                                      LazyNow* lazy_now) const;
+  std::optional<WakeUp> AdjustWakeUp(std::optional<WakeUp> wake_up,
+                                     LazyNow* lazy_now) const;
 
   void MaybeAddLeewayToTask(Task& task) const;
 
diff --git a/base/task/sequence_manager/sequence_manager_impl_unittest.cc b/base/task/sequence_manager/sequence_manager_impl_unittest.cc
index b2576d5..29b1c50 100644
--- a/base/task/sequence_manager/sequence_manager_impl_unittest.cc
+++ b/base/task/sequence_manager/sequence_manager_impl_unittest.cc
@@ -65,8 +65,9 @@
 #include "testing/gmock/include/gmock/gmock.h"
 
 #if BUILDFLAG(ENABLE_BASE_TRACING)
+#include <optional>
+
 #include "base/test/trace_event_analyzer.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
 
 using base::sequence_manager::EnqueueOrder;
@@ -2483,7 +2484,7 @@
   queue->task_runner()->PostDelayedTask(
       FROM_HERE, BindOnce(&TestTask, 1, &run_order), Milliseconds(10));
   LazyNow lazy_now1(domain.get());
-  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now1));
+  EXPECT_EQ(std::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now1));
   EXPECT_EQ(TimeTicks::Max(), NextPendingTaskTime());
 
   domain->SetNowTicks(sequence_manager()->NowTicks() + Milliseconds(10));
@@ -2536,9 +2537,9 @@
   MOCK_METHOD0(OnHasImmediateTask, void());
   MOCK_METHOD1(GetNextAllowedWakeUp_DesiredWakeUpTime, void(TimeTicks));
 
-  absl::optional<WakeUp> GetNextAllowedWakeUp(
+  std::optional<WakeUp> GetNextAllowedWakeUp(
       LazyNow* lazy_now,
-      absl::optional<WakeUp> next_desired_wake_up,
+      std::optional<WakeUp> next_desired_wake_up,
       bool has_immediate_work) override {
     if (next_desired_wake_up)
       GetNextAllowedWakeUp_DesiredWakeUpTime(next_desired_wake_up->time);
@@ -2547,12 +2548,12 @@
     return next_desired_wake_up;
   }
 
-  void SetNextAllowedWakeUp(absl::optional<WakeUp> next_allowed_wake_up) {
+  void SetNextAllowedWakeUp(std::optional<WakeUp> next_allowed_wake_up) {
     next_allowed_wake_up_ = next_allowed_wake_up;
   }
 
  private:
-  absl::optional<WakeUp> next_allowed_wake_up_;
+  std::optional<WakeUp> next_allowed_wake_up_;
 };
 
 }  // namespace
@@ -3524,9 +3525,9 @@
   auto queue = CreateTaskQueue();
   constexpr TimeDelta kDelay(Milliseconds(10));
   LazyNow lazy_now(mock_tick_clock());
-  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
+  EXPECT_EQ(std::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
   EXPECT_EQ(
-      absl::nullopt,
+      std::nullopt,
       sequence_manager()->GetPendingWakeUp(
           &lazy_now, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));
 
@@ -3541,7 +3542,7 @@
   EXPECT_EQ((WakeUp{lazy_now.Now() + kDelay, kLeeway}),
             sequence_manager()->GetPendingWakeUp(&lazy_now));
   EXPECT_EQ(
-      absl::nullopt,
+      std::nullopt,
       sequence_manager()->GetPendingWakeUp(
           &lazy_now, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));
 
@@ -3553,7 +3554,7 @@
   EXPECT_FALSE(sequence_manager()->SelectNextTask(
       lazy_now2, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));
   EXPECT_EQ(
-      absl::nullopt,
+      std::nullopt,
       sequence_manager()->GetPendingWakeUp(
           &lazy_now2, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));
 
@@ -3561,7 +3562,7 @@
   EXPECT_TRUE(sequence_manager()->SelectNextTask(
       lazy_now2, SequencedTaskSource::SelectTaskOption::kDefault));
   sequence_manager()->DidRunTask(lazy_now2);
-  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now2));
+  EXPECT_EQ(std::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now2));
 }
 
 TEST_P(SequenceManagerTest, DelayedTasksNotSelectedWithImmediateTask) {
@@ -3569,9 +3570,9 @@
   constexpr TimeDelta kDelay(Milliseconds(10));
   LazyNow lazy_now(mock_tick_clock());
 
-  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
+  EXPECT_EQ(std::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
   EXPECT_EQ(
-      absl::nullopt,
+      std::nullopt,
       sequence_manager()->GetPendingWakeUp(
           &lazy_now, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));
 
@@ -3607,7 +3608,7 @@
   EXPECT_FALSE(sequence_manager()->SelectNextTask(
       lazy_now2, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));
   EXPECT_EQ(
-      absl::nullopt,
+      std::nullopt,
       sequence_manager()->GetPendingWakeUp(
           &lazy_now2, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));
 
@@ -3615,7 +3616,7 @@
   EXPECT_TRUE(sequence_manager()->SelectNextTask(
       lazy_now2, SequencedTaskSource::SelectTaskOption::kDefault));
   EXPECT_EQ(
-      absl::nullopt,
+      std::nullopt,
       sequence_manager()->GetPendingWakeUp(
           &lazy_now2, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));
   sequence_manager()->DidRunTask(lazy_now2);
@@ -3667,7 +3668,7 @@
   EXPECT_FALSE(sequence_manager()->SelectNextTask(
       lazy_now2, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));
   EXPECT_EQ(
-      absl::nullopt,
+      std::nullopt,
       sequence_manager()->GetPendingWakeUp(
           &lazy_now2, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));
 
@@ -3679,14 +3680,14 @@
 
   // No delayed tasks can be executed anymore.
   EXPECT_FALSE(sequence_manager()->SelectNextTask(lazy_now2));
-  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now2));
+  EXPECT_EQ(std::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now2));
 }
 
 TEST_P(SequenceManagerTest, GetPendingWakeUp) {
   auto queues = CreateTaskQueues(2u);
 
   LazyNow lazy_now(mock_tick_clock());
-  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
+  EXPECT_EQ(std::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
 
   queues[0]->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                             Seconds(10));
@@ -3720,7 +3721,7 @@
   queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
 
   LazyNow lazy_now(mock_tick_clock());
-  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
+  EXPECT_EQ(std::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
 }
 
 TEST_P(SequenceManagerTest, GetPendingWakeUp_Fence) {
@@ -3730,7 +3731,7 @@
   queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
 
   LazyNow lazy_now(mock_tick_clock());
-  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
+  EXPECT_EQ(std::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
 }
 
 TEST_P(SequenceManagerTest, GetPendingWakeUp_FenceUnblocking) {
@@ -3773,7 +3774,7 @@
   // Canceling the task is not sufficient to ensure it is not considered for the
   // next task time.
   cancelable_closure.Cancel();
-  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
+  EXPECT_EQ(std::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
 }
 
 TEST_P(SequenceManagerTest,
@@ -3812,10 +3813,10 @@
   cancelable_closure_2.Cancel();
 
   // No more valid tasks in any queues.
-  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
+  EXPECT_EQ(std::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
 
   // Test that calling `GetPendingWakeUp()` works when no task is canceled.
-  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
+  EXPECT_EQ(std::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
 }
 
 namespace {
@@ -3958,7 +3959,7 @@
 TEST_P(SequenceManagerTest, GetNextDesiredWakeUp) {
   auto queue = CreateTaskQueue();
 
-  EXPECT_EQ(absl::nullopt, queue->GetNextDesiredWakeUp());
+  EXPECT_EQ(std::nullopt, queue->GetNextDesiredWakeUp());
 
   TimeTicks start_time = sequence_manager()->NowTicks();
   TimeDelta delay1 = Milliseconds(10);
@@ -3974,7 +3975,7 @@
   std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
       queue->CreateQueueEnabledVoter();
   voter->SetVoteToEnable(false);
-  EXPECT_EQ(absl::nullopt, queue->GetNextDesiredWakeUp());
+  EXPECT_EQ(std::nullopt, queue->GetNextDesiredWakeUp());
 
   voter->SetVoteToEnable(true);
   EXPECT_EQ(start_time + delay2, queue->GetNextDesiredWakeUp()->time);
@@ -4758,7 +4759,7 @@
   TimeTicks NowTicks() const override { return now_; }
 
   // TimeDomain:
-  bool MaybeFastForwardToWakeUp(absl::optional<WakeUp> wakeup,
+  bool MaybeFastForwardToWakeUp(std::optional<WakeUp> wakeup,
                                 bool quit_when_idle_requested) override {
     return MaybeFastForwardToWakeUp(quit_when_idle_requested);
   }
@@ -5792,8 +5793,8 @@
 
   SequenceCheckerImpl sequence_checker;
   ThreadCheckerImpl thread_checker;
-  absl::optional<SequenceCheckerImpl> sequence_checker_bound_in_task;
-  absl::optional<ThreadCheckerImpl> thread_checker_bound_in_task;
+  std::optional<SequenceCheckerImpl> sequence_checker_bound_in_task;
+  std::optional<ThreadCheckerImpl> thread_checker_bound_in_task;
 
   EXPECT_TRUE(other_thread_task_runner()->PostTask(
       FROM_HERE, BindLambdaForTesting([&]() {
@@ -5830,8 +5831,8 @@
 
   SequenceCheckerImpl sequence_checker;
   ThreadCheckerImpl thread_checker;
-  absl::optional<SequenceCheckerImpl> sequence_checker_bound_in_task;
-  absl::optional<ThreadCheckerImpl> thread_checker_bound_in_task;
+  std::optional<SequenceCheckerImpl> sequence_checker_bound_in_task;
+  std::optional<ThreadCheckerImpl> thread_checker_bound_in_task;
 
   ThreadPoolInstance::Create("TestPool");
   ThreadPoolInstance::Get()->Start({/* max_num_foreground_threads_in=*/1});
diff --git a/base/task/sequence_manager/sequence_manager_perftest.cc b/base/task/sequence_manager/sequence_manager_perftest.cc
index ff601b6d..bce73084 100644
--- a/base/task/sequence_manager/sequence_manager_perftest.cc
+++ b/base/task/sequence_manager/sequence_manager_perftest.cc
@@ -2,14 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/memory/raw_ptr.h"
 #include "base/task/sequence_manager/sequence_manager.h"
 
 #include <stddef.h>
+
 #include <memory>
+#include <optional>
 
 #include "base/functional/bind.h"
 #include "base/logging.h"
+#include "base/memory/raw_ptr.h"
 #include "base/message_loop/message_pump_default.h"
 #include "base/message_loop/message_pump_type.h"
 #include "base/run_loop.h"
@@ -30,7 +32,6 @@
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/perf/perf_result_reporter.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace sequence_manager {
@@ -58,7 +59,7 @@
   PerfTestTimeDomain& operator=(const PerfTestTimeDomain&) = delete;
   ~PerfTestTimeDomain() override = default;
 
-  bool MaybeFastForwardToWakeUp(absl::optional<WakeUp> wake_up,
+  bool MaybeFastForwardToWakeUp(std::optional<WakeUp> wake_up,
                                 bool quit_when_idle_requested) override {
     if (wake_up) {
       SetNowTicks(wake_up->time);
diff --git a/base/task/sequence_manager/sequenced_task_source.h b/base/task/sequence_manager/sequenced_task_source.h
index e8e3b74..4446721 100644
--- a/base/task/sequence_manager/sequenced_task_source.h
+++ b/base/task/sequence_manager/sequenced_task_source.h
@@ -5,6 +5,8 @@
 #ifndef BASE_TASK_SEQUENCE_MANAGER_SEQUENCED_TASK_SOURCE_H_
 #define BASE_TASK_SEQUENCE_MANAGER_SEQUENCED_TASK_SOURCE_H_
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/functional/callback_helpers.h"
 #include "base/memory/raw_ptr_exclusion.h"
@@ -12,7 +14,6 @@
 #include "base/task/common/lazy_now.h"
 #include "base/task/sequence_manager/task_queue.h"
 #include "base/task/sequence_manager/tasks.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace perfetto {
 class EventContext;
@@ -64,7 +65,7 @@
   // there're no more tasks ready to run. If a task is returned,
   // DidRunTask() must be invoked before the next call to SelectNextTask().
   // |option| allows control on which kind of tasks can be selected.
-  virtual absl::optional<SelectedTask> SelectNextTask(
+  virtual std::optional<SelectedTask> SelectNextTask(
       LazyNow& lazy_now,
       SelectTaskOption option = SelectTaskOption::kDefault) = 0;
 
@@ -76,7 +77,7 @@
   // next task can run immediately, or nullopt if there are no more immediate or
   // delayed tasks. |option| allows control on which kind of tasks can be
   // selected. May delete canceled tasks.
-  virtual absl::optional<WakeUp> GetPendingWakeUp(
+  virtual std::optional<WakeUp> GetPendingWakeUp(
       LazyNow* lazy_now,
       SelectTaskOption option = SelectTaskOption::kDefault) = 0;
 
diff --git a/base/task/sequence_manager/task_order_unittest.cc b/base/task/sequence_manager/task_order_unittest.cc
index d552df1..4551dff 100644
--- a/base/task/sequence_manager/task_order_unittest.cc
+++ b/base/task/sequence_manager/task_order_unittest.cc
@@ -4,10 +4,11 @@
 
 #include "base/task/sequence_manager/task_order.h"
 
+#include <optional>
+
 #include "base/task/sequence_manager/enqueue_order.h"
 #include "base/time/time.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace sequence_manager {
diff --git a/base/task/sequence_manager/task_queue.cc b/base/task/sequence_manager/task_queue.cc
index 75bb6b7..e066f8c 100644
--- a/base/task/sequence_manager/task_queue.cc
+++ b/base/task/sequence_manager/task_queue.cc
@@ -4,6 +4,7 @@
 
 #include "base/task/sequence_manager/task_queue.h"
 
+#include <optional>
 #include <utility>
 
 #include "base/functional/bind.h"
@@ -16,7 +17,6 @@
 #include "base/threading/thread_checker_impl.h"
 #include "base/time/time.h"
 #include "base/trace_event/base_tracing.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base::sequence_manager {
 
diff --git a/base/task/sequence_manager/task_queue.h b/base/task/sequence_manager/task_queue.h
index f828166..ab393f3 100644
--- a/base/task/sequence_manager/task_queue.h
+++ b/base/task/sequence_manager/task_queue.h
@@ -7,6 +7,7 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <type_traits>
 
 #include "base/base_export.h"
@@ -20,7 +21,6 @@
 #include "base/time/time.h"
 #include "base/trace_event/base_tracing.h"
 #include "base/trace_event/base_tracing_forward.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace perfetto {
 class EventContext;
@@ -88,9 +88,9 @@
     // tasks or ripe delayed tasks. The implementation should return the next
     // allowed wake up, or nullopt if no future wake-up is necessary.
     // This is always called on the thread this TaskQueue is associated with.
-    virtual absl::optional<WakeUp> GetNextAllowedWakeUp(
+    virtual std::optional<WakeUp> GetNextAllowedWakeUp(
         LazyNow* lazy_now,
-        absl::optional<WakeUp> next_desired_wake_up,
+        std::optional<WakeUp> next_desired_wake_up,
         bool has_ready_task) = 0;
 
    protected:
@@ -292,7 +292,7 @@
   // such tasks (immediate tasks don't count) or the queue is disabled it
   // returns nullopt.
   // NOTE: this must be called on the thread this TaskQueue was created by.
-  virtual absl::optional<WakeUp> GetNextDesiredWakeUp() = 0;
+  virtual std::optional<WakeUp> GetNextDesiredWakeUp() = 0;
 
   // Can be called on any thread.
   virtual const char* GetName() const = 0;
diff --git a/base/task/sequence_manager/task_queue_impl.cc b/base/task/sequence_manager/task_queue_impl.cc
index 926aba0..0b82ed5 100644
--- a/base/task/sequence_manager/task_queue_impl.cc
+++ b/base/task/sequence_manager/task_queue_impl.cc
@@ -7,6 +7,7 @@
 #include <inttypes.h>
 
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "base/check.h"
@@ -37,7 +38,6 @@
 #include "base/trace_event/base_tracing.h"
 #include "build/build_config.h"
 #include "third_party/abseil-cpp/absl/container/inlined_vector.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace sequence_manager {
@@ -607,7 +607,7 @@
       DCHECK(!task.queue_time.is_null());
       DCHECK(task.delayed_run_time.is_null());
       if (task.queue_time >= main_thread_only().delayed_fence.value()) {
-        main_thread_only().delayed_fence = absl::nullopt;
+        main_thread_only().delayed_fence = std::nullopt;
         DCHECK(!main_thread_only().current_fence);
         main_thread_only().current_fence = Fence(task.task_order());
         // Do not trigger WorkQueueSets notification when taking incoming
@@ -666,10 +666,10 @@
   return !any_thread_.immediate_incoming_queue.empty();
 }
 
-absl::optional<WakeUp> TaskQueueImpl::GetNextDesiredWakeUp() {
+std::optional<WakeUp> TaskQueueImpl::GetNextDesiredWakeUp() {
   // Note we don't scheduled a wake-up for disabled queues.
   if (main_thread_only().delayed_incoming_queue.empty() || !IsQueueEnabled())
-    return absl::nullopt;
+    return std::nullopt;
 
   const auto& top_task = main_thread_only().delayed_incoming_queue.top();
 
@@ -936,9 +936,9 @@
 
 void TaskQueueImpl::InsertFence(Fence current_fence) {
   // Only one fence may be present at a time.
-  main_thread_only().delayed_fence = absl::nullopt;
+  main_thread_only().delayed_fence = std::nullopt;
 
-  absl::optional<Fence> previous_fence = main_thread_only().current_fence;
+  std::optional<Fence> previous_fence = main_thread_only().current_fence;
 
   // Tasks posted after this point will have a strictly higher enqueue order
   // and will be blocked from running.
@@ -981,9 +981,9 @@
 }
 
 void TaskQueueImpl::RemoveFence() {
-  absl::optional<Fence> previous_fence = main_thread_only().current_fence;
-  main_thread_only().current_fence = absl::nullopt;
-  main_thread_only().delayed_fence = absl::nullopt;
+  std::optional<Fence> previous_fence = main_thread_only().current_fence;
+  main_thread_only().current_fence = std::nullopt;
+  main_thread_only().delayed_fence = std::nullopt;
 
   bool front_task_unblocked =
       main_thread_only().immediate_work_queue->RemoveFence();
@@ -1129,7 +1129,7 @@
 
   // Update the |main_thread_only_| struct.
   main_thread_only().is_enabled = enabled;
-  main_thread_only().disabled_time = absl::nullopt;
+  main_thread_only().disabled_time = std::nullopt;
 
   // |sequence_manager_| can be null in tests.
   if (!sequence_manager_)
@@ -1309,7 +1309,7 @@
 }
 
 void TaskQueueImpl::UpdateWakeUp(LazyNow* lazy_now) {
-  absl::optional<WakeUp> wake_up = GetNextDesiredWakeUp();
+  std::optional<WakeUp> wake_up = GetNextDesiredWakeUp();
   if (main_thread_only().throttler && IsQueueEnabled()) {
     // GetNextAllowedWakeUp() may return a non-null wake_up even if |wake_up| is
     // nullopt, e.g. to throttle immediate tasks.
@@ -1320,7 +1320,7 @@
 }
 
 void TaskQueueImpl::SetNextWakeUp(LazyNow* lazy_now,
-                                  absl::optional<WakeUp> wake_up) {
+                                  std::optional<WakeUp> wake_up) {
   if (main_thread_only().scheduled_wake_up == wake_up)
     return;
   main_thread_only().scheduled_wake_up = wake_up;
@@ -1418,7 +1418,7 @@
   if (main_thread_only().delayed_fence.value() > task.delayed_run_time)
     return;
   InsertFence(Fence(task.task_order()));
-  main_thread_only().delayed_fence = absl::nullopt;
+  main_thread_only().delayed_fence = std::nullopt;
 }
 
 void TaskQueueImpl::MaybeReportIpcTaskQueuedFromMainThread(
diff --git a/base/task/sequence_manager/task_queue_impl.h b/base/task/sequence_manager/task_queue_impl.h
index e835f29..98123387 100644
--- a/base/task/sequence_manager/task_queue_impl.h
+++ b/base/task/sequence_manager/task_queue_impl.h
@@ -9,6 +9,7 @@
 
 #include <functional>
 #include <memory>
+#include <optional>
 #include <queue>
 #include <set>
 #include <utility>
@@ -38,7 +39,6 @@
 #include "base/time/time_override.h"
 #include "base/trace_event/base_tracing_forward.h"
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class LazyNow;
@@ -122,7 +122,7 @@
   bool IsEmpty() const override;
   size_t GetNumberOfPendingTasks() const override;
   bool HasTaskToRunImmediatelyOrReadyDelayedTask() const override;
-  absl::optional<WakeUp> GetNextDesiredWakeUp() override;
+  std::optional<WakeUp> GetNextDesiredWakeUp() override;
   void SetQueuePriority(TaskQueue::QueuePriority priority) override;
   TaskQueue::QueuePriority GetQueuePriority() const override;
   void AddTaskObserver(TaskObserver* task_observer) override;
@@ -270,7 +270,7 @@
 
  protected:
   // Sets this queue's next wake up time to |wake_up| in the time domain.
-  void SetNextWakeUp(LazyNow* lazy_now, absl::optional<WakeUp> wake_up);
+  void SetNextWakeUp(LazyNow* lazy_now, std::optional<WakeUp> wake_up);
 
  private:
   friend class WorkQueue;
@@ -424,8 +424,8 @@
     ObserverList<TaskObserver>::Unchecked task_observers;
     HeapHandle heap_handle;
     bool is_enabled = true;
-    absl::optional<Fence> current_fence;
-    absl::optional<TimeTicks> delayed_fence;
+    std::optional<Fence> current_fence;
+    std::optional<TimeTicks> delayed_fence;
     // Snapshots the next sequence number when the queue is unblocked, otherwise
     // it contains EnqueueOrder::none(). If the EnqueueOrder of a task just
     // popped from this queue is greater than this, it means that the queue was
@@ -456,12 +456,12 @@
     TaskExecutionTraceLogger task_execution_trace_logger;
     // Last reported wake up, used only in UpdateWakeUp to avoid
     // excessive calls.
-    absl::optional<WakeUp> scheduled_wake_up;
+    std::optional<WakeUp> scheduled_wake_up;
     // If false, queue will be disabled. Used only for tests.
     bool is_enabled_for_test = true;
     // The time at which the task queue was disabled, if it is currently
     // disabled.
-    absl::optional<TimeTicks> disabled_time;
+    std::optional<TimeTicks> disabled_time;
     // Whether or not the task queue should emit tracing events for tasks
     // posted to this queue when it is disabled.
     bool should_report_posted_tasks_when_disabled = false;
@@ -564,7 +564,7 @@
       TracingOnly();
       ~TracingOnly();
 
-      absl::optional<TimeTicks> disabled_time;
+      std::optional<TimeTicks> disabled_time;
       bool should_report_posted_tasks_when_disabled = false;
     };
 
diff --git a/base/task/sequence_manager/task_queue_selector.cc b/base/task/sequence_manager/task_queue_selector.cc
index 0e364db..d03c098 100644
--- a/base/task/sequence_manager/task_queue_selector.cc
+++ b/base/task/sequence_manager/task_queue_selector.cc
@@ -5,6 +5,7 @@
 #include "base/task/sequence_manager/task_queue_selector.h"
 
 #include <bit>
+#include <optional>
 #include <utility>
 
 #include "base/check_op.h"
@@ -14,7 +15,6 @@
 #include "base/task/task_features.h"
 #include "base/threading/thread_checker.h"
 #include "base/trace_event/base_tracing.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace sequence_manager {
@@ -237,11 +237,11 @@
   task_queue_selector_observer_ = observer;
 }
 
-absl::optional<TaskQueue::QueuePriority>
+std::optional<TaskQueue::QueuePriority>
 TaskQueueSelector::GetHighestPendingPriority(SelectTaskOption option) const {
   DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker);
   if (!active_priority_tracker_.HasActivePriority())
-    return absl::nullopt;
+    return std::nullopt;
 
   TaskQueue::QueuePriority highest_priority =
       active_priority_tracker_.HighestActivePriority();
@@ -256,7 +256,7 @@
     }
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void TaskQueueSelector::SetImmediateStarvationCountForTest(
diff --git a/base/task/sequence_manager/task_queue_selector.h b/base/task/sequence_manager/task_queue_selector.h
index 0bcc9af3..efb3f8f 100644
--- a/base/task/sequence_manager/task_queue_selector.h
+++ b/base/task/sequence_manager/task_queue_selector.h
@@ -8,6 +8,7 @@
 #include <stddef.h>
 
 #include <atomic>
+#include <optional>
 #include <vector>
 
 #include "base/base_export.h"
@@ -19,7 +20,6 @@
 #include "base/task/sequence_manager/task_order.h"
 #include "base/task/sequence_manager/work_queue_sets.h"
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace sequence_manager {
@@ -88,7 +88,7 @@
 
   // Returns the priority of the most important pending task if one exists.
   // O(1).
-  absl::optional<TaskQueue::QueuePriority> GetHighestPendingPriority(
+  std::optional<TaskQueue::QueuePriority> GetHighestPendingPriority(
       SelectTaskOption option = SelectTaskOption::kDefault) const;
 
   // WorkQueueSets::Observer implementation:
@@ -146,14 +146,14 @@
   /*
    * SetOperation is used to configure ChooseWithPriority() and must have:
    *
-   * static absl::optional<WorkQueueAndTaskOrder>
+   * static std::optional<WorkQueueAndTaskOrder>
    * GetWithPriority(const WorkQueueSets& sets,
    *                 TaskQueue::QueuePriority priority);
    */
 
   // The default
   struct SetOperationOldest {
-    static absl::optional<WorkQueueAndTaskOrder> GetWithPriority(
+    static std::optional<WorkQueueAndTaskOrder> GetWithPriority(
         const WorkQueueSets& sets,
         TaskQueue::QueuePriority priority) {
       return sets.GetOldestQueueAndTaskOrderInSet(priority);
@@ -162,7 +162,7 @@
 
 #if DCHECK_IS_ON()
   struct SetOperationRandom {
-    static absl::optional<WorkQueueAndTaskOrder> GetWithPriority(
+    static std::optional<WorkQueueAndTaskOrder> GetWithPriority(
         const WorkQueueSets& sets,
         TaskQueue::QueuePriority priority) {
       return sets.GetRandomQueueAndTaskOrderInSet(priority);
diff --git a/base/task/sequence_manager/tasks.h b/base/task/sequence_manager/tasks.h
index 9a6208f..63168db 100644
--- a/base/task/sequence_manager/tasks.h
+++ b/base/task/sequence_manager/tasks.h
@@ -5,6 +5,8 @@
 #ifndef BASE_TASK_SEQUENCE_MANAGER_TASKS_H_
 #define BASE_TASK_SEQUENCE_MANAGER_TASKS_H_
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/check.h"
 #include "base/containers/intrusive_heap.h"
@@ -14,7 +16,6 @@
 #include "base/task/sequence_manager/delayed_task_handle_delegate.h"
 #include "base/task/sequence_manager/enqueue_order.h"
 #include "base/task/sequenced_task_runner.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
 
 namespace base {
diff --git a/base/task/sequence_manager/test/mock_time_domain.cc b/base/task/sequence_manager/test/mock_time_domain.cc
index 84b26e9..0a79a0b 100644
--- a/base/task/sequence_manager/test/mock_time_domain.cc
+++ b/base/task/sequence_manager/test/mock_time_domain.cc
@@ -4,7 +4,7 @@
 
 #include "base/task/sequence_manager/test/mock_time_domain.h"
 
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include <optional>
 
 namespace base {
 namespace sequence_manager {
@@ -23,7 +23,7 @@
 }
 
 bool MockTimeDomain::MaybeFastForwardToWakeUp(
-    absl::optional<WakeUp> next_wake_up,
+    std::optional<WakeUp> next_wake_up,
     bool quit_when_idle_requested) {
   return false;
 }
diff --git a/base/task/sequence_manager/test/mock_time_domain.h b/base/task/sequence_manager/test/mock_time_domain.h
index 6f728cc9..1a2e1d3 100644
--- a/base/task/sequence_manager/test/mock_time_domain.h
+++ b/base/task/sequence_manager/test/mock_time_domain.h
@@ -5,9 +5,10 @@
 #ifndef BASE_TASK_SEQUENCE_MANAGER_TEST_MOCK_TIME_DOMAIN_H_
 #define BASE_TASK_SEQUENCE_MANAGER_TEST_MOCK_TIME_DOMAIN_H_
 
+#include <optional>
+
 #include "base/task/sequence_manager/time_domain.h"
 #include "base/time/tick_clock.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace sequence_manager {
@@ -27,7 +28,7 @@
   TimeTicks NowTicks() const override;
 
   // TimeDomain implementation:
-  bool MaybeFastForwardToWakeUp(absl::optional<WakeUp> next_wake_up,
+  bool MaybeFastForwardToWakeUp(std::optional<WakeUp> next_wake_up,
                                 bool quit_when_idle_requested) override;
   const char* GetName() const override;
 
diff --git a/base/task/sequence_manager/thread_controller.h b/base/task/sequence_manager/thread_controller.h
index d649671..4d61e76 100644
--- a/base/task/sequence_manager/thread_controller.h
+++ b/base/task/sequence_manager/thread_controller.h
@@ -5,6 +5,7 @@
 #ifndef BASE_TASK_SEQUENCE_MANAGER_THREAD_CONTROLLER_H_
 #define BASE_TASK_SEQUENCE_MANAGER_THREAD_CONTROLLER_H_
 
+#include <optional>
 #include <stack>
 #include <vector>
 
@@ -25,7 +26,6 @@
 #include "base/trace_event/base_tracing.h"
 #include "base/tracing_buildflags.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -102,7 +102,7 @@
   // immediate work into account.
   // TODO(kraynov): Remove |lazy_now| parameter.
   virtual void SetNextDelayedDoWork(LazyNow* lazy_now,
-                                    absl::optional<WakeUp> wake_up) = 0;
+                                    std::optional<WakeUp> wake_up) = 0;
 
   // Sets the sequenced task source from which to take tasks after
   // a Schedule*Work() call is made.
@@ -360,7 +360,7 @@
       // non-null when recording is enabled.
       raw_ptr<HistogramBase> histogram_ = nullptr;
 #if BUILDFLAG(ENABLE_BASE_TRACING)
-      absl::optional<perfetto::Track> perfetto_track_;
+      std::optional<perfetto::Track> perfetto_track_;
 
       // True if tracing was enabled during the last pass of RecordTimeInPhase.
       bool was_tracing_enabled_ = false;
diff --git a/base/task/sequence_manager/thread_controller_impl.cc b/base/task/sequence_manager/thread_controller_impl.cc
index dbb708b..c48ff5fa 100644
--- a/base/task/sequence_manager/thread_controller_impl.cc
+++ b/base/task/sequence_manager/thread_controller_impl.cc
@@ -88,9 +88,8 @@
   }
 }
 
-void ThreadControllerImpl::SetNextDelayedDoWork(
-    LazyNow* lazy_now,
-    absl::optional<WakeUp> wake_up) {
+void ThreadControllerImpl::SetNextDelayedDoWork(LazyNow* lazy_now,
+                                                std::optional<WakeUp> wake_up) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(associated_thread_->sequence_checker);
   DCHECK(sequence_);
   DCHECK(!wake_up || !wake_up->is_immediate());
@@ -167,7 +166,7 @@
   DCHECK(sequence_);
 
   work_deduplicator_.OnWorkStarted();
-  absl::optional<base::TimeTicks> recent_time;
+  std::optional<base::TimeTicks> recent_time;
 
   WeakPtr<ThreadControllerImpl> weak_ptr = weak_factory_.GetWeakPtr();
   for (int i = 0; i < main_sequence_only().work_batch_size_; i++) {
@@ -182,7 +181,7 @@
     run_level_tracker_.OnWorkStarted(lazy_now_select_task);
     int run_depth = static_cast<int>(run_level_tracker_.num_run_levels());
 
-    absl::optional<SequencedTaskSource::SelectedTask> selected_task =
+    std::optional<SequencedTaskSource::SelectedTask> selected_task =
         sequence_->SelectNextTask(lazy_now_select_task);
     LazyNow lazy_now_task_selected(time_source_);
     run_level_tracker_.OnApplicationTaskSelected(
@@ -226,7 +225,7 @@
       // the next loop iteration.
       if (lazy_now_after_run_task.has_value()) {
         recent_time =
-            absl::optional<base::TimeTicks>(lazy_now_after_run_task.Now());
+            std::optional<base::TimeTicks>(lazy_now_after_run_task.Now());
       } else {
         recent_time.reset();
       }
@@ -250,7 +249,7 @@
   work_deduplicator_.WillCheckForMoreWork();
 
   LazyNow lazy_now_after_work(time_source_);
-  absl::optional<WakeUp> next_wake_up =
+  std::optional<WakeUp> next_wake_up =
       sequence_->GetPendingWakeUp(&lazy_now_after_work);
   // The OnIdle() callback allows the TimeDomains to advance virtual time in
   // which case we now have immediate work to do.
diff --git a/base/task/sequence_manager/thread_controller_impl.h b/base/task/sequence_manager/thread_controller_impl.h
index f827311..9ddd0ab 100644
--- a/base/task/sequence_manager/thread_controller_impl.h
+++ b/base/task/sequence_manager/thread_controller_impl.h
@@ -49,7 +49,7 @@
   void ScheduleWork() override;
   void BindToCurrentThread(std::unique_ptr<MessagePump> message_pump) override;
   void SetNextDelayedDoWork(LazyNow* lazy_now,
-                            absl::optional<WakeUp> wake_up) override;
+                            std::optional<WakeUp> wake_up) override;
   void SetSequencedTaskSource(SequencedTaskSource* sequence) override;
   bool RunsTasksInCurrentSequence() override;
   void SetDefaultTaskRunner(scoped_refptr<SingleThreadTaskRunner>) override;
diff --git a/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc b/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc
index d43fd502..07939e77 100644
--- a/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc
+++ b/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 #include <atomic>
+#include <optional>
 #include <utility>
 
 #include "base/auto_reset.h"
@@ -23,7 +24,6 @@
 #include "base/time/time.h"
 #include "base/trace_event/base_tracing.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_IOS)
 #include "base/message_loop/message_pump_apple.h"
@@ -62,7 +62,7 @@
 std::atomic_bool g_run_tasks_by_batches = false;
 std::atomic_bool g_avoid_schedule_calls_during_native_event_processing = false;
 
-base::TimeDelta GetLeewayForWakeUp(absl::optional<WakeUp> wake_up) {
+base::TimeDelta GetLeewayForWakeUp(std::optional<WakeUp> wake_up) {
   if (!wake_up || wake_up->delay_policy == subtle::DelayPolicy::kPrecise) {
     return TimeDelta();
   }
@@ -195,7 +195,7 @@
 
 void ThreadControllerWithMessagePumpImpl::SetNextDelayedDoWork(
     LazyNow* lazy_now,
-    absl::optional<WakeUp> wake_up) {
+    std::optional<WakeUp> wake_up) {
   DCHECK(!wake_up || !wake_up->is_immediate());
   // It's very rare for PostDelayedTask to be called outside of a DoWork in
   // production, so most of the time this does nothing.
@@ -335,7 +335,7 @@
 
   work_deduplicator_.OnWorkStarted();
   LazyNow continuation_lazy_now(time_source_);
-  absl::optional<WakeUp> next_wake_up = DoWorkImpl(&continuation_lazy_now);
+  std::optional<WakeUp> next_wake_up = DoWorkImpl(&continuation_lazy_now);
 
   // If we are yielding after DoWorkImpl (a work batch) set the flag boolean.
   // This will inform the MessagePump to schedule a new continuation based on
@@ -391,7 +391,7 @@
   return next_work_info;
 }
 
-absl::optional<WakeUp> ThreadControllerWithMessagePumpImpl::DoWorkImpl(
+std::optional<WakeUp> ThreadControllerWithMessagePumpImpl::DoWorkImpl(
     LazyNow* continuation_lazy_now) {
   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"),
                "ThreadControllerImpl::DoWork");
@@ -401,7 +401,7 @@
     // helps spot nested loops that intentionally starve application tasks.
     TRACE_EVENT0("base", "ThreadController: application tasks disallowed");
     if (main_thread_only().quit_runloop_after == TimeTicks::Max())
-      return absl::nullopt;
+      return std::nullopt;
     return WakeUp{main_thread_only().quit_runloop_after};
   }
 
@@ -412,11 +412,11 @@
   const base::TimeDelta batch_duration =
       RunsTasksByBatches() ? base::Milliseconds(8) : base::Milliseconds(0);
 
-  const absl::optional<base::TimeTicks> start_time =
+  const std::optional<base::TimeTicks> start_time =
       batch_duration.is_zero()
-          ? absl::nullopt
-          : absl::optional<base::TimeTicks>(time_source_->NowTicks());
-  absl::optional<base::TimeTicks> recent_time = start_time;
+          ? std::nullopt
+          : std::optional<base::TimeTicks>(time_source_->NowTicks());
+  std::optional<base::TimeTicks> recent_time = start_time;
 
   // Loops for |batch_duration|, or |work_batch_size| times if |batch_duration|
   // is zero.
@@ -439,7 +439,7 @@
         power_monitor_.IsProcessInPowerSuspendState()
             ? SequencedTaskSource::SelectTaskOption::kSkipDelayedTask
             : SequencedTaskSource::SelectTaskOption::kDefault;
-    absl::optional<SequencedTaskSource::SelectedTask> selected_task =
+    std::optional<SequencedTaskSource::SelectedTask> selected_task =
         main_thread_only().task_source->SelectNextTask(lazy_now_select_task,
                                                        select_task_option);
     LazyNow lazy_now_task_selected(time_source_);
@@ -507,7 +507,7 @@
   }
 
   if (main_thread_only().quit_pending)
-    return absl::nullopt;
+    return std::nullopt;
 
   work_deduplicator_.WillCheckForMoreWork();
 
@@ -540,7 +540,7 @@
    private:
     const raw_ref<RunLevelTracker> run_level_tracker;
   };
-  absl::optional<OnIdle> on_idle;
+  std::optional<OnIdle> on_idle;
 
   // Must be after `on_idle` as this trace event's scope must end before the END
   // of the "ThreadController active" trace event emitted from
diff --git a/base/task/sequence_manager/thread_controller_with_message_pump_impl.h b/base/task/sequence_manager/thread_controller_with_message_pump_impl.h
index 693f276..ed10d1f 100644
--- a/base/task/sequence_manager/thread_controller_with_message_pump_impl.h
+++ b/base/task/sequence_manager/thread_controller_with_message_pump_impl.h
@@ -6,6 +6,7 @@
 #define BASE_TASK_SEQUENCE_MANAGER_THREAD_CONTROLLER_WITH_MESSAGE_PUMP_IMPL_H_
 
 #include <memory>
+#include <optional>
 
 #include "base/base_export.h"
 #include "base/memory/raw_ptr.h"
@@ -24,7 +25,6 @@
 #include "base/threading/platform_thread.h"
 #include "base/threading/sequence_local_storage_map.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace sequence_manager {
@@ -61,7 +61,7 @@
   void WillQueueTask(PendingTask* pending_task) override;
   void ScheduleWork() override;
   void SetNextDelayedDoWork(LazyNow* lazy_now,
-                            absl::optional<WakeUp> wake_up) override;
+                            std::optional<WakeUp> wake_up) override;
   bool RunsTasksInCurrentSequence() override;
   void SetDefaultTaskRunner(
       scoped_refptr<SingleThreadTaskRunner> task_runner) override;
@@ -152,7 +152,7 @@
   // Returns a WakeUp for the next pending task, is_immediate() if the next task
   // can run immediately, or nullopt if there are no more immediate or delayed
   // tasks.
-  absl::optional<WakeUp> DoWorkImpl(LazyNow* continuation_lazy_now);
+  std::optional<WakeUp> DoWorkImpl(LazyNow* continuation_lazy_now);
 
   bool RunsTasksByBatches() const;
 
@@ -204,7 +204,7 @@
   // the overhead between each work item (no-op if HangWatcher is not enabled
   // on this thread). Cleared when going to sleep and at the end of a Run()
   // (i.e. when Quit()). Nested runs override their parent.
-  absl::optional<WatchHangsInScope> hang_watch_scope_;
+  std::optional<WatchHangsInScope> hang_watch_scope_;
 
   // Can only be set once (just before calling
   // work_deduplicator_.BindToCurrentThread()). After that only read access is
diff --git a/base/task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc b/base/task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc
index 8b90fbf..4335388 100644
--- a/base/task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc
+++ b/base/task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"
 
+#include <optional>
 #include <queue>
 #include <string>
 #include <utility>
@@ -24,7 +25,6 @@
 #include "build/build_config.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using testing::_;
 using testing::Invoke;
@@ -77,7 +77,7 @@
   }
 
   // Optionally emplaced, strict from then on.
-  absl::optional<testing::StrictMock<MockTraceObserver>> trace_observer_;
+  std::optional<testing::StrictMock<MockTraceObserver>> trace_observer_;
 };
 
 class MockMessagePump : public MessagePump {
@@ -125,16 +125,15 @@
   void SetRunTaskSynchronouslyAllowed(
       bool can_run_tasks_synchronously) override {}
 
-  absl::optional<SelectedTask> SelectNextTask(
-      LazyNow& lazy_now,
-      SelectTaskOption option) override {
+  std::optional<SelectedTask> SelectNextTask(LazyNow& lazy_now,
+                                             SelectTaskOption option) override {
     if (tasks_.empty())
-      return absl::nullopt;
+      return std::nullopt;
     if (tasks_.front().delayed_run_time > clock_->NowTicks())
-      return absl::nullopt;
+      return std::nullopt;
     if (option == SequencedTaskSource::SelectTaskOption::kSkipDelayedTask &&
         !tasks_.front().delayed_run_time.is_null()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     task_execution_stack_.push_back(std::move(tasks_.front()));
     tasks_.pop();
@@ -149,13 +148,13 @@
     task_execution_stack_.pop_back();
   }
 
-  absl::optional<WakeUp> GetPendingWakeUp(LazyNow* lazy_now,
-                                          SelectTaskOption option) override {
+  std::optional<WakeUp> GetPendingWakeUp(LazyNow* lazy_now,
+                                         SelectTaskOption option) override {
     if (tasks_.empty())
-      return absl::nullopt;
+      return std::nullopt;
     if (option == SequencedTaskSource::SelectTaskOption::kSkipDelayedTask &&
         !tasks_.front().delayed_run_time.is_null()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (tasks_.front().delayed_run_time.is_null())
       return WakeUp{};
diff --git a/base/task/sequence_manager/time_domain.cc b/base/task/sequence_manager/time_domain.cc
index a795626c..210d829 100644
--- a/base/task/sequence_manager/time_domain.cc
+++ b/base/task/sequence_manager/time_domain.cc
@@ -4,9 +4,10 @@
 
 #include "base/task/sequence_manager/time_domain.h"
 
+#include <optional>
+
 #include "base/task/sequence_manager/sequence_manager_impl.h"
 #include "base/threading/thread_checker.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace sequence_manager {
diff --git a/base/task/sequence_manager/time_domain.h b/base/task/sequence_manager/time_domain.h
index deafaa1..874430b8 100644
--- a/base/task/sequence_manager/time_domain.h
+++ b/base/task/sequence_manager/time_domain.h
@@ -5,6 +5,8 @@
 #ifndef BASE_TASK_SEQUENCE_MANAGER_TIME_DOMAIN_H_
 #define BASE_TASK_SEQUENCE_MANAGER_TIME_DOMAIN_H_
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/check.h"
 #include "base/memory/raw_ptr.h"
@@ -12,7 +14,6 @@
 #include "base/task/sequence_manager/tasks.h"
 #include "base/time/tick_clock.h"
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace sequence_manager {
@@ -35,7 +36,7 @@
   // time domain impl to fast-forward time and return true to indicate that
   // there's more work to run. If RunLoop::QuitWhenIdle has been called then
   // `quit_when_idle_requested` will be true.
-  virtual bool MaybeFastForwardToWakeUp(absl::optional<WakeUp> next_wake_up,
+  virtual bool MaybeFastForwardToWakeUp(std::optional<WakeUp> next_wake_up,
                                         bool quit_when_idle_requested) = 0;
 
   // Debug info.
diff --git a/base/task/sequence_manager/wake_up_queue.cc b/base/task/sequence_manager/wake_up_queue.cc
index 2fce8da..272f112 100644
--- a/base/task/sequence_manager/wake_up_queue.cc
+++ b/base/task/sequence_manager/wake_up_queue.cc
@@ -4,11 +4,12 @@
 
 #include "base/task/sequence_manager/wake_up_queue.h"
 
+#include <optional>
+
 #include "base/task/sequence_manager/associated_thread_id.h"
 #include "base/task/sequence_manager/sequence_manager_impl.h"
 #include "base/task/sequence_manager/task_queue_impl.h"
 #include "base/threading/thread_checker.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace sequence_manager {
@@ -42,13 +43,13 @@
 
 void WakeUpQueue::SetNextWakeUpForQueue(internal::TaskQueueImpl* queue,
                                         LazyNow* lazy_now,
-                                        absl::optional<WakeUp> wake_up) {
+                                        std::optional<WakeUp> wake_up) {
   DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker);
   DCHECK_EQ(queue->wake_up_queue(), this);
   DCHECK(queue->IsQueueEnabled() || !wake_up);
 
-  absl::optional<WakeUp> previous_wake_up = GetNextDelayedWakeUp();
-  absl::optional<WakeUpResolution> previous_queue_resolution;
+  std::optional<WakeUp> previous_wake_up = GetNextDelayedWakeUp();
+  std::optional<WakeUpResolution> previous_queue_resolution;
   if (queue->heap_handle().IsValid()) {
     previous_queue_resolution =
         wake_up_queue_.at(queue->heap_handle()).wake_up.resolution;
@@ -69,7 +70,7 @@
       wake_up_queue_.erase(queue->heap_handle());
   }
 
-  absl::optional<WakeUp> new_wake_up = GetNextDelayedWakeUp();
+  std::optional<WakeUp> new_wake_up = GetNextDelayedWakeUp();
 
   if (previous_queue_resolution &&
       *previous_queue_resolution == WakeUpResolution::kHigh) {
@@ -117,10 +118,10 @@
   }
 }
 
-absl::optional<WakeUp> WakeUpQueue::GetNextDelayedWakeUp() const {
+std::optional<WakeUp> WakeUpQueue::GetNextDelayedWakeUp() const {
   DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker);
   if (wake_up_queue_.empty())
-    return absl::nullopt;
+    return std::nullopt;
   WakeUp wake_up = wake_up_queue_.top().wake_up;
   // `wake_up.resolution` is not meaningful since it may be different from
   // has_pending_high_resolution_tasks(). Return WakeUpResolution::kLow here to
@@ -153,14 +154,14 @@
 DefaultWakeUpQueue::~DefaultWakeUpQueue() = default;
 
 void DefaultWakeUpQueue::OnNextWakeUpChanged(LazyNow* lazy_now,
-                                             absl::optional<WakeUp> wake_up) {
+                                             std::optional<WakeUp> wake_up) {
   sequence_manager_->SetNextWakeUp(lazy_now, wake_up);
 }
 
 void DefaultWakeUpQueue::UnregisterQueue(internal::TaskQueueImpl* queue) {
   DCHECK_EQ(queue->wake_up_queue(), this);
   LazyNow lazy_now(sequence_manager_->main_thread_clock());
-  SetNextWakeUpForQueue(queue, &lazy_now, absl::nullopt);
+  SetNextWakeUpForQueue(queue, &lazy_now, std::nullopt);
 }
 
 const char* DefaultWakeUpQueue::GetName() const {
@@ -174,8 +175,7 @@
 NonWakingWakeUpQueue::~NonWakingWakeUpQueue() = default;
 
 void NonWakingWakeUpQueue::OnNextWakeUpChanged(LazyNow* lazy_now,
-                                               absl::optional<WakeUp> wake_up) {
-}
+                                               std::optional<WakeUp> wake_up) {}
 
 const char* NonWakingWakeUpQueue::GetName() const {
   return "NonWakingWakeUpQueue";
@@ -183,7 +183,7 @@
 
 void NonWakingWakeUpQueue::UnregisterQueue(internal::TaskQueueImpl* queue) {
   DCHECK_EQ(queue->wake_up_queue(), this);
-  SetNextWakeUpForQueue(queue, nullptr, absl::nullopt);
+  SetNextWakeUpForQueue(queue, nullptr, std::nullopt);
 }
 
 }  // namespace internal
diff --git a/base/task/sequence_manager/wake_up_queue.h b/base/task/sequence_manager/wake_up_queue.h
index 4c15b44b..ee54471 100644
--- a/base/task/sequence_manager/wake_up_queue.h
+++ b/base/task/sequence_manager/wake_up_queue.h
@@ -5,6 +5,8 @@
 #ifndef BASE_TASK_SEQUENCE_MANAGER_WAKE_UP_QUEUE_H_
 #define BASE_TASK_SEQUENCE_MANAGER_WAKE_UP_QUEUE_H_
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/check.h"
 #include "base/containers/intrusive_heap.h"
@@ -13,7 +15,6 @@
 #include "base/task/sequence_manager/task_queue_impl.h"
 #include "base/time/time.h"
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace sequence_manager {
@@ -38,7 +39,7 @@
   // Returns a wake-up for the next pending delayed task (pending delayed tasks
   // that are ripe may be ignored). If there are no such tasks (immediate tasks
   // don't count) or queues are disabled it returns nullopt.
-  absl::optional<WakeUp> GetNextDelayedWakeUp() const;
+  std::optional<WakeUp> GetNextDelayedWakeUp() const;
 
   // Debug info.
   Value::Dict AsValue(TimeTicks now) const;
@@ -60,7 +61,7 @@
   // previously set wake up for `queue`.
   void SetNextWakeUpForQueue(internal::TaskQueueImpl* queue,
                              LazyNow* lazy_now,
-                             absl::optional<WakeUp> wake_up);
+                             std::optional<WakeUp> wake_up);
 
   // Remove the TaskQueue from any internal data structures.
   virtual void UnregisterQueue(internal::TaskQueueImpl* queue) = 0;
@@ -74,11 +75,11 @@
   explicit WakeUpQueue(
       scoped_refptr<const internal::AssociatedThreadId> associated_thread);
 
-  // Called every time the next `next_wake_up` changes. absl::nullopt is used to
+  // Called every time the next `next_wake_up` changes. std::nullopt is used to
   // cancel the next wake-up. Subclasses may use this to tell SequenceManager to
   // schedule the next wake-up at the given time.
   virtual void OnNextWakeUpChanged(LazyNow* lazy_now,
-                                   absl::optional<WakeUp> next_wake_up) = 0;
+                                   std::optional<WakeUp> next_wake_up) = 0;
 
   virtual const char* GetName() const = 0;
 
@@ -124,7 +125,7 @@
  private:
   // WakeUpQueue implementation:
   void OnNextWakeUpChanged(LazyNow* lazy_now,
-                           absl::optional<WakeUp> wake_up) override;
+                           std::optional<WakeUp> wake_up) override;
   const char* GetName() const override;
   void UnregisterQueue(internal::TaskQueueImpl* queue) override;
 
@@ -142,7 +143,7 @@
  private:
   // WakeUpQueue implementation:
   void OnNextWakeUpChanged(LazyNow* lazy_now,
-                           absl::optional<WakeUp> wake_up) override;
+                           std::optional<WakeUp> wake_up) override;
   const char* GetName() const override;
   void UnregisterQueue(internal::TaskQueueImpl* queue) override;
 };
diff --git a/base/task/sequence_manager/wake_up_queue_unittest.cc b/base/task/sequence_manager/wake_up_queue_unittest.cc
index f81a582..7a8fd72 100644
--- a/base/task/sequence_manager/wake_up_queue_unittest.cc
+++ b/base/task/sequence_manager/wake_up_queue_unittest.cc
@@ -5,6 +5,7 @@
 #include "base/task/sequence_manager/wake_up_queue.h"
 
 #include <memory>
+#include <optional>
 
 #include "base/memory/ptr_util.h"
 #include "base/message_loop/message_pump.h"
@@ -15,7 +16,6 @@
 #include "base/test/mock_callback.h"
 #include "base/test/simple_test_tick_clock.h"
 #include "testing/gmock/include/gmock/gmock.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using testing::_;
 using testing::AnyNumber;
@@ -50,13 +50,13 @@
   using WakeUpQueue::UnregisterQueue;
 
   void OnNextWakeUpChanged(LazyNow* lazy_now,
-                           absl::optional<WakeUp> wake_up) override {
+                           std::optional<WakeUp> wake_up) override {
     TimeTicks time = wake_up ? wake_up->time : TimeTicks::Max();
     OnNextWakeUpChanged_TimeTicks(time);
   }
   const char* GetName() const override { return "Test"; }
   void UnregisterQueue(internal::TaskQueueImpl* queue) override {
-    SetNextWakeUpForQueue(queue, nullptr, absl::nullopt);
+    SetNextWakeUpForQueue(queue, nullptr, std::nullopt);
   }
 
   internal::TaskQueueImpl* NextScheduledTaskQueue() const {
@@ -386,7 +386,7 @@
 
   EXPECT_CALL(*wake_up_queue_.get(),
               OnNextWakeUpChanged_TimeTicks(TimeTicks::Max()));
-  task_queue_->SetNextWakeUp(&lazy_now, absl::nullopt);
+  task_queue_->SetNextWakeUp(&lazy_now, std::nullopt);
   EXPECT_FALSE(wake_up_queue_->NextScheduledTaskQueue());
 }
 
@@ -412,7 +412,7 @@
   EXPECT_EQ(run_time1, wake_up_queue_->NextScheduledRunTime());
 
   EXPECT_CALL(*wake_up_queue_.get(), OnNextWakeUpChanged_TimeTicks(run_time2));
-  task_queue_->SetNextWakeUp(&lazy_now, absl::nullopt);
+  task_queue_->SetNextWakeUp(&lazy_now, std::nullopt);
   EXPECT_EQ(task_queue2.get(), wake_up_queue_->NextScheduledTaskQueue());
 
   EXPECT_EQ(run_time2, wake_up_queue_->NextScheduledRunTime());
@@ -445,11 +445,11 @@
   EXPECT_TRUE(wake_up_queue_->has_pending_high_resolution_tasks());
 
   // Remove one of the wake-ups.
-  wake_up_queue_->SetNextWakeUpForQueue(&q1, &lazy_now, absl::nullopt);
+  wake_up_queue_->SetNextWakeUpForQueue(&q1, &lazy_now, std::nullopt);
   EXPECT_TRUE(wake_up_queue_->has_pending_high_resolution_tasks());
 
   // Remove the second one too.
-  wake_up_queue_->SetNextWakeUpForQueue(&q2, &lazy_now, absl::nullopt);
+  wake_up_queue_->SetNextWakeUpForQueue(&q2, &lazy_now, std::nullopt);
   EXPECT_FALSE(wake_up_queue_->has_pending_high_resolution_tasks());
 
   // Change a low resolution wake-up to a high resolution one.
@@ -466,8 +466,8 @@
   EXPECT_TRUE(wake_up_queue_->has_pending_high_resolution_tasks());
 
   // Cancel the wake-up twice.
-  wake_up_queue_->SetNextWakeUpForQueue(&q1, &lazy_now, absl::nullopt);
-  wake_up_queue_->SetNextWakeUpForQueue(&q1, &lazy_now, absl::nullopt);
+  wake_up_queue_->SetNextWakeUpForQueue(&q1, &lazy_now, std::nullopt);
+  wake_up_queue_->SetNextWakeUpForQueue(&q1, &lazy_now, std::nullopt);
   EXPECT_FALSE(wake_up_queue_->has_pending_high_resolution_tasks());
 
   // Tidy up.
diff --git a/base/task/sequence_manager/work_queue.cc b/base/task/sequence_manager/work_queue.cc
index 11e44bb..1d702f51 100644
--- a/base/task/sequence_manager/work_queue.cc
+++ b/base/task/sequence_manager/work_queue.cc
@@ -4,6 +4,8 @@
 
 #include "base/task/sequence_manager/work_queue.h"
 
+#include <optional>
+
 #include "base/debug/alias.h"
 #include "base/task/sequence_manager/fence.h"
 #include "base/task/sequence_manager/sequence_manager_impl.h"
@@ -11,7 +13,6 @@
 #include "base/task/sequence_manager/work_queue_sets.h"
 #include "build/build_config.h"
 #include "third_party/abseil-cpp/absl/container/inlined_vector.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace sequence_manager {
@@ -56,9 +57,9 @@
   return tasks_.empty() || tasks_.front().task_order() >= fence_->task_order();
 }
 
-absl::optional<TaskOrder> WorkQueue::GetFrontTaskOrder() const {
+std::optional<TaskOrder> WorkQueue::GetFrontTaskOrder() const {
   if (tasks_.empty() || BlockedByFence())
-    return absl::nullopt;
+    return std::nullopt;
   // Quick sanity check.
   DCHECK(tasks_.front().task_order() <= tasks_.back().task_order())
       << task_queue_->GetName() << " : " << work_queue_sets_->GetName() << " : "
@@ -297,7 +298,7 @@
 
 bool WorkQueue::RemoveFence() {
   bool was_blocked_by_fence = BlockedByFence();
-  fence_ = absl::nullopt;
+  fence_ = std::nullopt;
   if (work_queue_sets_ && !tasks_.empty() && was_blocked_by_fence) {
     work_queue_sets_->OnTaskPushedToEmptyQueue(this);
     return true;
diff --git a/base/task/sequence_manager/work_queue.h b/base/task/sequence_manager/work_queue.h
index 48af3e7..04f78bee 100644
--- a/base/task/sequence_manager/work_queue.h
+++ b/base/task/sequence_manager/work_queue.h
@@ -5,6 +5,8 @@
 #ifndef BASE_TASK_SEQUENCE_MANAGER_WORK_QUEUE_H_
 #define BASE_TASK_SEQUENCE_MANAGER_WORK_QUEUE_H_
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/containers/intrusive_heap.h"
 #include "base/memory/raw_ptr.h"
@@ -12,7 +14,6 @@
 #include "base/task/sequence_manager/sequenced_task_source.h"
 #include "base/task/sequence_manager/task_queue_impl.h"
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace sequence_manager {
@@ -55,7 +56,7 @@
 
   // Returns the front task's TaskOrder if `tasks_` is non-empty and a fence
   // hasn't been reached, otherwise returns nullopt.
-  absl::optional<TaskOrder> GetFrontTaskOrder() const;
+  std::optional<TaskOrder> GetFrontTaskOrder() const;
 
   // Returns the first task in this queue or null if the queue is empty. This
   // method ignores any fences.
@@ -175,7 +176,7 @@
   // an IntrusiveHeap inside the WorkQueueSet.
   HeapHandle heap_handle_;
   const char* const name_;
-  absl::optional<Fence> fence_;
+  std::optional<Fence> fence_;
   const QueueType queue_type_;
 };
 
diff --git a/base/task/sequence_manager/work_queue_sets.cc b/base/task/sequence_manager/work_queue_sets.cc
index 803bb6b..e3b53fc 100644
--- a/base/task/sequence_manager/work_queue_sets.cc
+++ b/base/task/sequence_manager/work_queue_sets.cc
@@ -4,10 +4,11 @@
 
 #include "base/task/sequence_manager/work_queue_sets.h"
 
+#include <optional>
+
 #include "base/check_op.h"
 #include "base/task/sequence_manager/task_order.h"
 #include "base/task/sequence_manager/work_queue.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace sequence_manager {
@@ -30,7 +31,7 @@
   DCHECK(!work_queue->work_queue_sets());
   DCHECK_LT(set_index, work_queue_heaps_.size());
   DCHECK(!work_queue->heap_handle().IsValid());
-  absl::optional<TaskOrder> key = work_queue->GetFrontTaskOrder();
+  std::optional<TaskOrder> key = work_queue->GetFrontTaskOrder();
   work_queue->AssignToWorkQueueSets(this);
   work_queue->AssignSetIndex(set_index);
   if (!key)
@@ -57,7 +58,7 @@
 void WorkQueueSets::ChangeSetIndex(WorkQueue* work_queue, size_t set_index) {
   DCHECK_EQ(this, work_queue->work_queue_sets());
   DCHECK_LT(set_index, work_queue_heaps_.size());
-  absl::optional<TaskOrder> key = work_queue->GetFrontTaskOrder();
+  std::optional<TaskOrder> key = work_queue->GetFrontTaskOrder();
   size_t old_set = work_queue->work_queue_set_index();
   DCHECK_LT(old_set, work_queue_heaps_.size());
   DCHECK_NE(old_set, set_index);
@@ -101,7 +102,7 @@
   // NOTE if this function changes, we need to keep |WorkQueueSets::AddQueue| in
   // sync.
   DCHECK_EQ(this, work_queue->work_queue_sets());
-  absl::optional<TaskOrder> key = work_queue->GetFrontTaskOrder();
+  std::optional<TaskOrder> key = work_queue->GetFrontTaskOrder();
   DCHECK(key);
   size_t set_index = work_queue->work_queue_set_index();
   DCHECK_LT(set_index, work_queue_heaps_.size())
@@ -150,31 +151,31 @@
     observer_->WorkQueueSetBecameEmpty(set_index);
 }
 
-absl::optional<WorkQueueAndTaskOrder>
+std::optional<WorkQueueAndTaskOrder>
 WorkQueueSets::GetOldestQueueAndTaskOrderInSet(size_t set_index) const {
   DCHECK_LT(set_index, work_queue_heaps_.size());
   if (work_queue_heaps_[set_index].empty())
-    return absl::nullopt;
+    return std::nullopt;
   const OldestTaskOrder& oldest = work_queue_heaps_[set_index].top();
   DCHECK(oldest.value->heap_handle().IsValid());
 #if DCHECK_IS_ON()
-  absl::optional<TaskOrder> order = oldest.value->GetFrontTaskOrder();
+  std::optional<TaskOrder> order = oldest.value->GetFrontTaskOrder();
   DCHECK(order && oldest.key == *order);
 #endif
   return WorkQueueAndTaskOrder(*oldest.value, oldest.key);
 }
 
 #if DCHECK_IS_ON()
-absl::optional<WorkQueueAndTaskOrder>
+std::optional<WorkQueueAndTaskOrder>
 WorkQueueSets::GetRandomQueueAndTaskOrderInSet(size_t set_index) const {
   DCHECK_LT(set_index, work_queue_heaps_.size());
   if (work_queue_heaps_[set_index].empty())
-    return absl::nullopt;
+    return std::nullopt;
   const OldestTaskOrder& chosen =
       work_queue_heaps_[set_index].begin()[static_cast<long>(
           Random() % work_queue_heaps_[set_index].size())];
 #if DCHECK_IS_ON()
-  absl::optional<TaskOrder> key = chosen.value->GetFrontTaskOrder();
+  std::optional<TaskOrder> key = chosen.value->GetFrontTaskOrder();
   DCHECK(key && chosen.key == *key);
 #endif
   return WorkQueueAndTaskOrder(*chosen.value, chosen.key);
@@ -190,7 +191,7 @@
 #if DCHECK_IS_ON() || !defined(NDEBUG)
 bool WorkQueueSets::ContainsWorkQueueForTest(
     const WorkQueue* work_queue) const {
-  absl::optional<TaskOrder> task_order = work_queue->GetFrontTaskOrder();
+  std::optional<TaskOrder> task_order = work_queue->GetFrontTaskOrder();
 
   for (const auto& heap : work_queue_heaps_) {
     for (const OldestTaskOrder& heap_value_pair : heap) {
@@ -215,7 +216,7 @@
 void WorkQueueSets::CollectSkippedOverLowerPriorityTasks(
     const internal::WorkQueue* selected_work_queue,
     std::vector<const Task*>* result) const {
-  absl::optional<TaskOrder> task_order =
+  std::optional<TaskOrder> task_order =
       selected_work_queue->GetFrontTaskOrder();
   CHECK(task_order);
   for (size_t priority = selected_work_queue->work_queue_set_index() + 1;
diff --git a/base/task/sequence_manager/work_queue_sets.h b/base/task/sequence_manager/work_queue_sets.h
index 6afb827..a6a22d9 100644
--- a/base/task/sequence_manager/work_queue_sets.h
+++ b/base/task/sequence_manager/work_queue_sets.h
@@ -6,6 +6,7 @@
 #define BASE_TASK_SEQUENCE_MANAGER_WORK_QUEUE_SETS_H_
 
 #include <functional>
+#include <optional>
 #include <vector>
 
 #include "base/base_export.h"
@@ -16,7 +17,6 @@
 #include "base/task/sequence_manager/task_order.h"
 #include "base/task/sequence_manager/task_queue_impl.h"
 #include "base/task/sequence_manager/work_queue.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace sequence_manager {
@@ -75,12 +75,12 @@
   void OnQueueBlocked(WorkQueue* work_queue);
 
   // O(1)
-  absl::optional<WorkQueueAndTaskOrder> GetOldestQueueAndTaskOrderInSet(
+  std::optional<WorkQueueAndTaskOrder> GetOldestQueueAndTaskOrderInSet(
       size_t set_index) const;
 
 #if DCHECK_IS_ON()
   // O(1)
-  absl::optional<WorkQueueAndTaskOrder> GetRandomQueueAndTaskOrderInSet(
+  std::optional<WorkQueueAndTaskOrder> GetRandomQueueAndTaskOrderInSet(
       size_t set_index) const;
 #endif
 
diff --git a/base/task/sequence_manager/work_queue_sets_unittest.cc b/base/task/sequence_manager/work_queue_sets_unittest.cc
index 34a8b28..6f7ea1f7 100644
--- a/base/task/sequence_manager/work_queue_sets_unittest.cc
+++ b/base/task/sequence_manager/work_queue_sets_unittest.cc
@@ -7,6 +7,7 @@
 #include <stddef.h>
 
 #include <memory>
+#include <optional>
 
 #include "base/functional/bind.h"
 #include "base/memory/ptr_util.h"
@@ -17,7 +18,6 @@
 #include "base/task/sequence_manager/work_queue.h"
 #include "base/time/time.h"
 #include "testing/gmock/include/gmock/gmock.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace sequence_manager {
@@ -143,7 +143,7 @@
   size_t set = 1;
   work_queue_sets_->ChangeSetIndex(work_queue, set);
 
-  absl::optional<WorkQueueAndTaskOrder> work_queue_and_task_order =
+  std::optional<WorkQueueAndTaskOrder> work_queue_and_task_order =
       work_queue_sets_->GetOldestQueueAndTaskOrderInSet(set);
   ASSERT_TRUE(work_queue_and_task_order);
   EXPECT_EQ(work_queue, work_queue_and_task_order->queue);
@@ -161,7 +161,7 @@
   work_queue_sets_->ChangeSetIndex(queue1, set);
   work_queue_sets_->ChangeSetIndex(queue2, set);
   work_queue_sets_->ChangeSetIndex(queue3, set);
-  absl::optional<WorkQueueAndTaskOrder> queue_and_order =
+  std::optional<WorkQueueAndTaskOrder> queue_and_order =
       work_queue_sets_->GetOldestQueueAndTaskOrderInSet(set);
   ASSERT_TRUE(queue_and_order);
   EXPECT_EQ(queue3, queue_and_order->queue);
diff --git a/base/task/sequence_manager/work_queue_unittest.cc b/base/task/sequence_manager/work_queue_unittest.cc
index b606834..a7b2651 100644
--- a/base/task/sequence_manager/work_queue_unittest.cc
+++ b/base/task/sequence_manager/work_queue_unittest.cc
@@ -5,7 +5,9 @@
 #include "base/task/sequence_manager/work_queue.h"
 
 #include <stddef.h>
+
 #include <memory>
+#include <optional>
 
 #include "base/functional/bind.h"
 #include "base/task/common/lazy_now.h"
@@ -17,7 +19,6 @@
 #include "base/task/sequence_manager/work_queue_sets.h"
 #include "base/time/time.h"
 #include "testing/gmock/include/gmock/gmock.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace sequence_manager {
@@ -150,7 +151,7 @@
   work_queue_->Push(FakeTaskWithEnqueueOrder(3));
   work_queue_->Push(FakeTaskWithEnqueueOrder(4));
 
-  absl::optional<TaskOrder> task_order = work_queue_->GetFrontTaskOrder();
+  std::optional<TaskOrder> task_order = work_queue_->GetFrontTaskOrder();
   EXPECT_TRUE(task_order);
   EXPECT_EQ(2ull, task_order->enqueue_order());
 }
@@ -392,7 +393,7 @@
   EXPECT_FALSE(work_queue_->BlockedByFence());
 
   // Note until TakeTaskFromWorkQueue() is called we don't hit the fence.
-  absl::optional<TaskOrder> task_order = work_queue_->GetFrontTaskOrder();
+  std::optional<TaskOrder> task_order = work_queue_->GetFrontTaskOrder();
   EXPECT_TRUE(task_order);
   EXPECT_EQ(2ull, task_order->enqueue_order());
 
@@ -527,7 +528,7 @@
   }
   EXPECT_TRUE(work_queue_->RemoveAllCanceledTasksFromFront());
 
-  absl::optional<TaskOrder> task_order = work_queue_->GetFrontTaskOrder();
+  std::optional<TaskOrder> task_order = work_queue_->GetFrontTaskOrder();
   EXPECT_TRUE(task_order);
   EXPECT_EQ(5ull, task_order->enqueue_order());
 }
@@ -544,7 +545,7 @@
     work_queue_->Push(FakeTaskWithEnqueueOrder(5));
     EXPECT_FALSE(work_queue_->RemoveAllCanceledTasksFromFront());
 
-    absl::optional<TaskOrder> task_order = work_queue_->GetFrontTaskOrder();
+    std::optional<TaskOrder> task_order = work_queue_->GetFrontTaskOrder();
     EXPECT_TRUE(task_order);
     EXPECT_EQ(2ull, task_order->enqueue_order());
   }
diff --git a/base/task/sequence_manager/work_tracker_unittest.cc b/base/task/sequence_manager/work_tracker_unittest.cc
index cc8ce41..e9d044a 100644
--- a/base/task/sequence_manager/work_tracker_unittest.cc
+++ b/base/task/sequence_manager/work_tracker_unittest.cc
@@ -4,12 +4,13 @@
 
 #include "base/task/sequence_manager/work_tracker.h"
 
+#include <optional>
+
 #include "base/test/bind.h"
 #include "base/test/test_timeouts.h"
 #include "base/threading/platform_thread.h"
 #include "base/threading/thread.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base::sequence_manager::internal {
 
@@ -46,7 +47,7 @@
   other_thread.Start();
   other_thread.task_runner()->PostTask(
       FROM_HERE, BindLambdaForTesting([&]() {
-        absl::optional<SyncWorkAuthorization> auth =
+        std::optional<SyncWorkAuthorization> auth =
             tracker.TryAcquireSyncWorkAuthorization();
         EXPECT_TRUE(auth->IsValid());
         did_acquire_sync_work_auth.Signal();
@@ -107,7 +108,7 @@
   WorkTracker tracker;
   tracker.SetRunTaskSynchronouslyAllowed(true);
 
-  absl::optional<SyncWorkAuthorization> first =
+  std::optional<SyncWorkAuthorization> first =
       tracker.TryAcquireSyncWorkAuthorization();
   EXPECT_TRUE(first->IsValid());
   SyncWorkAuthorization second = tracker.TryAcquireSyncWorkAuthorization();
@@ -131,7 +132,7 @@
   other_thread.Start();
   other_thread.task_runner()->PostTask(
       FROM_HERE, BindLambdaForTesting([&]() {
-        absl::optional<SyncWorkAuthorization> auth =
+        std::optional<SyncWorkAuthorization> auth =
             tracker.TryAcquireSyncWorkAuthorization();
         EXPECT_TRUE(auth->IsValid());
         did_acquire_sync_work_auth.Signal();
diff --git a/base/task/single_thread_task_executor_unittest.cc b/base/task/single_thread_task_executor_unittest.cc
index e55a874..00a2c3a5 100644
--- a/base/task/single_thread_task_executor_unittest.cc
+++ b/base/task/single_thread_task_executor_unittest.cc
@@ -7,6 +7,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -39,7 +40,6 @@
 #include "build/build_config.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_ANDROID)
 #include "base/android/java_handler_thread.h"
@@ -294,7 +294,7 @@
 // can cause implicit message loops.
 void MessageBoxFunc(TaskList* order, int cookie, bool is_reentrant) {
   order->RecordStart(MESSAGEBOX, cookie);
-  absl::optional<CurrentThread::ScopedAllowApplicationTasksInNativeNestedLoop>
+  std::optional<CurrentThread::ScopedAllowApplicationTasksInNativeNestedLoop>
       maybe_allow_nesting;
   if (is_reentrant)
     maybe_allow_nesting.emplace();
diff --git a/base/task/single_thread_task_runner.h b/base/task/single_thread_task_runner.h
index 2f1d4b5..6659824 100644
--- a/base/task/single_thread_task_runner.h
+++ b/base/task/single_thread_task_runner.h
@@ -5,13 +5,14 @@
 #ifndef BASE_TASK_SINGLE_THREAD_TASK_RUNNER_H_
 #define BASE_TASK_SINGLE_THREAD_TASK_RUNNER_H_
 
+#include <optional>
+
 #include "base/auto_reset.h"
 #include "base/base_export.h"
 #include "base/dcheck_is_on.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/task/sequenced_task_runner.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace blink::scheduler {
 class MainThreadSchedulerImpl;
diff --git a/base/task/thread_pool/delayed_task_manager.cc b/base/task/thread_pool/delayed_task_manager.cc
index 7be6bb0..0d0ddbd 100644
--- a/base/task/thread_pool/delayed_task_manager.cc
+++ b/base/task/thread_pool/delayed_task_manager.cc
@@ -5,6 +5,7 @@
 #include "base/task/thread_pool/delayed_task_manager.h"
 
 #include <algorithm>
+#include <optional>
 
 #include "base/check.h"
 #include "base/feature_list.h"
@@ -14,7 +15,6 @@
 #include "base/task/task_features.h"
 #include "base/task/task_runner.h"
 #include "base/task/thread_pool/task.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace internal {
@@ -162,10 +162,10 @@
   }
 }
 
-absl::optional<TimeTicks> DelayedTaskManager::NextScheduledRunTime() const {
+std::optional<TimeTicks> DelayedTaskManager::NextScheduledRunTime() const {
   CheckedAutoLock auto_lock(queue_lock_);
   if (delayed_task_queue_.empty())
-    return absl::nullopt;
+    return std::nullopt;
   return delayed_task_queue_.top().task.delayed_run_time;
 }
 
diff --git a/base/task/thread_pool/delayed_task_manager.h b/base/task/thread_pool/delayed_task_manager.h
index d000053..6fcae05 100644
--- a/base/task/thread_pool/delayed_task_manager.h
+++ b/base/task/thread_pool/delayed_task_manager.h
@@ -6,6 +6,7 @@
 #define BASE_TASK_THREAD_POOL_DELAYED_TASK_MANAGER_H_
 
 #include <functional>
+#include <optional>
 
 #include "base/base_export.h"
 #include "base/containers/intrusive_heap.h"
@@ -20,7 +21,6 @@
 #include "base/thread_annotations.h"
 #include "base/time/default_tick_clock.h"
 #include "base/time/tick_clock.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -57,7 +57,7 @@
   void ProcessRipeTasks();
 
   // Returns the |delayed_run_time| of the next scheduled task, if any.
-  absl::optional<TimeTicks> NextScheduledRunTime() const;
+  std::optional<TimeTicks> NextScheduledRunTime() const;
 
   // Returns the DelayPolicy for the next delayed task.
   subtle::DelayPolicy TopTaskDelayPolicyForTesting() const;
diff --git a/base/task/thread_pool/job_task_source.cc b/base/task/thread_pool/job_task_source.cc
index be531a9f..aeaf7e44 100644
--- a/base/task/thread_pool/job_task_source.cc
+++ b/base/task/thread_pool/job_task_source.cc
@@ -407,14 +407,13 @@
   return true;
 }
 
-absl::optional<Task> JobTaskSource::Clear(
-    TaskSource::Transaction* transaction) {
+std::optional<Task> JobTaskSource::Clear(TaskSource::Transaction* transaction) {
   Cancel();
 
   // Nothing is cleared since other workers might still racily run tasks. For
   // simplicity, the destructor will take care of it once all references are
   // released.
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace internal
diff --git a/base/task/thread_pool/job_task_source.h b/base/task/thread_pool/job_task_source.h
index 107052c..a6adcb0 100644
--- a/base/task/thread_pool/job_task_source.h
+++ b/base/task/thread_pool/job_task_source.h
@@ -196,7 +196,7 @@
   // TaskSource:
   RunStatus WillRunTask() override;
   Task TakeTask(TaskSource::Transaction* transaction) override;
-  absl::optional<Task> Clear(TaskSource::Transaction* transaction) override;
+  std::optional<Task> Clear(TaskSource::Transaction* transaction) override;
   bool DidProcessTask(TaskSource::Transaction* transaction) override;
   bool WillReEnqueue(TimeTicks now,
                      TaskSource::Transaction* transaction) override;
diff --git a/base/task/thread_pool/sequence.cc b/base/task/thread_pool/sequence.cc
index 9ff5e35..e7117ce 100644
--- a/base/task/thread_pool/sequence.cc
+++ b/base/task/thread_pool/sequence.cc
@@ -296,7 +296,7 @@
   return TS_UNCHECKED_READ(latest_ready_time_).load(std::memory_order_relaxed);
 }
 
-absl::optional<Task> Sequence::Clear(TaskSource::Transaction* transaction) {
+std::optional<Task> Sequence::Clear(TaskSource::Transaction* transaction) {
   CheckedAutoLockMaybe auto_lock(transaction ? nullptr : &lock_);
   AnnotateLockAcquired annotate(lock_);
 
diff --git a/base/task/thread_pool/sequence.h b/base/task/thread_pool/sequence.h
index c8de9bb6..dc2ad3f 100644
--- a/base/task/thread_pool/sequence.h
+++ b/base/task/thread_pool/sequence.h
@@ -131,7 +131,7 @@
   // TaskSource:
   RunStatus WillRunTask() override;
   Task TakeTask(TaskSource::Transaction* transaction) override;
-  absl::optional<Task> Clear(TaskSource::Transaction* transaction) override;
+  std::optional<Task> Clear(TaskSource::Transaction* transaction) override;
   bool DidProcessTask(TaskSource::Transaction* transaction) override;
   bool WillReEnqueue(TimeTicks now,
                      TaskSource::Transaction* transaction) override;
diff --git a/base/task/thread_pool/sequence_unittest.cc b/base/task/thread_pool/sequence_unittest.cc
index 84a7bf14..cf73c9a 100644
--- a/base/task/thread_pool/sequence_unittest.cc
+++ b/base/task/thread_pool/sequence_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "base/task/thread_pool/sequence.h"
 
+#include <optional>
 #include <utility>
 
 #include "base/functional/bind.h"
@@ -13,7 +14,6 @@
 #include "base/time/time.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace internal {
@@ -75,7 +75,7 @@
   auto registered_task_source =
       RegisteredTaskSource::CreateForTesting(sequence);
   registered_task_source.WillRunTask();
-  absl::optional<Task> task =
+  std::optional<Task> task =
       registered_task_source.TakeTask(&sequence_transaction);
   ExpectMockTask(&mock_task_a, &task.value());
   EXPECT_FALSE(task->queue_time.is_null());
@@ -285,7 +285,7 @@
   EXPECT_TRUE(sequence->has_worker_for_testing());
 
   // The next task we get when we call Sequence::TakeTask should be Task A.
-  absl::optional<Task> task_a =
+  std::optional<Task> task_a =
       registered_task_source.TakeTask(&sequence_transaction);
 
   // Push task B into the sequence. WillPushImmediateTask() should return false.
@@ -308,7 +308,7 @@
   registered_task_source.WillRunTask();
 
   // The next task we get when we call Sequence::TakeTask should be Task B.
-  absl::optional<Task> task_b =
+  std::optional<Task> task_b =
       registered_task_source.TakeTask(&sequence_transaction);
 
   // Remove the empty slot. Sequence is be empty. This should return false.
@@ -364,7 +364,7 @@
   registered_task_source.WillRunTask();
 
   // Take the task in front of the sequence. It should be task B.
-  absl::optional<Task> task =
+  std::optional<Task> task =
       registered_task_source.TakeTask(&sequence_transaction);
   ExpectMockTask(&mock_task_b, &task.value());
   EXPECT_FALSE(task->queue_time.is_null());
@@ -485,7 +485,7 @@
   EXPECT_TRUE(sequence->has_worker_for_testing());
 
   // Take the task in front of the sequence. It should be task B.
-  absl::optional<Task> task =
+  std::optional<Task> task =
       registered_task_source.TakeTask(&sequence_transaction);
   ExpectMockTask(&mock_task_b, &task.value());
   EXPECT_FALSE(task->queue_time.is_null());
@@ -624,7 +624,7 @@
   auto registered_task_source =
       RegisteredTaskSource::CreateForTesting(sequence);
   registered_task_source.WillRunTask();
-  absl::optional<Task> take_delayed_task =
+  std::optional<Task> take_delayed_task =
       registered_task_source.TakeTask(&sequence_transaction);
   ExpectMockTask(&mock_task_a, &take_delayed_task.value());
   EXPECT_FALSE(take_delayed_task->queue_time.is_null());
@@ -645,7 +645,7 @@
   // Take the immediate task from the sequence, so that its queue time
   // is available for the check below.
   registered_task_source.WillRunTask();
-  absl::optional<Task> take_immediate_task =
+  std::optional<Task> take_immediate_task =
       registered_task_source.TakeTask(&sequence_transaction);
   ExpectMockTask(&mock_task_b, &take_immediate_task.value());
   EXPECT_FALSE(take_immediate_task->queue_time.is_null());
@@ -690,7 +690,7 @@
   auto registered_task_source =
       RegisteredTaskSource::CreateForTesting(sequence);
   registered_task_source.WillRunTask();
-  absl::optional<Task> task =
+  std::optional<Task> task =
       registered_task_source.TakeTask(&sequence_transaction);
   ExpectMockTask(&mock_task_b, &task.value());
   EXPECT_FALSE(task->queue_time.is_null());
diff --git a/base/task/thread_pool/task_source.cc b/base/task/thread_pool/task_source.cc
index 315dcd1..e8af7f0 100644
--- a/base/task/thread_pool/task_source.cc
+++ b/base/task/thread_pool/task_source.cc
@@ -151,7 +151,7 @@
   return task_source_->TakeTask(transaction);
 }
 
-absl::optional<Task> RegisteredTaskSource::Clear(
+std::optional<Task> RegisteredTaskSource::Clear(
     TaskSource::Transaction* transaction) {
   DCHECK(!transaction || transaction->task_source() == get());
   return task_source_->Clear(transaction);
diff --git a/base/task/thread_pool/task_source.h b/base/task/thread_pool/task_source.h
index 42a6b2bc..739bcbc 100644
--- a/base/task/thread_pool/task_source.h
+++ b/base/task/thread_pool/task_source.h
@@ -232,7 +232,7 @@
   // The implementation needs to support this being called multiple times;
   // unless it guarantees never to hand-out multiple RegisteredTaskSources that
   // are concurrently ready.
-  virtual absl::optional<Task> Clear(TaskSource::Transaction* transaction) = 0;
+  virtual std::optional<Task> Clear(TaskSource::Transaction* transaction) = 0;
 
   // Sets TaskSource priority to |priority|.
   void UpdatePriority(TaskPriority priority);
@@ -320,7 +320,7 @@
   // Returns a task that clears this TaskSource to make it empty. |transaction|
   // is optional and should only be provided if this operation is already part
   // of a transaction.
-  [[nodiscard]] absl::optional<Task> Clear(
+  [[nodiscard]] std::optional<Task> Clear(
       TaskSource::Transaction* transaction = nullptr);
 
  private:
diff --git a/base/task/thread_pool/task_tracker.cc b/base/task/thread_pool/task_tracker.cc
index 7bebac25..5a4cbde 100644
--- a/base/task/thread_pool/task_tracker.cc
+++ b/base/task/thread_pool/task_tracker.cc
@@ -5,6 +5,7 @@
 #include "base/task/thread_pool/task_tracker.h"
 
 #include <atomic>
+#include <optional>
 #include <string>
 #include <utility>
 
@@ -34,7 +35,6 @@
 #include "base/values.h"
 #include "build/build_config.h"
 #include "third_party/abseil-cpp/absl/base/attributes.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace internal {
@@ -398,7 +398,7 @@
   const bool should_run_tasks = BeforeRunTask(task_source->shutdown_behavior());
 
   // Run the next task in |task_source|.
-  absl::optional<Task> task;
+  std::optional<Task> task;
   TaskTraits traits;
   {
     auto transaction = task_source->BeginTransaction();
@@ -462,10 +462,10 @@
       DCHECK_EQ(fizzle_block_shutdown_tasks_ref, 0);
     }
   };
-  absl::optional<ScopedDisallowSingleton> disallow_singleton;
-  absl::optional<ScopedDisallowBlocking> disallow_blocking;
-  absl::optional<ScopedDisallowBaseSyncPrimitives> disallow_sync_primitives;
-  absl::optional<BlockShutdownTaskFizzler> fizzle_block_shutdown_tasks;
+  std::optional<ScopedDisallowSingleton> disallow_singleton;
+  std::optional<ScopedDisallowBlocking> disallow_blocking;
+  std::optional<ScopedDisallowBaseSyncPrimitives> disallow_sync_primitives;
+  std::optional<BlockShutdownTaskFizzler> fizzle_block_shutdown_tasks;
   if (traits.shutdown_behavior() ==
       TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) {
     disallow_singleton.emplace();
@@ -485,7 +485,7 @@
         scoped_set_task_priority_for_current_thread(traits.priority());
 
     // Local storage map used if none is provided by |environment|.
-    absl::optional<SequenceLocalStorageMap> local_storage_map;
+    std::optional<SequenceLocalStorageMap> local_storage_map;
     if (!environment.sequence_local_storage)
       local_storage_map.emplace();
 
@@ -497,9 +497,9 @@
 
     // Set up TaskRunner CurrentDefaultHandle as expected for the scope of the
     // task.
-    absl::optional<SequencedTaskRunner::CurrentDefaultHandle>
+    std::optional<SequencedTaskRunner::CurrentDefaultHandle>
         sequenced_task_runner_current_default_handle;
-    absl::optional<SingleThreadTaskRunner::CurrentDefaultHandle>
+    std::optional<SingleThreadTaskRunner::CurrentDefaultHandle>
         single_thread_task_runner_current_default_handle;
     if (environment.sequenced_task_runner) {
       DCHECK_EQ(TaskSourceExecutionMode::kSequenced,
diff --git a/base/task/thread_pool/thread_group.cc b/base/task/thread_pool/thread_group.cc
index 91d68d6..c33900d 100644
--- a/base/task/thread_pool/thread_group.cc
+++ b/base/task/thread_pool/thread_group.cc
@@ -162,7 +162,7 @@
     WorkerThreadObserver* worker_thread_observer,
     WorkerEnvironment worker_environment,
     bool synchronous_thread_start_for_testing,
-    absl::optional<TimeDelta> may_block_threshold) {
+    std::optional<TimeDelta> may_block_threshold) {
   DCHECK(!replacement_thread_group_);
 
   if (synchronous_thread_start_for_testing) {
diff --git a/base/task/thread_pool/thread_group.h b/base/task/thread_pool/thread_group.h
index ea9b1a3e..a42a147 100644
--- a/base/task/thread_pool/thread_group.h
+++ b/base/task/thread_pool/thread_group.h
@@ -6,6 +6,7 @@
 #define BASE_TASK_THREAD_POOL_THREAD_GROUP_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -21,7 +22,6 @@
 #include "base/task/thread_pool/worker_thread.h"
 #include "build/build_config.h"
 #include "third_party/abseil-cpp/absl/container/inlined_vector.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_WIN)
 #include "base/win/scoped_windows_thread_environment.h"
@@ -90,8 +90,8 @@
       WorkerThreadObserver* worker_thread_observer,
       WorkerEnvironment worker_environment,
       bool synchronous_thread_start_for_testing = false,
-      absl::optional<TimeDelta> may_block_threshold =
-          absl::optional<TimeDelta>()) = 0;
+      std::optional<TimeDelta> may_block_threshold =
+          std::optional<TimeDelta>()) = 0;
 
   // Registers the thread group in TLS.
   void BindToCurrentThread();
@@ -212,8 +212,8 @@
       WorkerThreadObserver* worker_thread_observer,
       WorkerEnvironment worker_environment,
       bool synchronous_thread_start_for_testing = false,
-      absl::optional<TimeDelta> may_block_threshold =
-          absl::optional<TimeDelta>());
+      std::optional<TimeDelta> may_block_threshold =
+          std::optional<TimeDelta>());
 
   // Derived classes must implement a ScopedCommandsExecutor that derives from
   // this to perform operations at the end of a scope, when all locks have been
@@ -265,7 +265,7 @@
    private:
     // A RegisteredTaskSourceAndTransaction and the thread group in which it
     // should be enqueued.
-    absl::optional<RegisteredTaskSourceAndTransaction>
+    std::optional<RegisteredTaskSourceAndTransaction>
         transaction_with_task_source_;
     raw_ptr<ThreadGroup> destination_thread_group_ = nullptr;
   };
@@ -529,7 +529,7 @@
   // Null-opt unless |synchronous_thread_start_for_testing| was true at
   // construction. In that case, it's signaled each time
   // WorkerThreadDelegateImpl::OnMainEntry() completes.
-  absl::optional<WaitableEvent> worker_started_for_testing_;
+  std::optional<WaitableEvent> worker_started_for_testing_;
 
   // Set at the start of JoinForTesting().
   bool join_for_testing_started_ GUARDED_BY(lock_) = false;
diff --git a/base/task/thread_pool/thread_group_impl.cc b/base/task/thread_pool/thread_group_impl.cc
index cb0abdf8..3698c15 100644
--- a/base/task/thread_pool/thread_group_impl.cc
+++ b/base/task/thread_pool/thread_group_impl.cc
@@ -4,6 +4,8 @@
 
 #include "base/task/thread_pool/thread_group_impl.h"
 
+#include <optional>
+
 #include "base/auto_reset.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/sequence_token.h"
@@ -17,7 +19,6 @@
 #include "base/time/time_override.h"
 #include "base/trace_event/base_tracing.h"
 #include "third_party/abseil-cpp/absl/container/inlined_vector.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace internal {
@@ -134,7 +135,7 @@
     WorkerThreadObserver* worker_thread_observer,
     WorkerEnvironment worker_environment,
     bool synchronous_thread_start_for_testing,
-    absl::optional<TimeDelta> may_block_threshold) {
+    std::optional<TimeDelta> may_block_threshold) {
   ThreadGroup::StartImpl(
       max_tasks, max_best_effort_tasks, suggested_reclaim_time,
       service_thread_task_runner, worker_thread_observer, worker_environment,
@@ -279,7 +280,7 @@
   // A transaction to the TaskSource to reenqueue, if any. Instantiated here as
   // |TaskSource::lock_| is a UniversalPredecessor and must always be acquired
   // prior to acquiring a second lock
-  absl::optional<RegisteredTaskSourceAndTransaction>
+  std::optional<RegisteredTaskSourceAndTransaction>
       transaction_with_task_source;
   if (task_source) {
     transaction_with_task_source.emplace(
@@ -319,8 +320,8 @@
   // Running task bookkeeping.
   outer()->DecrementTasksRunningLockRequired(
       *read_worker().current_task_priority);
-  write_worker().current_shutdown_behavior = absl::nullopt;
-  write_worker().current_task_priority = absl::nullopt;
+  write_worker().current_shutdown_behavior = std::nullopt;
+  write_worker().current_task_priority = std::nullopt;
 
   if (transaction_with_task_source) {
     outer()->ReEnqueueTaskSourceLockRequired(
diff --git a/base/task/thread_pool/thread_group_impl.h b/base/task/thread_pool/thread_group_impl.h
index e2edf28..03b81d9 100644
--- a/base/task/thread_pool/thread_group_impl.h
+++ b/base/task/thread_pool/thread_group_impl.h
@@ -5,6 +5,7 @@
 #ifndef BASE_TASK_THREAD_POOL_THREAD_GROUP_IMPL_H_
 #define BASE_TASK_THREAD_POOL_THREAD_GROUP_IMPL_H_
 
+#include <optional>
 #include <vector>
 
 #include "base/base_export.h"
@@ -19,7 +20,6 @@
 #include "base/task/thread_pool/worker_thread_set.h"
 #include "base/task/thread_pool/worker_thread_waitable_event.h"
 #include "base/time/time.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -66,8 +66,8 @@
              WorkerThreadObserver* worker_thread_observer,
              WorkerEnvironment worker_environment,
              bool synchronous_thread_start_for_testing = false,
-             absl::optional<TimeDelta> may_block_threshold =
-                 absl::optional<TimeDelta>()) override;
+             std::optional<TimeDelta> may_block_threshold =
+                 std::optional<TimeDelta>()) override;
   void JoinForTesting() override;
   void DidUpdateCanRunPolicy() override;
   void OnShutdownStarted() override;
diff --git a/base/task/thread_pool/thread_group_impl_unittest.cc b/base/task/thread_pool/thread_group_impl_unittest.cc
index f91dbd1..312dddf 100644
--- a/base/task/thread_pool/thread_group_impl_unittest.cc
+++ b/base/task/thread_pool/thread_group_impl_unittest.cc
@@ -9,6 +9,7 @@
 #include <algorithm>
 #include <atomic>
 #include <memory>
+#include <optional>
 #include <unordered_set>
 #include <utility>
 #include <vector>
@@ -51,7 +52,6 @@
 #include "base/timer/timer.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace internal {
@@ -102,9 +102,9 @@
   void StartThreadGroup(
       TimeDelta suggested_reclaim_time,
       size_t max_tasks,
-      absl::optional<int> max_best_effort_tasks = absl::nullopt,
+      std::optional<int> max_best_effort_tasks = std::nullopt,
       WorkerThreadObserver* worker_observer = nullptr,
-      absl::optional<TimeDelta> may_block_threshold = absl::nullopt) {
+      std::optional<TimeDelta> may_block_threshold = std::nullopt) {
     ASSERT_TRUE(thread_group_);
     thread_group_->Start(
         max_tasks,
@@ -117,9 +117,9 @@
   void CreateAndStartThreadGroup(
       TimeDelta suggested_reclaim_time = TimeDelta::Max(),
       size_t max_tasks = kMaxTasks,
-      absl::optional<int> max_best_effort_tasks = absl::nullopt,
+      std::optional<int> max_best_effort_tasks = std::nullopt,
       WorkerThreadObserver* worker_observer = nullptr,
-      absl::optional<TimeDelta> may_block_threshold = absl::nullopt) {
+      std::optional<TimeDelta> may_block_threshold = std::nullopt) {
     CreateThreadGroup();
     StartThreadGroup(suggested_reclaim_time, max_tasks, max_best_effort_tasks,
                      worker_observer, may_block_threshold);
@@ -530,9 +530,9 @@
   void CreateAndStartThreadGroup(
       TimeDelta suggested_reclaim_time = TimeDelta::Max(),
       size_t max_tasks = kMaxTasks,
-      absl::optional<int> max_best_effort_tasks = absl::nullopt,
+      std::optional<int> max_best_effort_tasks = std::nullopt,
       WorkerThreadObserver* worker_observer = nullptr,
-      absl::optional<TimeDelta> may_block_threshold = absl::nullopt) {
+      std::optional<TimeDelta> may_block_threshold = std::nullopt) {
     if (!CanUseBackgroundThreadTypeForWorkerThread())
       return;
     CreateThreadGroup(ThreadType::kBackground);
@@ -1076,7 +1076,7 @@
   // MAY_BLOCK ScopedBlockingCall never increases the max tasks.
   CreateAndStartThreadGroup(TimeDelta::Max(),   // |suggested_reclaim_time|
                             kMaxTasks,          // |max_tasks|
-                            absl::nullopt,      // |max_best_effort_tasks|
+                            std::nullopt,       // |max_best_effort_tasks|
                             nullptr,            // |worker_observer|
                             TimeDelta::Max());  // |may_block_threshold|
 
@@ -1534,7 +1534,7 @@
   constexpr size_t kNumWorkers = 2U;
   StartThreadGroup(TimeDelta::Max(),  // |suggested_reclaim_time|
                    kNumWorkers,       // |max_tasks|
-                   absl::nullopt);    // |max_best_effort_tasks|
+                   std::nullopt);     // |max_best_effort_tasks|
   const scoped_refptr<TaskRunner> runner = test::CreatePooledTaskRunner(
       {MayBlock()}, &mock_pooled_task_runner_delegate_);
 
diff --git a/base/task/thread_pool/thread_group_semaphore.cc b/base/task/thread_pool/thread_group_semaphore.cc
index 0440a6c..9de058bd 100644
--- a/base/task/thread_pool/thread_group_semaphore.cc
+++ b/base/task/thread_pool/thread_group_semaphore.cc
@@ -140,7 +140,7 @@
     WorkerThreadObserver* worker_thread_observer,
     WorkerEnvironment worker_environment,
     bool synchronous_thread_start_for_testing,
-    absl::optional<TimeDelta> may_block_threshold) {
+    std::optional<TimeDelta> may_block_threshold) {
   ThreadGroup::StartImpl(
       max_tasks, max_best_effort_tasks, suggested_reclaim_time,
       service_thread_task_runner, worker_thread_observer, worker_environment,
@@ -284,7 +284,7 @@
   // A transaction to the TaskSource to reenqueue, if any. Instantiated here as
   // `TaskSource::lock_` is a UniversalPredecessor and must always be acquired
   // prior to acquiring a second lock
-  absl::optional<RegisteredTaskSourceAndTransaction>
+  std::optional<RegisteredTaskSourceAndTransaction>
       transaction_with_task_source;
   if (task_source) {
     transaction_with_task_source.emplace(
@@ -317,8 +317,8 @@
   // Running task bookkeeping.
   outer()->DecrementTasksRunningLockRequired(
       *read_worker().current_task_priority);
-  write_worker().current_shutdown_behavior = absl::nullopt;
-  write_worker().current_task_priority = absl::nullopt;
+  write_worker().current_shutdown_behavior = std::nullopt;
+  write_worker().current_task_priority = std::nullopt;
 
   if (transaction_with_task_source) {
     // If there is a task to enqueue, we can swap it for another task without
diff --git a/base/task/thread_pool/thread_group_semaphore.h b/base/task/thread_pool/thread_group_semaphore.h
index 3fb5bab..227a4e2 100644
--- a/base/task/thread_pool/thread_group_semaphore.h
+++ b/base/task/thread_pool/thread_group_semaphore.h
@@ -5,12 +5,13 @@
 #ifndef BASE_TASK_THREAD_POOL_THREAD_GROUP_SEMAPHORE_H_
 #define BASE_TASK_THREAD_POOL_THREAD_GROUP_SEMAPHORE_H_
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/strings/string_piece.h"
 #include "base/task/thread_pool/task_source.h"
 #include "base/task/thread_pool/thread_group_impl.h"
 #include "base/task/thread_pool/worker_thread_semaphore.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -52,8 +53,8 @@
              WorkerThreadObserver* worker_thread_observer,
              WorkerEnvironment worker_environment,
              bool synchronous_thread_start_for_testing = false,
-             absl::optional<TimeDelta> may_block_threshold =
-                 absl::optional<TimeDelta>()) override;
+             std::optional<TimeDelta> may_block_threshold =
+                 std::optional<TimeDelta>()) override;
   void JoinForTesting() override;
   void DidUpdateCanRunPolicy() override;
   void OnShutdownStarted() override;
diff --git a/base/task/thread_pool/thread_group_semaphore_unittest.cc b/base/task/thread_pool/thread_group_semaphore_unittest.cc
index a9ce4c0..c3e45dc 100644
--- a/base/task/thread_pool/thread_group_semaphore_unittest.cc
+++ b/base/task/thread_pool/thread_group_semaphore_unittest.cc
@@ -9,6 +9,7 @@
 #include <algorithm>
 #include <atomic>
 #include <memory>
+#include <optional>
 #include <unordered_set>
 #include <utility>
 #include <vector>
@@ -51,7 +52,6 @@
 #include "base/timer/timer.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace internal {
@@ -104,9 +104,9 @@
   void StartThreadGroup(
       TimeDelta suggested_reclaim_time,
       size_t max_tasks,
-      absl::optional<int> max_best_effort_tasks = absl::nullopt,
+      std::optional<int> max_best_effort_tasks = std::nullopt,
       WorkerThreadObserver* worker_observer = nullptr,
-      absl::optional<TimeDelta> may_block_threshold = absl::nullopt) {
+      std::optional<TimeDelta> may_block_threshold = std::nullopt) {
     ASSERT_TRUE(thread_group_);
     thread_group_->Start(
         max_tasks,
@@ -119,9 +119,9 @@
   void CreateAndStartThreadGroup(
       TimeDelta suggested_reclaim_time = TimeDelta::Max(),
       size_t max_tasks = kMaxTasks,
-      absl::optional<int> max_best_effort_tasks = absl::nullopt,
+      std::optional<int> max_best_effort_tasks = std::nullopt,
       WorkerThreadObserver* worker_observer = nullptr,
-      absl::optional<TimeDelta> may_block_threshold = absl::nullopt) {
+      std::optional<TimeDelta> may_block_threshold = std::nullopt) {
     CreateThreadGroup();
     StartThreadGroup(suggested_reclaim_time, max_tasks, max_best_effort_tasks,
                      worker_observer, may_block_threshold);
@@ -534,9 +534,9 @@
   void CreateAndStartThreadGroup(
       TimeDelta suggested_reclaim_time = TimeDelta::Max(),
       size_t max_tasks = kMaxTasks,
-      absl::optional<int> max_best_effort_tasks = absl::nullopt,
+      std::optional<int> max_best_effort_tasks = std::nullopt,
       WorkerThreadObserver* worker_observer = nullptr,
-      absl::optional<TimeDelta> may_block_threshold = absl::nullopt) {
+      std::optional<TimeDelta> may_block_threshold = std::nullopt) {
     if (!CanUseBackgroundThreadTypeForWorkerThread()) {
       return;
     }
@@ -1090,7 +1090,7 @@
   // MAY_BLOCK ScopedBlockingCall never increases the max tasks.
   CreateAndStartThreadGroup(TimeDelta::Max(),   // |suggested_reclaim_time|
                             kMaxTasks,          // |max_tasks|
-                            absl::nullopt,      // |max_best_effort_tasks|
+                            std::nullopt,       // |max_best_effort_tasks|
                             nullptr,            // |worker_observer|
                             TimeDelta::Max());  // |may_block_threshold|
 
@@ -1548,7 +1548,7 @@
   constexpr size_t kNumWorkers = 2U;
   StartThreadGroup(TimeDelta::Max(),  // |suggested_reclaim_time|
                    kNumWorkers,       // |max_tasks|
-                   absl::nullopt);    // |max_best_effort_tasks|
+                   std::nullopt);     // |max_best_effort_tasks|
   const scoped_refptr<TaskRunner> runner = test::CreatePooledTaskRunner(
       {MayBlock()}, &mock_pooled_task_runner_delegate_);
 
diff --git a/base/task/thread_pool/thread_group_worker_delegate.h b/base/task/thread_pool/thread_group_worker_delegate.h
index 64df487..42a53b2 100644
--- a/base/task/thread_pool/thread_group_worker_delegate.h
+++ b/base/task/thread_pool/thread_group_worker_delegate.h
@@ -5,6 +5,8 @@
 #ifndef BASE_TASK_THREAD_POOL_THREAD_GROUP_WORKER_DELEGATE_H_
 #define BASE_TASK_THREAD_POOL_THREAD_GROUP_WORKER_DELEGATE_H_
 
+#include <optional>
+
 #include "base/metrics/histogram_macros.h"
 #include "base/task/task_traits.h"
 #include "base/task/thread_pool/thread_group.h"
@@ -12,7 +14,6 @@
 #include "base/threading/scoped_blocking_call.h"
 #include "base/threading/scoped_blocking_call_internal.h"
 #include "base/threading/thread_checker.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base::internal {
 
@@ -117,9 +118,9 @@
   // thread, protected by |outer_->lock_| when not on the worker thread.
   struct WriteWorkerReadAny {
     // The priority of the task the worker is currently running if any.
-    absl::optional<TaskPriority> current_task_priority;
+    std::optional<TaskPriority> current_task_priority;
     // The shutdown behavior of the task the worker is currently running if any.
-    absl::optional<TaskShutdownBehavior> current_shutdown_behavior;
+    std::optional<TaskShutdownBehavior> current_shutdown_behavior;
 
     // Time when MayBlockScopeEntered() was last called. Reset when
     // BlockingScopeExited() is called.
diff --git a/base/task/thread_pool/thread_pool_impl.cc b/base/task/thread_pool/thread_pool_impl.cc
index a13882c4..6107054b 100644
--- a/base/task/thread_pool/thread_pool_impl.cc
+++ b/base/task/thread_pool/thread_pool_impl.cc
@@ -5,6 +5,7 @@
 #include "base/task/thread_pool/thread_pool_impl.h"
 
 #include <algorithm>
+#include <optional>
 #include <string>
 #include <utility>
 
@@ -33,7 +34,6 @@
 #include "base/threading/platform_thread.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace internal {
@@ -317,7 +317,7 @@
   return MakeRefCounted<PooledSequencedTaskRunner>(traits, this);
 }
 
-absl::optional<TimeTicks> ThreadPoolImpl::NextScheduledRunTimeForTesting()
+std::optional<TimeTicks> ThreadPoolImpl::NextScheduledRunTimeForTesting()
     const {
   if (task_tracker_->HasIncompleteTaskSourcesForTesting())
     return TimeTicks::Now();
diff --git a/base/task/thread_pool/thread_pool_impl.h b/base/task/thread_pool/thread_pool_impl.h
index 9365099..a4b3aeff 100644
--- a/base/task/thread_pool/thread_pool_impl.h
+++ b/base/task/thread_pool/thread_pool_impl.h
@@ -6,6 +6,7 @@
 #define BASE_TASK_THREAD_POOL_THREAD_POOL_IMPL_H_
 
 #include <memory>
+#include <optional>
 
 #include "base/base_export.h"
 #include "base/dcheck_is_on.h"
@@ -28,7 +29,6 @@
 #include "base/task/updateable_sequenced_task_runner.h"
 #include "base/thread_annotations.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_WIN)
 #include "base/win/com_init_check_hook.h"
@@ -91,7 +91,7 @@
   // immediate, nullopt if none). This is thread-safe, i.e., it's safe if tasks
   // are being posted in parallel with this call but such a situation obviously
   // results in a race as to whether this call will see the new tasks in time.
-  absl::optional<TimeTicks> NextScheduledRunTimeForTesting() const;
+  std::optional<TimeTicks> NextScheduledRunTimeForTesting() const;
 
   // Forces ripe delayed tasks to be posted (e.g. when time is mocked and
   // advances faster than the real-time delay on ServiceThread).
diff --git a/base/task/thread_pool/thread_pool_perftest.cc b/base/task/thread_pool/thread_pool_perftest.cc
index f0f8cfb..4e8ef79f 100644
--- a/base/task/thread_pool/thread_pool_perftest.cc
+++ b/base/task/thread_pool/thread_pool_perftest.cc
@@ -2,9 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/task/thread_pool.h"
+
 #include <stddef.h>
+
 #include <atomic>
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "base/barrier_closure.h"
@@ -13,13 +17,11 @@
 #include "base/functional/callback_helpers.h"
 #include "base/memory/raw_ptr.h"
 #include "base/synchronization/waitable_event.h"
-#include "base/task/thread_pool.h"
 #include "base/task/thread_pool/thread_pool_instance.h"
 #include "base/threading/simple_thread.h"
 #include "base/time/time.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/perf/perf_result_reporter.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace internal {
@@ -164,7 +166,7 @@
   void OnCompletePostingTasks() { complete_posting_tasks_.Signal(); }
 
   void Benchmark(const std::string& story_name, ExecutionMode execution_mode) {
-    absl::optional<ThreadPoolInstance::ScopedExecutionFence> execution_fence;
+    std::optional<ThreadPoolInstance::ScopedExecutionFence> execution_fence;
     if (execution_mode == ExecutionMode::kPostThenRun) {
       execution_fence.emplace();
     }
diff --git a/base/task/thread_pool/tracked_ref.h b/base/task/thread_pool/tracked_ref.h
index c799b98..2e93216c 100644
--- a/base/task/thread_pool/tracked_ref.h
+++ b/base/task/thread_pool/tracked_ref.h
@@ -5,6 +5,8 @@
 #ifndef BASE_TASK_THREAD_POOL_TRACKED_REF_H_
 #define BASE_TASK_THREAD_POOL_TRACKED_REF_H_
 
+#include <optional>
+
 #include "base/atomic_ref_count.h"
 #include "base/check.h"
 #include "base/gtest_prod_util.h"
@@ -12,7 +14,6 @@
 #include "base/memory/raw_ptr.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/template_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace internal {
@@ -169,11 +170,11 @@
   // Non-null during the destruction phase. Signaled once |live_tracked_refs_|
   // reaches 0. Note: making this optional and only initializing it in the
   // destruction phase avoids keeping a handle open for the entire session.
-  absl::optional<WaitableEvent> ready_to_destroy_;
+  std::optional<WaitableEvent> ready_to_destroy_;
 
   // TrackedRefFactory holds a TrackedRef as well to prevent
   // |live_tracked_refs_| from ever reaching zero before ~TrackedRefFactory().
-  absl::optional<TrackedRef<T>> self_ref_;
+  std::optional<TrackedRef<T>> self_ref_;
 };
 
 }  // namespace internal
diff --git a/base/task/thread_pool/worker_thread.cc b/base/task/thread_pool/worker_thread.cc
index 3d112704..0706fb09 100644
--- a/base/task/thread_pool/worker_thread.cc
+++ b/base/task/thread_pool/worker_thread.cc
@@ -8,6 +8,7 @@
 
 #include <algorithm>
 #include <atomic>
+#include <optional>
 #include <utility>
 
 #include "base/allocator/partition_allocator/src/partition_alloc/partition_alloc_buildflags.h"
@@ -26,7 +27,6 @@
 #include "base/time/time_override.h"
 #include "base/trace_event/base_tracing.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL)) || BUILDFLAG(IS_FUCHSIA)
 #include "base/files/file_descriptor_watcher_posix.h"
@@ -394,7 +394,7 @@
 #if BUILDFLAG(IS_APPLE)
     apple::ScopedNSAutoreleasePool autorelease_pool;
 #endif
-    absl::optional<WatchHangsInScope> hang_watch_scope;
+    std::optional<WatchHangsInScope> hang_watch_scope;
 
     TRACE_EVENT_END0("base", "WorkerThread active");
     // TODO(crbug.com/1021571): Remove this once fixed.
diff --git a/base/test/gtest_util.cc b/base/test/gtest_util.cc
index 8b50af5..11e7f406 100644
--- a/base/test/gtest_util.cc
+++ b/base/test/gtest_util.cc
@@ -101,7 +101,7 @@
     if (!file || !IsStringASCII(*file))
       return false;
 
-    absl::optional<int> line = dict.FindInt("line");
+    std::optional<int> line = dict.FindInt("line");
     if (!line.has_value())
       return false;
 
diff --git a/base/test/launcher/test_launcher_test_utils.cc b/base/test/launcher/test_launcher_test_utils.cc
index 9315aab..6f3bc83 100644
--- a/base/test/launcher/test_launcher_test_utils.cc
+++ b/base/test/launcher/test_launcher_test_utils.cc
@@ -4,12 +4,13 @@
 
 #include "base/test/launcher/test_launcher_test_utils.h"
 
+#include <optional>
+
 #include "base/files/file_util.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
 #include "base/test/gtest_util.h"
 #include "base/test/launcher/test_result.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -148,13 +149,13 @@
   return result;
 }
 
-absl::optional<Value::Dict> ReadSummary(const FilePath& path) {
-  absl::optional<Value::Dict> result;
+std::optional<Value::Dict> ReadSummary(const FilePath& path) {
+  std::optional<Value::Dict> result;
   File resultFile(path, File::FLAG_OPEN | File::FLAG_READ);
   const int size = 2e7;
   std::string json;
   CHECK(ReadFileToStringWithMaxSize(path, &json, size));
-  absl::optional<Value> value = JSONReader::Read(json);
+  std::optional<Value> value = JSONReader::Read(json);
   if (value && value->is_dict())
     result = std::move(*value).TakeDict();
 
diff --git a/base/test/launcher/test_launcher_test_utils.h b/base/test/launcher/test_launcher_test_utils.h
index b8dbd8ab..8b61e939 100644
--- a/base/test/launcher/test_launcher_test_utils.h
+++ b/base/test/launcher/test_launcher_test_utils.h
@@ -7,11 +7,11 @@
 
 #include <stddef.h>
 
+#include <optional>
 #include <string>
 
 #include "base/values.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -49,7 +49,7 @@
                           int line);
 
 // Read json output file of test launcher.
-absl::optional<Value::Dict> ReadSummary(const FilePath& path);
+std::optional<Value::Dict> ReadSummary(const FilePath& path);
 
 }  // namespace test_launcher_utils
 
diff --git a/base/test/launcher/test_launcher_unittest.cc b/base/test/launcher/test_launcher_unittest.cc
index 8e25bf91..97871db4 100644
--- a/base/test/launcher/test_launcher_unittest.cc
+++ b/base/test/launcher/test_launcher_unittest.cc
@@ -6,6 +6,8 @@
 
 #include <stddef.h>
 
+#include <optional>
+
 #include "base/base64.h"
 #include "base/command_line.h"
 #include "base/files/file_util.h"
@@ -31,7 +33,6 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/multiprocess_func_list.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace {
@@ -731,7 +732,7 @@
 
 // Validate |root| dictionary value contains a list with |values|
 // at |key| value.
-bool ValidateStringList(const absl::optional<Value::Dict>& root,
+bool ValidateStringList(const std::optional<Value::Dict>& root,
                         const std::string& key,
                         std::vector<const char*> values) {
   const Value::List* list = root->FindList(key);
@@ -788,7 +789,7 @@
   EXPECT_TRUE(test_launcher.Run(command_line.get()));
 
   // Validate the resulting JSON file is the expected output.
-  absl::optional<Value::Dict> root = test_launcher_utils::ReadSummary(path);
+  std::optional<Value::Dict> root = test_launcher_utils::ReadSummary(path);
   ASSERT_TRUE(root);
   EXPECT_TRUE(
       ValidateStringList(root, "all_tests",
@@ -839,7 +840,7 @@
   EXPECT_TRUE(test_launcher.Run(command_line.get()));
 
   // Validate the resulting JSON file is the expected output.
-  absl::optional<Value::Dict> root = test_launcher_utils::ReadSummary(path);
+  std::optional<Value::Dict> root = test_launcher_utils::ReadSummary(path);
   ASSERT_TRUE(root);
   Value::Dict* dict = root->FindDict("test_locations");
   ASSERT_TRUE(dict);
@@ -1211,7 +1212,7 @@
   GetAppOutputAndError(command_line, &output);
 
   // Validate the resulting JSON file is the expected output.
-  absl::optional<Value::Dict> root = test_launcher_utils::ReadSummary(path);
+  std::optional<Value::Dict> root = test_launcher_utils::ReadSummary(path);
   ASSERT_TRUE(root);
 
   const Value::Dict* dict = root->FindDict("test_locations");
@@ -1381,7 +1382,7 @@
   GetAppOutputWithExitCode(command_line, &output, &exit_code);
 
   // Validate that we actually ran a test.
-  absl::optional<Value::Dict> root = test_launcher_utils::ReadSummary(path);
+  std::optional<Value::Dict> root = test_launcher_utils::ReadSummary(path);
   ASSERT_TRUE(root);
 
   Value::Dict* dict = root->FindDict("test_locations");
diff --git a/base/test/launcher/test_result.h b/base/test/launcher/test_result.h
index 40f5b7b..60bcf5c 100644
--- a/base/test/launcher/test_result.h
+++ b/base/test/launcher/test_result.h
@@ -6,12 +6,12 @@
 #define BASE_TEST_LAUNCHER_TEST_RESULT_H_
 
 #include <map>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "base/threading/platform_thread.h"
 #include "base/time/time.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -107,17 +107,17 @@
 
   // Start time of child test process, the field is optional the test could be
   // NOT_RUN.
-  absl::optional<base::Time> timestamp;
+  std::optional<base::Time> timestamp;
 
   // Thread id of the runner that launching the child process, which is also
   // recorded in TestLauncherTracer.
-  absl::optional<base::PlatformThreadId> thread_id;
+  std::optional<base::PlatformThreadId> thread_id;
 
   // The process num of child process launched it's recorded as event name in
   // TestLauncherTracer.
   // It's used instead of process id to distinguish processes that process id
   // might be reused by OS.
-  absl::optional<int> process_num;
+  std::optional<int> process_num;
 
   // Time it took to run the test.
   base::TimeDelta elapsed_time;
diff --git a/base/test/metrics/histogram_enum_reader.cc b/base/test/metrics/histogram_enum_reader.cc
index 0b5a870..da6e86e 100644
--- a/base/test/metrics/histogram_enum_reader.cc
+++ b/base/test/metrics/histogram_enum_reader.cc
@@ -4,12 +4,13 @@
 
 #include "base/test/metrics/histogram_enum_reader.h"
 
+#include <optional>
+
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/path_service.h"
 #include "base/strings/string_number_conversions.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/libxml/chromium/xml_reader.h"
 
 namespace base {
@@ -19,7 +20,7 @@
 // Extracts single enum (with integer values) from histograms.xml.
 // Expects |reader| to point at given enum.
 // Returns map { value => label } on success, and nullopt on failure.
-absl::optional<HistogramEnumEntryMap> ParseEnumFromHistogramsXml(
+std::optional<HistogramEnumEntryMap> ParseEnumFromHistogramsXml(
     const std::string& enum_name,
     XmlReader* reader) {
   int entries_index = -1;
@@ -77,18 +78,18 @@
   }
   if (success)
     return result;
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace
 
-absl::optional<HistogramEnumEntryMap> ReadEnumFromEnumsXml(
+std::optional<HistogramEnumEntryMap> ReadEnumFromEnumsXml(
     const std::string& enum_name,
-    const absl::optional<std::string>& subdirectory) {
+    const std::optional<std::string>& subdirectory) {
   FilePath src_root;
   if (!PathService::Get(DIR_SRC_TEST_DATA_ROOT, &src_root)) {
     ADD_FAILURE() << "Failed to get src root.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   base::FilePath enums_xml =
@@ -102,16 +103,16 @@
 
   if (!PathExists(enums_xml)) {
     ADD_FAILURE() << "enums.xml file does not exist.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   XmlReader enums_xml_reader;
   if (!enums_xml_reader.LoadFile(enums_xml.MaybeAsASCII())) {
     ADD_FAILURE() << "Failed to load enums.xml";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  absl::optional<HistogramEnumEntryMap> result;
+  std::optional<HistogramEnumEntryMap> result;
 
   // Implement simple depth first search.
   while (true) {
@@ -122,21 +123,21 @@
         if (result.has_value()) {
           ADD_FAILURE() << "Duplicate enum '" << enum_name
                         << "' found in enums.xml";
-          return absl::nullopt;
+          return std::nullopt;
         }
 
         const bool got_into_enum = enums_xml_reader.Read();
         if (!got_into_enum) {
           ADD_FAILURE() << "Bad enum '" << enum_name
                         << "' (looks empty) found in enums.xml.";
-          return absl::nullopt;
+          return std::nullopt;
         }
 
         result = ParseEnumFromHistogramsXml(enum_name, &enums_xml_reader);
         if (!result.has_value()) {
           ADD_FAILURE() << "Bad enum '" << enum_name
                         << "' found in histograms.xml (format error).";
-          return absl::nullopt;
+          return std::nullopt;
         }
       }
     }
diff --git a/base/test/metrics/histogram_enum_reader.h b/base/test/metrics/histogram_enum_reader.h
index 17896605..c143ef5 100644
--- a/base/test/metrics/histogram_enum_reader.h
+++ b/base/test/metrics/histogram_enum_reader.h
@@ -6,10 +6,10 @@
 #define BASE_TEST_METRICS_HISTOGRAM_ENUM_READER_H_
 
 #include <map>
+#include <optional>
 #include <string>
 
 #include "base/metrics/histogram_base.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -23,10 +23,10 @@
 //   <int value="9" label="enable-pinch-virtual-viewport"/>
 // becomes:
 //   { 9 => "enable-pinch-virtual-viewport" }
-// Returns empty absl::nullopt on failure.
-absl::optional<HistogramEnumEntryMap> ReadEnumFromEnumsXml(
+// Returns empty std::nullopt on failure.
+std::optional<HistogramEnumEntryMap> ReadEnumFromEnumsXml(
     const std::string& enum_name,
-    const absl::optional<std::string>& subdirectory = absl::nullopt);
+    const std::optional<std::string>& subdirectory = std::nullopt);
 
 }  // namespace base
 
diff --git a/base/test/metrics/histogram_enum_reader_unittest.cc b/base/test/metrics/histogram_enum_reader_unittest.cc
index aa9e50e..b4aa1dea2 100644
--- a/base/test/metrics/histogram_enum_reader_unittest.cc
+++ b/base/test/metrics/histogram_enum_reader_unittest.cc
@@ -4,8 +4,9 @@
 
 #include "base/test/metrics/histogram_enum_reader.h"
 
+#include <optional>
+
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -15,7 +16,7 @@
     // otherwise inject content would circumvent a lot of the logic of the
     // method and add additional complexity. "Boolean" is hopefully a pretty
     // stable enum.
-    absl::optional<HistogramEnumEntryMap> results =
+    std::optional<HistogramEnumEntryMap> results =
         ReadEnumFromEnumsXml("Boolean");
     ASSERT_TRUE(results);
     EXPECT_EQ("False", results->at(0));
@@ -23,7 +24,7 @@
   }
 
   {
-    absl::optional<HistogramEnumEntryMap> results =
+    std::optional<HistogramEnumEntryMap> results =
         ReadEnumFromEnumsXml("TheWorstNameForAnEnum");
     ASSERT_FALSE(results);
   }
diff --git a/base/test/power_monitor_test_utils.cc b/base/test/power_monitor_test_utils.cc
index 37f07b99..a366612 100644
--- a/base/test/power_monitor_test_utils.cc
+++ b/base/test/power_monitor_test_utils.cc
@@ -22,13 +22,13 @@
 
 void TestBatteryLevelProvider::GetBatteryState(
     base::OnceCallback<
-        void(const absl::optional<base::BatteryLevelProvider::BatteryState>&)>
+        void(const std::optional<base::BatteryLevelProvider::BatteryState>&)>
         callback) {
   std::move(callback).Run(battery_state_);
 }
 
 void TestBatteryLevelProvider::SetBatteryState(
-    absl::optional<base::BatteryLevelProvider::BatteryState> battery_state) {
+    std::optional<base::BatteryLevelProvider::BatteryState> battery_state) {
   battery_state_ = battery_state;
 }
 
diff --git a/base/test/power_monitor_test_utils.h b/base/test/power_monitor_test_utils.h
index 20161ae..d3e7aec 100644
--- a/base/test/power_monitor_test_utils.h
+++ b/base/test/power_monitor_test_utils.h
@@ -5,10 +5,11 @@
 #ifndef BASE_TEST_POWER_MONITOR_TEST_UTILS_H_
 #define BASE_TEST_POWER_MONITOR_TEST_UTILS_H_
 
+#include <optional>
+
 #include "base/functional/callback.h"
 #include "base/power_monitor/battery_level_provider.h"
 #include "base/power_monitor/sampling_event_source.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base::test {
 
@@ -30,11 +31,11 @@
   TestBatteryLevelProvider();
   void GetBatteryState(
       base::OnceCallback<
-          void(const absl::optional<base::BatteryLevelProvider::BatteryState>&)>
+          void(const std::optional<base::BatteryLevelProvider::BatteryState>&)>
           callback) override;
 
   void SetBatteryState(
-      absl::optional<base::BatteryLevelProvider::BatteryState> battery_state);
+      std::optional<base::BatteryLevelProvider::BatteryState> battery_state);
 
   static base::BatteryLevelProvider::BatteryState CreateBatteryState(
       int battery_count = 1,
@@ -42,7 +43,7 @@
       int charge_percent = 100);
 
  private:
-  absl::optional<base::BatteryLevelProvider::BatteryState> battery_state_;
+  std::optional<base::BatteryLevelProvider::BatteryState> battery_state_;
 };
 
 }  // namespace base::test
diff --git a/base/test/repeating_test_future.h b/base/test/repeating_test_future.h
index db583009..4ea1f85 100644
--- a/base/test/repeating_test_future.h
+++ b/base/test/repeating_test_future.h
@@ -5,6 +5,7 @@
 #ifndef BASE_TEST_REPEATING_TEST_FUTURE_H_
 #define BASE_TEST_REPEATING_TEST_FUTURE_H_
 
+#include <optional>
 #include <utility>
 
 #include "base/check.h"
@@ -14,7 +15,6 @@
 #include "base/sequence_checker.h"
 #include "base/test/test_future_internal.h"
 #include "base/thread_annotations.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base::test {
 
@@ -162,7 +162,7 @@
   base::queue<TupleType> elements_ GUARDED_BY_CONTEXT(sequence_checker_);
 
   // Used by Wait() to know when AddValue() is called.
-  absl::optional<base::RunLoop> run_loop_ GUARDED_BY_CONTEXT(sequence_checker_);
+  std::optional<base::RunLoop> run_loop_ GUARDED_BY_CONTEXT(sequence_checker_);
 
   SEQUENCE_CHECKER(sequence_checker_);
 
diff --git a/base/test/scoped_amount_of_physical_memory_override.h b/base/test/scoped_amount_of_physical_memory_override.h
index 93a2697..f8f3d36 100644
--- a/base/test/scoped_amount_of_physical_memory_override.h
+++ b/base/test/scoped_amount_of_physical_memory_override.h
@@ -7,7 +7,7 @@
 
 #include <stdint.h>
 
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include <optional>
 
 namespace base::test {
 
@@ -29,7 +29,7 @@
   ~ScopedAmountOfPhysicalMemoryOverride();
 
  private:
-  absl::optional<uint64_t> old_amount_of_physical_memory_mb_;
+  std::optional<uint64_t> old_amount_of_physical_memory_mb_;
 };
 
 }  // namespace base::test
diff --git a/base/test/scoped_path_override.h b/base/test/scoped_path_override.h
index 5295de8..4a1b877 100644
--- a/base/test/scoped_path_override.h
+++ b/base/test/scoped_path_override.h
@@ -5,8 +5,9 @@
 #ifndef BASE_TEST_SCOPED_PATH_OVERRIDE_H_
 #define BASE_TEST_SCOPED_PATH_OVERRIDE_H_
 
+#include <optional>
+
 #include "base/files/scoped_temp_dir.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -41,7 +42,7 @@
 
   int key_;
   ScopedTempDir temp_dir_;
-  absl::optional<FilePath> original_override_;
+  std::optional<FilePath> original_override_;
 };
 
 }  // namespace base
diff --git a/base/test/scoped_run_loop_timeout.cc b/base/test/scoped_run_loop_timeout.cc
index aabf39a81..6fac888 100644
--- a/base/test/scoped_run_loop_timeout.cc
+++ b/base/test/scoped_run_loop_timeout.cc
@@ -4,6 +4,8 @@
 
 #include "base/test/scoped_run_loop_timeout.h"
 
+#include <optional>
+
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "base/location.h"
@@ -11,7 +13,6 @@
 #include "base/strings/strcat.h"
 #include "base/time/time.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base::test {
 
@@ -73,7 +74,7 @@
 
 ScopedRunLoopTimeout::ScopedRunLoopTimeout(
     const Location& timeout_enabled_from_here,
-    absl::optional<TimeDelta> timeout,
+    std::optional<TimeDelta> timeout,
     RepeatingCallback<std::string()> on_timeout_log)
     : nested_timeout_(RunLoop::GetTimeoutForCurrentThread()) {
   CHECK(timeout.has_value() || nested_timeout_)
diff --git a/base/test/scoped_run_loop_timeout.h b/base/test/scoped_run_loop_timeout.h
index 2b36e2e..977fa964 100644
--- a/base/test/scoped_run_loop_timeout.h
+++ b/base/test/scoped_run_loop_timeout.h
@@ -5,6 +5,7 @@
 #ifndef BASE_TEST_SCOPED_RUN_LOOP_TIMEOUT_H_
 #define BASE_TEST_SCOPED_RUN_LOOP_TIMEOUT_H_
 
+#include <optional>
 #include <string>
 
 #include "base/functional/callback.h"
@@ -13,7 +14,6 @@
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
 #include "base/time/time.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace content {
 FORWARD_DECLARE_TEST(ContentBrowserTest, RunTimeoutInstalled);
@@ -81,7 +81,7 @@
   // logged error message. If `timeout` is not specified the current timeout is
   // used and only the log message is overridden.
   ScopedRunLoopTimeout(const Location& timeout_enabled_from_here,
-                       absl::optional<TimeDelta> timeout,
+                       std::optional<TimeDelta> timeout,
                        RepeatingCallback<std::string()> on_timeout_log);
 
   ScopedRunLoopTimeout(const ScopedRunLoopTimeout&) = delete;
diff --git a/base/test/scoped_run_loop_timeout_unittest.cc b/base/test/scoped_run_loop_timeout_unittest.cc
index a5de9d5..1b9f43e8 100644
--- a/base/test/scoped_run_loop_timeout_unittest.cc
+++ b/base/test/scoped_run_loop_timeout_unittest.cc
@@ -69,7 +69,7 @@
 
   static constexpr auto kArbitraryTimeout = Milliseconds(10);
   ScopedRunLoopTimeout run_timeout(FROM_HERE, kArbitraryTimeout);
-  ScopedRunLoopTimeout run_timeout2(FROM_HERE, absl::nullopt,
+  ScopedRunLoopTimeout run_timeout2(FROM_HERE, std::nullopt,
                                     log_callback.Get());
 
   // Since the delayed task will be posted only after the message pump starts
@@ -100,7 +100,7 @@
 
   static constexpr auto kArbitraryTimeout = Milliseconds(10);
   ScopedRunLoopTimeout run_timeout(FROM_HERE, kArbitraryTimeout);
-  ScopedRunLoopTimeout run_timeout2(FROM_HERE, absl::nullopt,
+  ScopedRunLoopTimeout run_timeout2(FROM_HERE, std::nullopt,
                                     log_callback.Get());
 
   // Posting a task with the same delay as our timeout, immediately before
diff --git a/base/test/task_environment.cc b/base/test/task_environment.cc
index 69e1ae1..51fef5c 100644
--- a/base/test/task_environment.cc
+++ b/base/test/task_environment.cc
@@ -50,8 +50,9 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
+#include <optional>
+
 #include "base/files/file_descriptor_watcher_posix.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #endif
 
 #if BUILDFLAG(ENABLE_BASE_TRACING)
@@ -253,7 +254,7 @@
   // non-delayed work. Advances time to the next task unless
   // |quit_when_idle_requested| or TaskEnvironment controls mock time.
   bool MaybeFastForwardToWakeUp(
-      absl::optional<sequence_manager::WakeUp> next_wake_up,
+      std::optional<sequence_manager::WakeUp> next_wake_up,
       bool quit_when_idle_requested) override {
     if (quit_when_idle_requested) {
       return false;
@@ -309,13 +310,13 @@
   // by the same amount. If false, `LiveTicks` won't be advanced (behaving as if
   // the system was suspended).
   NextTaskSource FastForwardToNextTaskOrCap(
-      absl::optional<sequence_manager::WakeUp> next_main_thread_wake_up,
+      std::optional<sequence_manager::WakeUp> next_main_thread_wake_up,
       TimeTicks fast_forward_cap,
       bool advance_live_ticks) {
     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
     // Consider the next thread pool tasks iff they're running.
-    absl::optional<TimeTicks> next_thread_pool_task_time;
+    std::optional<TimeTicks> next_thread_pool_task_time;
     if (thread_pool_ && thread_pool_task_tracker_->TasksAllowedToRun()) {
       next_thread_pool_task_time =
           thread_pool_->NextScheduledRunTimeForTesting();
@@ -324,7 +325,7 @@
     // Custom comparison logic to consider nullopt the largest rather than
     // smallest value. Could consider using TimeTicks::Max() instead of nullopt
     // to represent out-of-tasks?
-    absl::optional<TimeTicks> next_task_time;
+    std::optional<TimeTicks> next_task_time;
     if (!next_main_thread_wake_up) {
       next_task_time = next_thread_pool_task_time;
     } else if (!next_thread_pool_task_time) {
@@ -873,7 +874,7 @@
   if (!sequence_manager_->IsIdleForTesting()) {
     return TimeDelta();
   }
-  absl::optional<sequence_manager::WakeUp> wake_up =
+  std::optional<sequence_manager::WakeUp> wake_up =
       sequence_manager_->GetNextDelayedWakeUp();
   return wake_up ? wake_up->time - lazy_now.Now() : TimeDelta::Max();
 }
diff --git a/base/test/test_future.h b/base/test/test_future.h
index fed98c7..4affa3e 100644
--- a/base/test/test_future.h
+++ b/base/test/test_future.h
@@ -6,6 +6,7 @@
 #define BASE_TEST_TEST_FUTURE_H_
 
 #include <memory>
+#include <optional>
 #include <tuple>
 
 #include "base/auto_reset.h"
@@ -22,7 +23,6 @@
 #include "base/test/test_future_internal.h"
 #include "base/thread_annotations.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base::test {
 
@@ -475,7 +475,7 @@
   base::RepeatingClosure ready_signal_ GUARDED_BY_CONTEXT(sequence_checker_) =
       base::DoNothing();
 
-  absl::optional<TupleType> values_ GUARDED_BY_CONTEXT(sequence_checker_);
+  std::optional<TupleType> values_ GUARDED_BY_CONTEXT(sequence_checker_);
 
   WeakPtrFactory<TestFuture<Types...>> weak_ptr_factory_{this};
 };
diff --git a/base/test/test_mock_time_task_runner.cc b/base/test/test_mock_time_task_runner.cc
index 7cc0d21..2b65abeb 100644
--- a/base/test/test_mock_time_task_runner.cc
+++ b/base/test/test_mock_time_task_runner.cc
@@ -4,6 +4,7 @@
 
 #include "base/test/test_mock_time_task_runner.h"
 
+#include <optional>
 #include <utility>
 
 #include "base/check_op.h"
@@ -12,7 +13,6 @@
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "base/task/single_thread_task_runner.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -370,7 +370,7 @@
 
   // Multiple test task runners can share the same thread for determinism in
   // unit tests. Make sure this TestMockTimeTaskRunner's tasks run in its scope.
-  absl::optional<SingleThreadTaskRunner::CurrentHandleOverrideForTesting>
+  std::optional<SingleThreadTaskRunner::CurrentHandleOverrideForTesting>
       ttrh_override;
   if (!SingleThreadTaskRunner::HasCurrentDefault() ||
       SingleThreadTaskRunner::GetCurrentDefault() != proxy_task_runner_.get()) {
diff --git a/base/test/test_simple_task_runner.cc b/base/test/test_simple_task_runner.cc
index e6881c09..7b3baa80f 100644
--- a/base/test/test_simple_task_runner.cc
+++ b/base/test/test_simple_task_runner.cc
@@ -4,12 +4,12 @@
 
 #include "base/test/test_simple_task_runner.h"
 
+#include <optional>
 #include <utility>
 
 #include "base/check.h"
 #include "base/memory/ptr_util.h"
 #include "base/task/single_thread_task_runner.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -86,7 +86,7 @@
 
   // Multiple test task runners can share the same thread for determinism in
   // unit tests. Make sure this TestSimpleTaskRunner's tasks run in its scope.
-  absl::optional<SingleThreadTaskRunner::CurrentHandleOverrideForTesting>
+  std::optional<SingleThreadTaskRunner::CurrentHandleOverrideForTesting>
       ttrh_override;
   if (!SingleThreadTaskRunner::HasCurrentDefault() ||
       SingleThreadTaskRunner::GetCurrentDefault() != this) {
diff --git a/base/test/trace_event_analyzer.cc b/base/test/trace_event_analyzer.cc
index b702011..7f3ac459 100644
--- a/base/test/trace_event_analyzer.cc
+++ b/base/test/trace_event_analyzer.cc
@@ -7,6 +7,7 @@
 #include <math.h>
 
 #include <algorithm>
+#include <optional>
 #include <set>
 
 #include "base/functional/bind.h"
@@ -21,7 +22,6 @@
 #include "base/trace_event/trace_config.h"
 #include "base/trace_event/trace_log.h"
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 void OnTraceDataCollected(base::OnceClosure quit_closure,
@@ -75,21 +75,21 @@
                      phase == TRACE_EVENT_PHASE_NESTABLE_ASYNC_END);
 
   if (require_origin) {
-    absl::optional<int> maybe_process_id = event_dict.FindInt("pid");
+    std::optional<int> maybe_process_id = event_dict.FindInt("pid");
     if (!maybe_process_id) {
       LOG(ERROR) << "pid is missing from TraceEvent JSON";
       return false;
     }
     thread.process_id = *maybe_process_id;
 
-    absl::optional<int> maybe_thread_id = event_dict.FindInt("tid");
+    std::optional<int> maybe_thread_id = event_dict.FindInt("tid");
     if (!maybe_thread_id) {
       LOG(ERROR) << "tid is missing from TraceEvent JSON";
       return false;
     }
     thread.thread_id = *maybe_thread_id;
 
-    absl::optional<double> maybe_timestamp = event_dict.FindDouble("ts");
+    std::optional<double> maybe_timestamp = event_dict.FindDouble("ts");
     if (!maybe_timestamp) {
       LOG(ERROR) << "ts is missing from TraceEvent JSON";
       return false;
@@ -97,7 +97,7 @@
     timestamp = *maybe_timestamp;
   }
   if (may_have_duration) {
-    absl::optional<double> maybe_duration = event_dict.FindDouble("dur");
+    std::optional<double> maybe_duration = event_dict.FindDouble("dur");
     if (maybe_duration)
       duration = *maybe_duration;
   }
@@ -136,11 +136,11 @@
       id = *maybe_id;
   }
 
-  absl::optional<double> maybe_thread_duration = event_dict.FindDouble("tdur");
+  std::optional<double> maybe_thread_duration = event_dict.FindDouble("tdur");
   if (maybe_thread_duration) {
     thread_duration = *maybe_thread_duration;
   }
-  absl::optional<double> maybe_thread_timestamp = event_dict.FindDouble("tts");
+  std::optional<double> maybe_thread_timestamp = event_dict.FindDouble("tts");
   if (maybe_thread_timestamp) {
     thread_timestamp = *maybe_thread_timestamp;
   }
@@ -152,11 +152,11 @@
   if (maybe_bind_id) {
     bind_id = *maybe_bind_id;
   }
-  absl::optional<bool> maybe_flow_out = event_dict.FindBool("flow_out");
+  std::optional<bool> maybe_flow_out = event_dict.FindBool("flow_out");
   if (maybe_flow_out) {
     flow_out = *maybe_flow_out;
   }
-  absl::optional<bool> maybe_flow_in = event_dict.FindBool("flow_in");
+  std::optional<bool> maybe_flow_in = event_dict.FindBool("flow_in");
   if (maybe_flow_in) {
     flow_in = *maybe_flow_in;
   }
@@ -774,7 +774,7 @@
 
 bool ParseEventsFromJson(const std::string& json,
                          std::vector<TraceEvent>* output) {
-  absl::optional<base::Value> root = base::JSONReader::Read(json);
+  std::optional<base::Value> root = base::JSONReader::Read(json);
 
   if (!root)
     return false;
diff --git a/base/test/trace_event_analyzer_unittest.cc b/base/test/trace_event_analyzer_unittest.cc
index 8460fef5..e6b08ba2 100644
--- a/base/test/trace_event_analyzer_unittest.cc
+++ b/base/test/trace_event_analyzer_unittest.cc
@@ -955,7 +955,7 @@
 
   ASSERT_TRUE(events[0]->HasDictArg("arg"));
   base::Value::Dict arg = events[0]->GetKnownArgAsDict("arg");
-  EXPECT_EQ(absl::optional<std::string>("value"),
+  EXPECT_EQ(std::optional<std::string>("value"),
             base::OptionalFromPtr(arg.FindString("property")));
 }
 
diff --git a/base/test/values_test_util.cc b/base/test/values_test_util.cc
index 170d0a4..f85c008 100644
--- a/base/test/values_test_util.cc
+++ b/base/test/values_test_util.cc
@@ -4,6 +4,7 @@
 
 #include "base/test/values_test_util.h"
 
+#include <optional>
 #include <ostream>
 #include <utility>
 
@@ -15,22 +16,20 @@
 #include "base/types/optional_util.h"
 #include "base/values.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
 void ExpectDictBooleanValue(bool expected_value,
                             const Value::Dict& dict,
                             StringPiece path) {
-  EXPECT_EQ(dict.FindBoolByDottedPath(path),
-            absl::make_optional(expected_value))
+  EXPECT_EQ(dict.FindBoolByDottedPath(path), std::make_optional(expected_value))
       << path;
 }
 
 void ExpectDictIntegerValue(int expected_value,
                             const Value::Dict& dict,
                             StringPiece path) {
-  EXPECT_EQ(dict.FindIntByDottedPath(path), absl::make_optional(expected_value))
+  EXPECT_EQ(dict.FindIntByDottedPath(path), std::make_optional(expected_value))
       << path;
 }
 
@@ -38,7 +37,7 @@
                            const Value::Dict& dict,
                            StringPiece path) {
   EXPECT_EQ(OptionalFromPtr(dict.FindStringByDottedPath(path)),
-            absl::make_optional(expected_value))
+            std::make_optional(expected_value))
       << path;
 }
 
@@ -167,19 +166,18 @@
 // EXPECT failure and returns nullopt on failure. If `expected_type` is
 // provided, treats `json` parsing as a Value of a different type as a failure.
 //
-absl::optional<Value> ParseJsonHelper(
-    StringPiece json,
-    absl::optional<Value::Type> expected_type) {
+std::optional<Value> ParseJsonHelper(StringPiece json,
+                                     std::optional<Value::Type> expected_type) {
   auto result = JSONReader::ReadAndReturnValueWithError(
       json, JSON_PARSE_CHROMIUM_EXTENSIONS | JSON_ALLOW_TRAILING_COMMAS);
   if (!result.has_value()) {
     ADD_FAILURE() << "Failed to parse \"" << json
                   << "\": " << result.error().message;
-    return absl::nullopt;
+    return std::nullopt;
   }
   if (expected_type && result->type() != *expected_type) {
     ADD_FAILURE() << "JSON is of wrong type: " << json;
-    return absl::nullopt;
+    return std::nullopt;
   }
   return std::move(*result);
 }
@@ -261,19 +259,19 @@
 }
 
 Value ParseJson(StringPiece json) {
-  absl::optional<Value> result =
-      ParseJsonHelper(json, /*expected_type=*/absl::nullopt);
+  std::optional<Value> result =
+      ParseJsonHelper(json, /*expected_type=*/std::nullopt);
   return result.has_value() ? std::move(*result) : Value();
 }
 
 Value::Dict ParseJsonDict(StringPiece json) {
-  absl::optional<Value> result =
+  std::optional<Value> result =
       ParseJsonHelper(json, /*expected_type=*/Value::Type::DICT);
   return result.has_value() ? std::move(*result).TakeDict() : Value::Dict();
 }
 
 Value::List ParseJsonList(StringPiece json) {
-  absl::optional<Value> result =
+  std::optional<Value> result =
       ParseJsonHelper(json, /*expected_type=*/Value::Type::LIST);
   return result.has_value() ? std::move(*result).TakeList() : Value::List();
 }
diff --git a/base/threading/hang_watcher_unittest.cc b/base/threading/hang_watcher_unittest.cc
index 28b0512..ffc5008f 100644
--- a/base/threading/hang_watcher_unittest.cc
+++ b/base/threading/hang_watcher_unittest.cc
@@ -3,8 +3,10 @@
 // found in the LICENSE file.
 
 #include "base/threading/hang_watcher.h"
+
 #include <atomic>
 #include <memory>
+#include <optional>
 
 #include "base/barrier_closure.h"
 #include "base/functional/bind.h"
@@ -31,7 +33,6 @@
 #include "build/build_config.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using testing::ElementsAre;
 using testing::IsEmpty;
diff --git a/base/threading/platform_thread.cc b/base/threading/platform_thread.cc
index 1bc5ee15..839836a2 100644
--- a/base/threading/platform_thread.cc
+++ b/base/threading/platform_thread.cc
@@ -41,7 +41,7 @@
 }
 
 // static
-absl::optional<TimeDelta> PlatformThreadBase::GetThreadLeewayOverride() {
+std::optional<TimeDelta> PlatformThreadBase::GetThreadLeewayOverride() {
 #if BUILDFLAG(IS_FUCHSIA)
   // On Fuchsia, all audio threads run with the CPU scheduling profile that uses
   // an interval of |kAudioSchedulingPeriod|. Using the default leeway may lead
@@ -50,7 +50,7 @@
   if (GetCurrentThreadType() == ThreadType::kRealtimeAudio)
     return kAudioSchedulingPeriod;
 #endif
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 // static
diff --git a/base/threading/platform_thread.h b/base/threading/platform_thread.h
index 07922aaf..d441aa9 100644
--- a/base/threading/platform_thread.h
+++ b/base/threading/platform_thread.h
@@ -12,6 +12,7 @@
 #include <stddef.h>
 
 #include <iosfwd>
+#include <optional>
 #include <type_traits>
 
 #include "base/base_export.h"
@@ -24,7 +25,6 @@
 #include "base/types/strong_alias.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_WIN)
 #include "base/win/windows_types.h"
@@ -266,7 +266,7 @@
   static TimeDelta GetRealtimePeriod(Delegate* delegate);
 
   // Returns the override of task leeway if any.
-  static absl::optional<TimeDelta> GetThreadLeewayOverride();
+  static std::optional<TimeDelta> GetThreadLeewayOverride();
 
   // Returns the default thread stack size set by chrome. If we do not
   // explicitly set default size then returns 0.
@@ -361,7 +361,7 @@
                                     bool backgrounded);
 
   // Returns the thread type of a thread given its thread id.
-  static absl::optional<ThreadType> GetThreadTypeFromThreadId(
+  static std::optional<ThreadType> GetThreadTypeFromThreadId(
       ProcessId process_id,
       PlatformThreadId thread_id);
 
diff --git a/base/threading/platform_thread_android.cc b/base/threading/platform_thread_android.cc
index 667b6d2..dd9f2fb 100644
--- a/base/threading/platform_thread_android.cc
+++ b/base/threading/platform_thread_android.cc
@@ -10,13 +10,14 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <optional>
+
 #include "base/android/jni_android.h"
 #include "base/base_jni/ThreadUtils_jni.h"
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/threading/platform_thread_internal_posix.h"
 #include "base/threading/thread_id_name_manager.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -76,14 +77,14 @@
   return false;
 }
 
-absl::optional<ThreadPriorityForTest>
+std::optional<ThreadPriorityForTest>
 GetCurrentThreadPriorityForPlatformForTest() {
   JNIEnv* env = base::android::AttachCurrentThread();
   if (Java_ThreadUtils_isThreadPriorityAudio(
       env, PlatformThread::CurrentId())) {
-    return absl::make_optional(ThreadPriorityForTest::kRealtimeAudio);
+    return std::make_optional(ThreadPriorityForTest::kRealtimeAudio);
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace internal
diff --git a/base/threading/platform_thread_cros.cc b/base/threading/platform_thread_cros.cc
index 1500fce..c01b7b4 100644
--- a/base/threading/platform_thread_cros.cc
+++ b/base/threading/platform_thread_cros.cc
@@ -213,16 +213,16 @@
 }
 
 // Get the type by reading through kThreadTypeToNiceValueMap
-absl::optional<ThreadType> GetThreadTypeForNiceValue(int nice_value) {
+std::optional<ThreadType> GetThreadTypeForNiceValue(int nice_value) {
   for (auto i : internal::kThreadTypeToNiceValueMap) {
     if (nice_value == i.nice_value) {
       return i.thread_type;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<int> GetNiceValueForThreadId(PlatformThreadId thread_id) {
+std::optional<int> GetNiceValueForThreadId(PlatformThreadId thread_id) {
   // Get the current nice value of the thread_id
   errno = 0;
   int nice_value = getpriority(PRIO_PROCESS, static_cast<id_t>(thread_id));
@@ -231,7 +231,7 @@
     DVPLOG_IF(1, errno != ESRCH)
         << "Failed to call getpriority for thread id " << thread_id
         << ", performance may be effected.";
-    return absl::nullopt;
+    return std::nullopt;
   }
   return nice_value;
 }
@@ -350,13 +350,13 @@
 }
 
 // static
-absl::optional<ThreadType> PlatformThreadChromeOS::GetThreadTypeFromThreadId(
+std::optional<ThreadType> PlatformThreadChromeOS::GetThreadTypeFromThreadId(
     ProcessId process_id,
     PlatformThreadId thread_id) {
   // Get the current nice_value of the thread_id
-  absl::optional<int> nice_value = GetNiceValueForThreadId(thread_id);
+  std::optional<int> nice_value = GetNiceValueForThreadId(thread_id);
   if (!nice_value.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return GetThreadTypeForNiceValue(nice_value.value());
 }
@@ -393,13 +393,12 @@
                                                    PlatformThreadId thread_id,
                                                    bool backgrounded) {
   // Get the current nice value of the thread_id
-  absl::optional<int> nice_value =
-      GetNiceValueForThreadId(thread_id);
+  std::optional<int> nice_value = GetNiceValueForThreadId(thread_id);
   if (!nice_value.has_value()) {
     return;
   }
 
-  absl::optional<ThreadType> type =
+  std::optional<ThreadType> type =
       GetThreadTypeForNiceValue(nice_value.value());
   if (!type.has_value()) {
     return;
diff --git a/base/threading/platform_thread_internal_posix.h b/base/threading/platform_thread_internal_posix.h
index 1f724c1..09c01e31 100644
--- a/base/threading/platform_thread_internal_posix.h
+++ b/base/threading/platform_thread_internal_posix.h
@@ -5,10 +5,11 @@
 #ifndef BASE_THREADING_PLATFORM_THREAD_INTERNAL_POSIX_H_
 #define BASE_THREADING_PLATFORM_THREAD_INTERNAL_POSIX_H_
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/threading/platform_thread.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -63,7 +64,7 @@
 // platform-specific implementation of kThreadPriorityToNiceValueMapForTest.
 ThreadPriorityForTest NiceValueToThreadPriorityForTest(int nice_value);
 
-absl::optional<ThreadPriorityForTest>
+std::optional<ThreadPriorityForTest>
 GetCurrentThreadPriorityForPlatformForTest();
 
 int GetCurrentThreadNiceValue();
diff --git a/base/threading/platform_thread_linux.cc b/base/threading/platform_thread_linux.cc
index 1b5384b5..53e5983f 100644
--- a/base/threading/platform_thread_linux.cc
+++ b/base/threading/platform_thread_linux.cc
@@ -4,14 +4,21 @@
 // Description: Linux specific functionality. Other Linux-derivatives layer on
 // top of this translation unit.
 
-#include "base/no_destructor.h"
 #include "base/threading/platform_thread.h"
 
 #include <errno.h>
+#include <pthread.h>
 #include <sched.h>
 #include <stddef.h>
-#include <cstdint>
+#include <sys/prctl.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
 #include <atomic>
+#include <cstdint>
+#include <optional>
 
 #include "base/base_switches.h"
 #include "base/command_line.h"
@@ -21,6 +28,7 @@
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/metrics/field_trial_params.h"
+#include "base/no_destructor.h"
 #include "base/notreached.h"
 #include "base/process/internal_linux.h"
 #include "base/strings/string_number_conversions.h"
@@ -29,14 +37,6 @@
 #include "base/threading/thread_id_name_manager.h"
 #include "base/threading/thread_type_delegate.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
-
-#include <pthread.h>
-#include <sys/prctl.h>
-#include <sys/resource.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
 
 namespace base {
 
@@ -164,7 +164,7 @@
   return true;
 }
 
-absl::optional<ThreadPriorityForTest>
+std::optional<ThreadPriorityForTest>
 GetCurrentThreadPriorityForPlatformForTest() {
   int maybe_sched_rr = 0;
   struct sched_param maybe_realtime_prio = {0};
@@ -173,9 +173,9 @@
       maybe_sched_rr == SCHED_RR &&
       maybe_realtime_prio.sched_priority ==
           PlatformThreadLinux::kRealTimeAudioPrio.sched_priority) {
-    return absl::make_optional(ThreadPriorityForTest::kRealtimeAudio);
+    return std::make_optional(ThreadPriorityForTest::kRealtimeAudio);
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace internal
diff --git a/base/threading/platform_thread_nacl.cc b/base/threading/platform_thread_nacl.cc
index e506462..482855f6 100644
--- a/base/threading/platform_thread_nacl.cc
+++ b/base/threading/platform_thread_nacl.cc
@@ -17,9 +17,9 @@
   return false;
 }
 
-absl::optional<ThreadPriorityForTest>
+std::optional<ThreadPriorityForTest>
 GetCurrentThreadPriorityForPlatformForTest() {
-  return absl::nullopt;
+  return std::nullopt;
 }
 }  // namespace internal
 
diff --git a/base/threading/scoped_blocking_call_internal.h b/base/threading/scoped_blocking_call_internal.h
index cf435812..3bcc54a3 100644
--- a/base/threading/scoped_blocking_call_internal.h
+++ b/base/threading/scoped_blocking_call_internal.h
@@ -5,6 +5,8 @@
 #ifndef BASE_THREADING_SCOPED_BLOCKING_CALL_INTERNAL_H_
 #define BASE_THREADING_SCOPED_BLOCKING_CALL_INTERNAL_H_
 
+#include <optional>
+
 #include "base/auto_reset.h"
 #include "base/base_export.h"
 #include "base/functional/callback_forward.h"
@@ -14,7 +16,6 @@
 #include "base/thread_annotations.h"
 #include "base/time/time.h"
 #include "base/types/strong_alias.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -199,7 +200,7 @@
 
   // Non-nullopt for non-nested blocking calls of type MAY_BLOCK on foreground
   // threads which we monitor for I/O jank.
-  absl::optional<IOJankMonitoringWindow::ScopedMonitoredCall> monitored_call_;
+  std::optional<IOJankMonitoringWindow::ScopedMonitoredCall> monitored_call_;
 };
 
 }  // namespace internal
diff --git a/base/threading/scoped_blocking_call_unittest.cc b/base/threading/scoped_blocking_call_unittest.cc
index f4f29c69..fd65a9458 100644
--- a/base/threading/scoped_blocking_call_unittest.cc
+++ b/base/threading/scoped_blocking_call_unittest.cc
@@ -5,6 +5,7 @@
 #include "base/threading/scoped_blocking_call.h"
 
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -24,7 +25,6 @@
 #include "build/build_config.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using testing::ElementsAre;
 
@@ -171,7 +171,7 @@
   explicit ScopedBlockingCallIOJankMonitoringTest(
       test::TaskEnvironment::TimeSource time_source =
           test::TaskEnvironment::TimeSource::MOCK_TIME)
-      : task_environment_(absl::in_place, time_source) {}
+      : task_environment_(std::in_place, time_source) {}
 
   void SetUp() override {
     // Note 1: While EnableIOJankMonitoringForProcess() is documented as being
@@ -231,7 +231,7 @@
   // TaskEnvironment+MOCK_TIME advances the test in lock steps.
   std::vector<std::pair<int, int>> reports_;
 
-  absl::optional<test::TaskEnvironment> task_environment_;
+  std::optional<test::TaskEnvironment> task_environment_;
 
   // The main thread needs to register a BlockingObserver per
   // OnlyObservedThreadsForTest(true) but doesn't otherwise care about
diff --git a/base/threading/scoped_thread_priority.h b/base/threading/scoped_thread_priority.h
index ade4dee..2ec181d 100644
--- a/base/threading/scoped_thread_priority.h
+++ b/base/threading/scoped_thread_priority.h
@@ -6,6 +6,7 @@
 #define BASE_THREADING_SCOPED_THREAD_PRIORITY_H_
 
 #include <atomic>
+#include <optional>
 
 #include "base/base_export.h"
 #include "base/compiler_specific.h"
@@ -13,7 +14,6 @@
 #include "base/macros/uniquify.h"
 #include "base/memory/raw_ptr.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -61,7 +61,7 @@
   ScopedBoostPriority& operator=(const ScopedBoostPriority&) = delete;
 
  private:
-  absl::optional<ThreadType> original_thread_type_;
+  std::optional<ThreadType> original_thread_type_;
 };
 
 namespace internal {
@@ -84,7 +84,7 @@
  private:
 #if BUILDFLAG(IS_WIN)
   // The original priority when invoking entering the scope().
-  absl::optional<ThreadType> original_thread_type_;
+  std::optional<ThreadType> original_thread_type_;
   const raw_ptr<std::atomic_bool> already_loaded_;
 #endif
 };
diff --git a/base/threading/thread.cc b/base/threading/thread.cc
index 9a30864..8f87f3f18 100644
--- a/base/threading/thread.cc
+++ b/base/threading/thread.cc
@@ -30,8 +30,9 @@
 #include "third_party/abseil-cpp/absl/base/attributes.h"
 
 #if (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL)) || BUILDFLAG(IS_FUCHSIA)
+#include <optional>
+
 #include "base/files/file_descriptor_watcher_posix.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #endif
 
 #if BUILDFLAG(IS_WIN)
diff --git a/base/threading/thread_local_unittest.cc b/base/threading/thread_local_unittest.cc
index 0267a3a1..4bde84d 100644
--- a/base/threading/thread_local_unittest.cc
+++ b/base/threading/thread_local_unittest.cc
@@ -3,6 +3,9 @@
 // found in the LICENSE file.
 
 #include "base/threading/thread_local.h"
+
+#include <optional>
+
 #include "base/check_op.h"
 #include "base/memory/raw_ptr.h"
 #include "base/synchronization/waitable_event.h"
@@ -11,7 +14,6 @@
 #include "base/threading/simple_thread.h"
 #include "base/threading/thread.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -86,8 +88,8 @@
 }
 
 TEST(ThreadLocalTest, ThreadLocalOwnedPointerCleansUpMainThreadOnDestruction) {
-  absl::optional<ThreadLocalOwnedPointer<SetTrueOnDestruction>>
-      tls_owned_pointer(absl::in_place);
+  std::optional<ThreadLocalOwnedPointer<SetTrueOnDestruction>>
+      tls_owned_pointer(std::in_place);
   bool tls_was_destroyed_other = false;
 
   Thread thread("TestThread");
@@ -128,8 +130,7 @@
 TEST(ThreadLocalTest, ThreadLocalOwnedPointerDeathIfDestroyedWithActiveThread) {
   GTEST_FLAG_SET(death_test_style, "threadsafe");
 
-  absl::optional<ThreadLocalOwnedPointer<int>> tls_owned_pointer(
-      absl::in_place);
+  std::optional<ThreadLocalOwnedPointer<int>> tls_owned_pointer(std::in_place);
 
   Thread thread("TestThread");
   thread.Start();
diff --git a/base/threading/thread_restrictions.h b/base/threading/thread_restrictions.h
index 0c6f557..e9b83663 100644
--- a/base/threading/thread_restrictions.h
+++ b/base/threading/thread_restrictions.h
@@ -14,8 +14,9 @@
 #include "build/build_config.h"
 
 #if DCHECK_IS_ON()
+#include <optional>
+
 #include "base/debug/stack_trace.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #endif
 
 // -----------------------------------------------------------------------------
@@ -510,7 +511,7 @@
 
  private:
   bool value_ = false;
-  absl::optional<debug::StackTrace> stack_;
+  std::optional<debug::StackTrace> stack_;
 };
 
 #else
diff --git a/base/time/time.cc b/base/time/time.cc
index a02505a..3224381 100644
--- a/base/time/time.cc
+++ b/base/time/time.cc
@@ -7,6 +7,7 @@
 #include <atomic>
 #include <cmath>
 #include <limits>
+#include <optional>
 #include <ostream>
 #include <tuple>
 #include <utility>
@@ -17,7 +18,6 @@
 #include "base/third_party/nspr/prtime.h"
 #include "base/time/time_override.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
diff --git a/base/time/time_delta_from_string.cc b/base/time/time_delta_from_string.cc
index 3975cda..4136cda 100644
--- a/base/time/time_delta_from_string.cc
+++ b/base/time/time_delta_from_string.cc
@@ -53,7 +53,7 @@
 //
 // Adapted from absl:
 // https://cs.chromium.org/chromium/src/third_party/abseil-cpp/absl/time/duration.cc?l=807&rcl=2c22e9135f107a4319582ae52e2e3e6b201b6b7c
-constexpr absl::optional<ParsedDecimal> ConsumeDurationNumber(
+constexpr std::optional<ParsedDecimal> ConsumeDurationNumber(
     StringPiece& number_string) {
   ParsedDecimal res;
   StringPiece::const_iterator orig_start = number_string.begin();
@@ -64,15 +64,15 @@
       break;
 
     if (res.int_part > std::numeric_limits<int64_t>::max() / 10)
-      return absl::nullopt;
+      return std::nullopt;
     res.int_part *= 10;
     if (res.int_part > std::numeric_limits<int64_t>::max() - d)
-      return absl::nullopt;
+      return std::nullopt;
     res.int_part += d;
   }
   const bool int_part_empty = number_string.begin() == orig_start;
   if (number_string.empty() || number_string.front() != '.')
-    return int_part_empty ? absl::nullopt : absl::make_optional(res);
+    return int_part_empty ? std::nullopt : std::make_optional(res);
 
   number_string.remove_prefix(1);  // consume '.'
   // Parse contiguous digits.
@@ -89,8 +89,8 @@
     }
   }
 
-  return int_part_empty && res.frac_scale == 1 ? absl::nullopt
-                                               : absl::make_optional(res);
+  return int_part_empty && res.frac_scale == 1 ? std::nullopt
+                                               : std::make_optional(res);
 }
 
 // A helper for FromString() that tries to parse a leading unit designator
@@ -99,7 +99,7 @@
 //
 // Adapted from absl:
 // https://cs.chromium.org/chromium/src/third_party/abseil-cpp/absl/time/duration.cc?l=841&rcl=2c22e9135f107a4319582ae52e2e3e6b201b6b7c
-absl::optional<TimeDelta> ConsumeDurationUnit(StringPiece& unit_string) {
+std::optional<TimeDelta> ConsumeDurationUnit(StringPiece& unit_string) {
   for (const auto& str_delta : {
            std::make_pair("ns", Nanoseconds(1)),
            std::make_pair("us", Microseconds(1)),
@@ -115,19 +115,19 @@
       return str_delta.second;
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace
 
-absl::optional<TimeDelta> TimeDeltaFromString(StringPiece duration_string) {
+std::optional<TimeDelta> TimeDeltaFromString(StringPiece duration_string) {
   int sign = 1;
   if (ConsumePrefix(duration_string, "-"))
     sign = -1;
   else
     ConsumePrefix(duration_string, "+");
   if (duration_string.empty())
-    return absl::nullopt;
+    return std::nullopt;
 
   // Handle special-case values that don't require units.
   if (duration_string == "0")
@@ -137,13 +137,13 @@
 
   TimeDelta delta;
   while (!duration_string.empty()) {
-    absl::optional<ParsedDecimal> number_opt =
+    std::optional<ParsedDecimal> number_opt =
         ConsumeDurationNumber(duration_string);
     if (!number_opt.has_value())
-      return absl::nullopt;
-    absl::optional<TimeDelta> unit_opt = ConsumeDurationUnit(duration_string);
+      return std::nullopt;
+    std::optional<TimeDelta> unit_opt = ConsumeDurationUnit(duration_string);
     if (!unit_opt.has_value())
-      return absl::nullopt;
+      return std::nullopt;
 
     ParsedDecimal number = number_opt.value();
     TimeDelta unit = unit_opt.value();
diff --git a/base/time/time_delta_from_string.h b/base/time/time_delta_from_string.h
index f9f6098..b50b5e0 100644
--- a/base/time/time_delta_from_string.h
+++ b/base/time/time_delta_from_string.h
@@ -5,9 +5,10 @@
 #ifndef BASE_TIME_TIME_DELTA_FROM_STRING_H_
 #define BASE_TIME_TIME_DELTA_FROM_STRING_H_
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/strings/string_piece.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -27,10 +28,10 @@
 //  "0", "+0", "-0" -> TimeDelta()
 //  "inf", "+inf"   -> TimeDelta::Max()
 //  "-inf"          -> TimeDelta::Min()
-// Returns `absl::nullopt` when parsing fails. Numbers larger than 2^63-1
+// Returns `std::nullopt` when parsing fails. Numbers larger than 2^63-1
 // will fail parsing. Overflowing `number * unit` will return +/-inf, as
 // appropriate.
-BASE_EXPORT absl::optional<TimeDelta> TimeDeltaFromString(
+BASE_EXPORT std::optional<TimeDelta> TimeDeltaFromString(
     StringPiece duration_string);
 
 }  // namespace base
diff --git a/base/time/time_delta_from_string_unittest.cc b/base/time/time_delta_from_string_unittest.cc
index 53ff461..053e1ea 100644
--- a/base/time/time_delta_from_string_unittest.cc
+++ b/base/time/time_delta_from_string_unittest.cc
@@ -22,26 +22,26 @@
   EXPECT_EQ(TimeDeltaFromString("inf"), TimeDelta::Max());
   EXPECT_EQ(TimeDeltaFromString("+inf"), TimeDelta::Max());
   EXPECT_EQ(TimeDeltaFromString("-inf"), TimeDelta::Min());
-  EXPECT_EQ(TimeDeltaFromString("infBlah"), absl::nullopt);
+  EXPECT_EQ(TimeDeltaFromString("infBlah"), std::nullopt);
 
   // Illegal input forms.
-  EXPECT_EQ(TimeDeltaFromString(""), absl::nullopt);
-  EXPECT_EQ(TimeDeltaFromString("0.0"), absl::nullopt);
-  EXPECT_EQ(TimeDeltaFromString(".0"), absl::nullopt);
-  EXPECT_EQ(TimeDeltaFromString("."), absl::nullopt);
-  EXPECT_EQ(TimeDeltaFromString("01"), absl::nullopt);
-  EXPECT_EQ(TimeDeltaFromString("1"), absl::nullopt);
-  EXPECT_EQ(TimeDeltaFromString("-1"), absl::nullopt);
-  EXPECT_EQ(TimeDeltaFromString("2"), absl::nullopt);
-  EXPECT_EQ(TimeDeltaFromString("2 s"), absl::nullopt);
-  EXPECT_EQ(TimeDeltaFromString(".s"), absl::nullopt);
-  EXPECT_EQ(TimeDeltaFromString("-.s"), absl::nullopt);
-  EXPECT_EQ(TimeDeltaFromString("s"), absl::nullopt);
-  EXPECT_EQ(TimeDeltaFromString(" 2s"), absl::nullopt);
-  EXPECT_EQ(TimeDeltaFromString("2s "), absl::nullopt);
-  EXPECT_EQ(TimeDeltaFromString(" 2s "), absl::nullopt);
-  EXPECT_EQ(TimeDeltaFromString("2mt"), absl::nullopt);
-  EXPECT_EQ(TimeDeltaFromString("1e3s"), absl::nullopt);
+  EXPECT_EQ(TimeDeltaFromString(""), std::nullopt);
+  EXPECT_EQ(TimeDeltaFromString("0.0"), std::nullopt);
+  EXPECT_EQ(TimeDeltaFromString(".0"), std::nullopt);
+  EXPECT_EQ(TimeDeltaFromString("."), std::nullopt);
+  EXPECT_EQ(TimeDeltaFromString("01"), std::nullopt);
+  EXPECT_EQ(TimeDeltaFromString("1"), std::nullopt);
+  EXPECT_EQ(TimeDeltaFromString("-1"), std::nullopt);
+  EXPECT_EQ(TimeDeltaFromString("2"), std::nullopt);
+  EXPECT_EQ(TimeDeltaFromString("2 s"), std::nullopt);
+  EXPECT_EQ(TimeDeltaFromString(".s"), std::nullopt);
+  EXPECT_EQ(TimeDeltaFromString("-.s"), std::nullopt);
+  EXPECT_EQ(TimeDeltaFromString("s"), std::nullopt);
+  EXPECT_EQ(TimeDeltaFromString(" 2s"), std::nullopt);
+  EXPECT_EQ(TimeDeltaFromString("2s "), std::nullopt);
+  EXPECT_EQ(TimeDeltaFromString(" 2s "), std::nullopt);
+  EXPECT_EQ(TimeDeltaFromString("2mt"), std::nullopt);
+  EXPECT_EQ(TimeDeltaFromString("1e3s"), std::nullopt);
 
   // One unit type.
   EXPECT_EQ(TimeDeltaFromString("1ns"), Nanoseconds(1));
@@ -59,7 +59,7 @@
             Microseconds(-9223372036854775807));
 
   // Overflow count. Note the "93" at the beginning (instead of "92").
-  EXPECT_EQ(TimeDeltaFromString("9323372036854775807us"), absl::nullopt);
+  EXPECT_EQ(TimeDeltaFromString("9323372036854775807us"), std::nullopt);
   // Overflow overall duration.
   EXPECT_EQ(TimeDeltaFromString("9323372036854s"), TimeDelta::Max());
   EXPECT_EQ(TimeDeltaFromString("-9323372036854s"), TimeDelta::Min());
@@ -99,9 +99,9 @@
   EXPECT_EQ(TimeDeltaFromString("-1d"), Days(-1));
 
   EXPECT_EQ(TimeDeltaFromString("-1h2s"), -(Hours(1) + Seconds(2)));
-  EXPECT_EQ(TimeDeltaFromString("1h-2s"), absl::nullopt);
-  EXPECT_EQ(TimeDeltaFromString("-1h-2s"), absl::nullopt);
-  EXPECT_EQ(TimeDeltaFromString("-1h -2s"), absl::nullopt);
+  EXPECT_EQ(TimeDeltaFromString("1h-2s"), std::nullopt);
+  EXPECT_EQ(TimeDeltaFromString("-1h-2s"), std::nullopt);
+  EXPECT_EQ(TimeDeltaFromString("-1h -2s"), std::nullopt);
 }
 
 }  // namespace
diff --git a/base/time/time_now_posix.cc b/base/time/time_now_posix.cc
index b0ecb39..8d8f16d 100644
--- a/base/time/time_now_posix.cc
+++ b/base/time/time_now_posix.cc
@@ -2,19 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/time/time.h"
-
 #include <stdint.h>
 #include <sys/time.h>
 #include <time.h>
 #include <unistd.h>
 
+#include <optional>
+
 #include "base/check.h"
 #include "base/notreached.h"
 #include "base/numerics/safe_math.h"
+#include "base/time/time.h"
 #include "base/time/time_override.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_ANDROID) && !defined(__LP64__)
 #include <time64.h>
@@ -56,12 +56,12 @@
   return ConvertTimespecToMicros(ts);
 }
 
-absl::optional<int64_t> MaybeClockNow(clockid_t clk_id) {
+std::optional<int64_t> MaybeClockNow(clockid_t clk_id) {
   struct timespec ts;
   int res = clock_gettime(clk_id, &ts);
   if (res == 0)
     return ConvertTimespecToMicros(ts);
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 #else  // _POSIX_MONOTONIC_CLOCK
@@ -100,11 +100,11 @@
   return TimeTicks() + Microseconds(ClockNow(CLOCK_MONOTONIC));
 }
 
-absl::optional<TimeTicks> MaybeTimeTicksNowIgnoringOverride() {
-  absl::optional<int64_t> now = MaybeClockNow(CLOCK_MONOTONIC);
+std::optional<TimeTicks> MaybeTimeTicksNowIgnoringOverride() {
+  std::optional<int64_t> now = MaybeClockNow(CLOCK_MONOTONIC);
   if (now.has_value())
     return TimeTicks() + Microseconds(now.value());
-  return absl::nullopt;
+  return std::nullopt;
 }
 }  // namespace subtle
 
diff --git a/base/time/time_override.h b/base/time/time_override.h
index f51bb0d..8050d917 100644
--- a/base/time/time_override.h
+++ b/base/time/time_override.h
@@ -6,11 +6,11 @@
 #define BASE_TIME_TIME_OVERRIDE_H_
 
 #include <atomic>
+#include <optional>
 
 #include "base/base_export.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -67,8 +67,8 @@
 
 #if BUILDFLAG(IS_POSIX)
 // Equivalent to TimeTicksNowIgnoringOverride(), but is allowed to fail and
-// return absl::nullopt. This may safely be used in a signal handler.
-BASE_EXPORT absl::optional<TimeTicks> MaybeTimeTicksNowIgnoringOverride();
+// return std::nullopt. This may safely be used in a signal handler.
+BASE_EXPORT std::optional<TimeTicks> MaybeTimeTicksNowIgnoringOverride();
 #endif
 
 }  // namespace subtle
diff --git a/base/time/time_unittest.cc b/base/time/time_unittest.cc
index 61d85602..73dda779e 100644
--- a/base/time/time_unittest.cc
+++ b/base/time/time_unittest.cc
@@ -8,6 +8,7 @@
 #include <time.h>
 
 #include <limits>
+#include <optional>
 #include <string>
 
 #include "base/build_time.h"
@@ -22,7 +23,6 @@
 #include "build/build_config.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/icu/source/common/unicode/utypes.h"
 #include "third_party/icu/source/i18n/unicode/timezone.h"
 
@@ -52,9 +52,9 @@
 const char kBangkokTimeZoneId[] = "Asia/Bangkok";
 
 // Returns the total offset (including Daylight Saving Time) of the timezone
-// with |timezone_id| at |time|, or absl::nullopt in case of failure.
-absl::optional<base::TimeDelta> GetTimeZoneOffsetAtTime(const char* timezone_id,
-                                                        Time time) {
+// with |timezone_id| at |time|, or std::nullopt in case of failure.
+std::optional<base::TimeDelta> GetTimeZoneOffsetAtTime(const char* timezone_id,
+                                                       Time time) {
   std::unique_ptr<icu::TimeZone> tz(icu::TimeZone::createTimeZone(timezone_id));
   if (*tz == icu::TimeZone::getUnknown()) {
     return {};
@@ -109,7 +109,7 @@
   static constexpr char kTZ[] = "TZ";
 
   bool success_ = true;
-  absl::optional<std::string> old_timezone_;
+  std::optional<std::string> old_timezone_;
 };
 
 constexpr char ScopedLibcTZ::kTZ[];
@@ -1208,7 +1208,7 @@
   Time time;
   ASSERT_TRUE(base::Time::FromUTCExploded(utc_exploded_orig, &time));
 
-  absl::optional<TimeDelta> expected_delta =
+  std::optional<TimeDelta> expected_delta =
       GetTimeZoneOffsetAtTime(kBangkokTimeZoneId, time);
 
   ASSERT_TRUE(expected_delta.has_value());
diff --git a/base/token.cc b/base/token.cc
index 27e77d5..ccdb1709 100644
--- a/base/token.cc
+++ b/base/token.cc
@@ -6,13 +6,14 @@
 
 #include <inttypes.h>
 
+#include <optional>
+
 #include "base/check.h"
 #include "base/hash/hash.h"
 #include "base/pickle.h"
 #include "base/rand_util.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/stringprintf.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -34,9 +35,9 @@
 }
 
 // static
-absl::optional<Token> Token::FromString(StringPiece string_representation) {
+std::optional<Token> Token::FromString(StringPiece string_representation) {
   if (string_representation.size() != 32) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   uint64_t words[2];
   for (size_t i = 0; i < 2; i++) {
@@ -50,12 +51,12 @@
       } else if (('A' <= c) && (c <= 'F')) {
         word = (word << 4) | static_cast<uint64_t>(c - 'A' + 10);
       } else {
-        return absl::nullopt;
+        return std::nullopt;
       }
     }
     words[i] = word;
   }
-  return absl::optional<Token>(absl::in_place, words[0], words[1]);
+  return std::optional<Token>(std::in_place, words[0], words[1]);
 }
 
 void WriteTokenToPickle(Pickle* pickle, const Token& token) {
@@ -63,14 +64,14 @@
   pickle->WriteUInt64(token.low());
 }
 
-absl::optional<Token> ReadTokenFromPickle(PickleIterator* pickle_iterator) {
+std::optional<Token> ReadTokenFromPickle(PickleIterator* pickle_iterator) {
   uint64_t high;
   if (!pickle_iterator->ReadUInt64(&high))
-    return absl::nullopt;
+    return std::nullopt;
 
   uint64_t low;
   if (!pickle_iterator->ReadUInt64(&low))
-    return absl::nullopt;
+    return std::nullopt;
 
   return Token(high, low);
 }
diff --git a/base/token.h b/base/token.h
index aab6045..faa2dde 100644
--- a/base/token.h
+++ b/base/token.h
@@ -8,12 +8,12 @@
 #include <stdint.h>
 
 #include <compare>
+#include <optional>
 #include <string>
 
 #include "base/base_export.h"
 #include "base/containers/span.h"
 #include "base/strings/string_piece.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -59,9 +59,9 @@
   // Generates a string representation of this Token useful for e.g. logging.
   std::string ToString() const;
 
-  // FromString is the opposite of ToString. It returns absl::nullopt if the
+  // FromString is the opposite of ToString. It returns std::nullopt if the
   // |string_representation| is invalid.
-  static absl::optional<Token> FromString(StringPiece string_representation);
+  static std::optional<Token> FromString(StringPiece string_representation);
 
  private:
   // Note: Two uint64_t are used instead of uint8_t[16] in order to have a
@@ -81,7 +81,7 @@
 
 // For serializing and deserializing Token values.
 BASE_EXPORT void WriteTokenToPickle(Pickle* pickle, const Token& token);
-BASE_EXPORT absl::optional<Token> ReadTokenFromPickle(
+BASE_EXPORT std::optional<Token> ReadTokenFromPickle(
     PickleIterator* pickle_iterator);
 
 }  // namespace base
diff --git a/base/trace_event/interned_args_helper.cc b/base/trace_event/interned_args_helper.cc
index 2e92d90..7a2edef4 100644
--- a/base/trace_event/interned_args_helper.cc
+++ b/base/trace_event/interned_args_helper.cc
@@ -112,7 +112,7 @@
 }
 
 // static
-absl::optional<size_t> InternedUnsymbolizedSourceLocation::Get(
+std::optional<size_t> InternedUnsymbolizedSourceLocation::Get(
     perfetto::EventContext* ctx,
     uintptr_t address) {
   auto* index_for_field = GetOrCreateIndexForField(ctx->GetIncrementalState());
@@ -131,7 +131,7 @@
       index_for_field->module_cache_.GetModuleForAddress(address);
 #endif
   if (!module) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   size_t iid;
   if (index_for_field->index_.LookUpOrInsert(&iid, address)) {
diff --git a/base/trace_event/interned_args_helper.h b/base/trace_event/interned_args_helper.h
index 09941fe..5eea6ff 100644
--- a/base/trace_event/interned_args_helper.h
+++ b/base/trace_event/interned_args_helper.h
@@ -5,6 +5,7 @@
 #ifndef BASE_TRACE_EVENT_INTERNED_ARGS_HELPER_H_
 #define BASE_TRACE_EVENT_INTERNED_ARGS_HELPER_H_
 
+#include <optional>
 #include <string>
 
 #include "base/base_export.h"
@@ -14,7 +15,6 @@
 #include "base/profiler/module_cache.h"
 #include "base/trace_event/trace_event.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/perfetto/include/perfetto/tracing/track_event_interned_data_index.h"
 #include "third_party/perfetto/protos/perfetto/trace/interned_data/interned_data.pbzero.h"
 
@@ -169,8 +169,8 @@
           uintptr_t> {
   // We need a custom Get implementation to use ModuleCache, and to return
   // a nullopt if a module for the given address cannot be found.
-  static absl::optional<size_t> Get(perfetto::EventContext* ctx,
-                                    uintptr_t address);
+  static std::optional<size_t> Get(perfetto::EventContext* ctx,
+                                   uintptr_t address);
   static void Add(perfetto::protos::pbzero::InternedData* interned_data,
                   size_t iid,
                   const UnsymbolizedSourceLocation& location);
diff --git a/base/trace_event/memory_allocator_dump.h b/base/trace_event/memory_allocator_dump.h
index 3688048..ab6d834 100644
--- a/base/trace_event/memory_allocator_dump.h
+++ b/base/trace_event/memory_allocator_dump.h
@@ -9,6 +9,7 @@
 
 #include <iosfwd>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -16,7 +17,6 @@
 #include "base/trace_event/memory_allocator_dump_guid.h"
 #include "base/trace_event/memory_dump_request_args.h"
 #include "base/unguessable_token.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace perfetto {
 namespace protos {
@@ -148,8 +148,7 @@
   MemoryAllocatorDumpGuid guid_;
   MemoryDumpLevelOfDetail level_of_detail_;
   int flags_;  // See enum Flags.
-  mutable absl::optional<uint64_t>
-      cached_size_;  // Lazy, for GetSizeInternal().
+  mutable std::optional<uint64_t> cached_size_;  // Lazy, for GetSizeInternal().
   std::vector<Entry> entries_;
 };
 
diff --git a/base/trace_event/process_memory_dump.cc b/base/trace_event/process_memory_dump.cc
index 71c458c..31b2c70a 100644
--- a/base/trace_event/process_memory_dump.cc
+++ b/base/trace_event/process_memory_dump.cc
@@ -7,6 +7,7 @@
 #include <errno.h>
 
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "base/bits.h"
@@ -23,7 +24,6 @@
 #include "base/trace_event/traced_value.h"
 #include "base/unguessable_token.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/perfetto/protos/perfetto/trace/memory_graph.pbzero.h"
 #include "third_party/perfetto/protos/perfetto/trace/trace_packet.pbzero.h"
 
@@ -93,7 +93,7 @@
 }
 
 // static
-absl::optional<size_t> ProcessMemoryDump::CountResidentBytes(
+std::optional<size_t> ProcessMemoryDump::CountResidentBytes(
     void* start_address,
     size_t mapped_size) {
   const size_t page_size = GetSystemPageSize();
@@ -176,13 +176,13 @@
   DCHECK(!failure);
   if (failure) {
     LOG(ERROR) << "CountResidentBytes failed. The resident size is invalid";
-    return absl::nullopt;
+    return std::nullopt;
   }
   return total_resident_pages;
 }
 
 // static
-absl::optional<size_t> ProcessMemoryDump::CountResidentBytesInSharedMemory(
+std::optional<size_t> ProcessMemoryDump::CountResidentBytesInSharedMemory(
     void* start_address,
     size_t mapped_size) {
   // `MapAt()` performs some internal arithmetic to allow non-page-aligned
@@ -211,7 +211,7 @@
   if (result == MachVMRegionResult::Error) {
     LOG(ERROR) << "CountResidentBytesInSharedMemory failed. The resident size "
                   "is invalid";
-    return absl::optional<size_t>();
+    return std::optional<size_t>();
   }
 
   size_t resident_pages =
diff --git a/base/trace_event/process_memory_dump.h b/base/trace_event/process_memory_dump.h
index c47a25a..1fb6341 100644
--- a/base/trace_event/process_memory_dump.h
+++ b/base/trace_event/process_memory_dump.h
@@ -8,6 +8,7 @@
 #include <stddef.h>
 
 #include <map>
+#include <optional>
 #include <unordered_map>
 #include <vector>
 
@@ -18,7 +19,6 @@
 #include "base/trace_event/memory_allocator_dump_guid.h"
 #include "base/trace_event/memory_dump_request_args.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // Define COUNT_RESIDENT_BYTES_SUPPORTED if platform supports counting of the
 // resident memory.
@@ -77,12 +77,12 @@
   // |start_address| and |mapped_size|. |mapped_size| is specified in bytes. The
   // value returned is valid only if the given range is currently mmapped by the
   // process. The |start_address| must be page-aligned.
-  static absl::optional<size_t> CountResidentBytes(void* start_address,
-                                                   size_t mapped_size);
+  static std::optional<size_t> CountResidentBytes(void* start_address,
+                                                  size_t mapped_size);
 
   // The same as above, but the given mapped range should belong to the
   // shared_memory's mapped region.
-  static absl::optional<size_t> CountResidentBytesInSharedMemory(
+  static std::optional<size_t> CountResidentBytesInSharedMemory(
       void* start_address,
       size_t mapped_size);
 #endif
diff --git a/base/trace_event/process_memory_dump_unittest.cc b/base/trace_event/process_memory_dump_unittest.cc
index 2a68c72..c41775c 100644
--- a/base/trace_event/process_memory_dump_unittest.cc
+++ b/base/trace_event/process_memory_dump_unittest.cc
@@ -7,6 +7,7 @@
 #include <stddef.h>
 
 #include <memory>
+#include <optional>
 
 #include "base/memory/aligned_memory.h"
 #include "base/memory/ptr_util.h"
@@ -19,7 +20,6 @@
 #include "base/trace_event/traced_value.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_WIN)
 #include <windows.h>
@@ -489,7 +489,7 @@
   const size_t size1 = 5 * page_size;
   void* memory1 = Map(size1);
   memset(memory1, 0, size1);
-  absl::optional<size_t> res1 =
+  std::optional<size_t> res1 =
       ProcessMemoryDump::CountResidentBytes(memory1, size1);
   ASSERT_TRUE(res1.has_value());
   ASSERT_EQ(res1.value(), size1);
@@ -499,7 +499,7 @@
   const size_t kVeryLargeMemorySize = 15 * 1024 * 1024;
   void* memory2 = Map(kVeryLargeMemorySize);
   memset(memory2, 0, kVeryLargeMemorySize);
-  absl::optional<size_t> res2 =
+  std::optional<size_t> res2 =
       ProcessMemoryDump::CountResidentBytes(memory2, kVeryLargeMemorySize);
   ASSERT_TRUE(res2.has_value());
   ASSERT_EQ(res2.value(), kVeryLargeMemorySize);
@@ -522,7 +522,7 @@
     auto region = base::WritableSharedMemoryRegion::Create(kDirtyMemorySize);
     base::WritableSharedMemoryMapping mapping = region.Map();
     memset(mapping.memory(), 0, kDirtyMemorySize);
-    absl::optional<size_t> res1 =
+    std::optional<size_t> res1 =
         ProcessMemoryDump::CountResidentBytesInSharedMemory(
             mapping.memory(), mapping.mapped_size());
     ASSERT_TRUE(res1.has_value());
@@ -537,7 +537,7 @@
     base::WritableSharedMemoryMapping mapping =
         region.MapAt(page_size / 2, kDirtyMemorySize);
     memset(mapping.memory(), 0, kDirtyMemorySize);
-    absl::optional<size_t> res1 =
+    std::optional<size_t> res1 =
         ProcessMemoryDump::CountResidentBytesInSharedMemory(
             mapping.memory(), mapping.mapped_size());
     ASSERT_TRUE(res1.has_value());
@@ -551,7 +551,7 @@
         base::WritableSharedMemoryRegion::Create(kVeryLargeMemorySize);
     base::WritableSharedMemoryMapping mapping = region.Map();
     memset(mapping.memory(), 0, kVeryLargeMemorySize);
-    absl::optional<size_t> res2 =
+    std::optional<size_t> res2 =
         ProcessMemoryDump::CountResidentBytesInSharedMemory(
             mapping.memory(), mapping.mapped_size());
     ASSERT_TRUE(res2.has_value());
@@ -564,7 +564,7 @@
     auto region = base::WritableSharedMemoryRegion::Create(kTouchedMemorySize);
     base::WritableSharedMemoryMapping mapping = region.Map();
     memset(mapping.memory(), 0, kTouchedMemorySize);
-    absl::optional<size_t> res3 =
+    std::optional<size_t> res3 =
         ProcessMemoryDump::CountResidentBytesInSharedMemory(
             mapping.memory(), mapping.mapped_size());
     ASSERT_TRUE(res3.has_value());
diff --git a/base/trace_event/trace_config.cc b/base/trace_event/trace_config.cc
index b0e5a66..d25da0a 100644
--- a/base/trace_event/trace_config.cc
+++ b/base/trace_event/trace_config.cc
@@ -7,6 +7,7 @@
 #include <stddef.h>
 
 #include <algorithm>
+#include <optional>
 #include <utility>
 
 #include "base/json/json_reader.h"
@@ -18,7 +19,6 @@
 #include "base/trace_event/memory_dump_manager.h"
 #include "base/trace_event/memory_dump_request_args.h"
 #include "base/trace_event/trace_event.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
 #include "third_party/perfetto/protos/perfetto/config/track_event/track_event_config.gen.h"  // nogncheck
@@ -480,7 +480,7 @@
 }
 
 void TraceConfig::InitializeFromConfigString(StringPiece config_string) {
-  absl::optional<Value> dict = JSONReader::Read(config_string);
+  std::optional<Value> dict = JSONReader::Read(config_string);
   if (dict && dict->is_dict())
     InitializeFromConfigDict(dict->GetDict());
   else
@@ -571,7 +571,7 @@
       const Value::Dict& trigger_dict = trigger.GetDict();
 
       MemoryDumpConfig::Trigger dump_config;
-      absl::optional<int> interval = trigger_dict.FindInt(kMinTimeBetweenDumps);
+      std::optional<int> interval = trigger_dict.FindInt(kMinTimeBetweenDumps);
       if (!interval) {
         // If "min_time_between_dumps_ms" param was not given, then the trace
         // config uses old format where only periodic dumps are supported.
@@ -601,7 +601,7 @@
   const Value::Dict* heap_profiler_options =
       memory_dump_config.FindDict(kHeapProfilerOptions);
   if (heap_profiler_options) {
-    absl::optional<int> min_size_bytes =
+    std::optional<int> min_size_bytes =
         heap_profiler_options->FindInt(kBreakdownThresholdBytes);
     if (min_size_bytes && *min_size_bytes >= 0) {
       memory_dump_config_.heap_profiler_options.breakdown_threshold_bytes =
diff --git a/base/trace_event/trace_config_unittest.cc b/base/trace_event/trace_config_unittest.cc
index f965863..dc112329 100644
--- a/base/trace_event/trace_config_unittest.cc
+++ b/base/trace_event/trace_config_unittest.cc
@@ -2,15 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/trace_event/trace_config.h"
+
 #include <stddef.h>
 
+#include <optional>
+
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
 #include "base/trace_event/memory_dump_manager.h"
-#include "base/trace_event/trace_config.h"
 #include "base/trace_event/trace_config_memory_test_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base::trace_event {
 
@@ -359,7 +361,7 @@
   EXPECT_FALSE(tc.IsEventPackageNameFilterEnabled());
   EXPECT_STREQ("", tc.ToCategoryFilterString().c_str());
 
-  absl::optional<Value> default_value =
+  std::optional<Value> default_value =
       JSONReader::Read(kDefaultTraceConfigString);
   ASSERT_TRUE(default_value);
   ASSERT_TRUE(default_value->is_dict());
@@ -371,7 +373,7 @@
   EXPECT_FALSE(default_tc.IsArgumentFilterEnabled());
   EXPECT_STREQ("", default_tc.ToCategoryFilterString().c_str());
 
-  absl::optional<Value> custom_value =
+  std::optional<Value> custom_value =
       JSONReader::Read(kCustomTraceConfigString);
   ASSERT_TRUE(custom_value);
   ASSERT_TRUE(custom_value->is_dict());
diff --git a/base/trace_event/trace_event_unittest.cc b/base/trace_event/trace_event_unittest.cc
index b77911a..cf42edc15 100644
--- a/base/trace_event/trace_event_unittest.cc
+++ b/base/trace_event/trace_event_unittest.cc
@@ -207,7 +207,7 @@
   trace_buffer_.AddFragment(events_str->data());
   trace_buffer_.Finish();
 
-  absl::optional<Value> root = base::JSONReader::Read(
+  std::optional<Value> root = base::JSONReader::Read(
       json_output_.json_output, JSON_PARSE_RFC | JSON_ALLOW_CONTROL_CHARS);
 
   if (!root.has_value()) {
@@ -796,8 +796,8 @@
     if (!name || *name != "multi thread event")
       continue;
 
-    absl::optional<int> maybe_thread = dict->FindIntByDottedPath("args.thread");
-    absl::optional<int> maybe_event = dict->FindIntByDottedPath("args.event");
+    std::optional<int> maybe_thread = dict->FindIntByDottedPath("args.thread");
+    std::optional<int> maybe_event = dict->FindIntByDottedPath("args.event");
 
     EXPECT_TRUE(maybe_thread.has_value());
     EXPECT_TRUE(maybe_event.has_value());
@@ -1461,7 +1461,7 @@
   for (const Value::Dict* item : items) {
     ASSERT_TRUE(item);
 
-    absl::optional<int> maybe_tid = item->FindInt("tid");
+    std::optional<int> maybe_tid = item->FindInt("tid");
     EXPECT_TRUE(maybe_tid.has_value());
 
     // See if this thread name is one of the threads we just created
@@ -2085,7 +2085,7 @@
 
   EXPECT_TRUE(trace_full_metadata);
   EXPECT_EQ(*trace_full_metadata->FindString("ph"), "M");
-  absl::optional<double> maybe_buffer_limit_reached_timestamp =
+  std::optional<double> maybe_buffer_limit_reached_timestamp =
       trace_full_metadata->FindDoubleByDottedPath("args.overflowed_at_ts");
 
   EXPECT_EQ(*maybe_buffer_limit_reached_timestamp,
@@ -2098,7 +2098,7 @@
   ASSERT_TRUE(!trace_parsed_.empty());
   const Value& last_trace_event = trace_parsed_.back();
   EXPECT_TRUE(last_trace_event.is_dict());
-  absl::optional<double> maybe_last_trace_event_timestamp =
+  std::optional<double> maybe_last_trace_event_timestamp =
       last_trace_event.GetDict().FindDouble("ts");
   EXPECT_TRUE(maybe_last_trace_event_timestamp.has_value());
   EXPECT_LE(maybe_last_trace_event_timestamp.value(),
@@ -2473,7 +2473,7 @@
   double last_timestamp = 0;
   for (const Value& item : trace_parsed_) {
     EXPECT_TRUE(item.is_dict());
-    absl::optional<double> timestamp = item.GetDict().FindDouble("ts");
+    std::optional<double> timestamp = item.GetDict().FindDouble("ts");
     EXPECT_TRUE(timestamp.has_value());
     EXPECT_GE(timestamp.value(), last_timestamp);
     EXPECT_LE(timestamp.value(), end_time);
diff --git a/base/trace_event/trace_log.h b/base/trace_event/trace_log.h
index 6e6dbb9..7be7c05 100644
--- a/base/trace_event/trace_log.h
+++ b/base/trace_event/trace_log.h
@@ -11,6 +11,7 @@
 #include <atomic>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <unordered_map>
 #include <vector>
@@ -29,7 +30,6 @@
 #include "base/trace_event/trace_config.h"
 #include "base/trace_event/trace_event_impl.h"
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
 #include "third_party/perfetto/include/perfetto/tracing/core/trace_config.h"
@@ -645,7 +645,7 @@
 #endif  // BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
 
 #if BUILDFLAG(IS_ANDROID)
-  absl::optional<TraceConfig> atrace_startup_config_;
+  std::optional<TraceConfig> atrace_startup_config_;
 #endif
 };
 
diff --git a/base/trace_event/traced_value_support.h b/base/trace_event/traced_value_support.h
index 0e58679..f418ef96 100644
--- a/base/trace_event/traced_value_support.h
+++ b/base/trace_event/traced_value_support.h
@@ -5,17 +5,16 @@
 #ifndef BASE_TRACE_EVENT_TRACED_VALUE_SUPPORT_H_
 #define BASE_TRACE_EVENT_TRACED_VALUE_SUPPORT_H_
 
+#include <optional>
 #include <string_view>
 
 #include "base/memory/raw_ptr.h"
 #include "base/memory/raw_ref.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
-
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "base/unguessable_token.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/perfetto/include/perfetto/tracing/traced_proto.h"
 #include "third_party/perfetto/include/perfetto/tracing/traced_value.h"
 
@@ -66,16 +65,16 @@
   }
 };
 
-// If T is serialisable into a trace, absl::optional<T> is serialisable as well.
-// Note that we need definitions for both absl::optional<T>& and
-// const absl::optional<T>& (unlike scoped_refptr and WeakPtr above), as
+// If T is serialisable into a trace, std::optional<T> is serialisable as well.
+// Note that we need definitions for both std::optional<T>& and
+// const std::optional<T>& (unlike scoped_refptr and WeakPtr above), as
 // dereferencing const scoped_refptr<T>& gives you T, while dereferencing const
-// absl::optional<T>& gives you const T&.
+// std::optional<T>& gives you const T&.
 template <class T>
-struct TraceFormatTraits<::absl::optional<T>,
+struct TraceFormatTraits<::std::optional<T>,
                          perfetto::check_traced_value_support_t<T>> {
   static void WriteIntoTrace(perfetto::TracedValue context,
-                             const ::absl::optional<T>& value) {
+                             const ::std::optional<T>& value) {
     if (!value) {
       std::move(context).WritePointer(nullptr);
       return;
@@ -84,7 +83,7 @@
   }
 
   static void WriteIntoTrace(perfetto::TracedValue context,
-                             ::absl::optional<T>& value) {
+                             ::std::optional<T>& value) {
     if (!value) {
       std::move(context).WritePointer(nullptr);
       return;
diff --git a/base/trace_event/traced_value_support_unittest.cc b/base/trace_event/traced_value_support_unittest.cc
index cda45e3..966b2dc6 100644
--- a/base/trace_event/traced_value_support_unittest.cc
+++ b/base/trace_event/traced_value_support_unittest.cc
@@ -4,11 +4,11 @@
 
 #include "base/trace_event/traced_value_support.h"
 
+#include <optional>
 #include <string_view>
 
 #include "base/memory/ref_counted.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/perfetto/include/perfetto/test/traced_value_test_support.h"
 
 namespace base {
@@ -61,8 +61,8 @@
 }
 
 TEST(TracedValueSupportTest, Optional) {
-  EXPECT_EQ(perfetto::TracedValueToString(absl::optional<int>()), "0x0");
-  EXPECT_EQ(perfetto::TracedValueToString(absl::optional<const int>(42)), "42");
+  EXPECT_EQ(perfetto::TracedValueToString(std::optional<int>()), "0x0");
+  EXPECT_EQ(perfetto::TracedValueToString(std::optional<const int>(42)), "42");
 }
 
 TEST(TracedValueSupportTest, WeakPtr) {
diff --git a/base/traits_bag.h b/base/traits_bag.h
index 577d8e6c..3be9f27 100644
--- a/base/traits_bag.h
+++ b/base/traits_bag.h
@@ -6,12 +6,12 @@
 #define BASE_TRAITS_BAG_H_
 
 #include <initializer_list>
+#include <optional>
 #include <tuple>
 #include <type_traits>
 #include <utility>
 
 #include "base/parameter_pack.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // A bag of Traits (structs / enums / etc...) can be an elegant alternative to
 // the builder pattern and multiple default arguments for configuring things.
@@ -170,11 +170,11 @@
 
 template <typename ArgType>
 struct OptionalEnumTraitFilter
-    : public BasicTraitFilter<ArgType, absl::optional<ArgType>> {
+    : public BasicTraitFilter<ArgType, std::optional<ArgType>> {
   constexpr OptionalEnumTraitFilter()
-      : BasicTraitFilter<ArgType, absl::optional<ArgType>>(absl::nullopt) {}
+      : BasicTraitFilter<ArgType, std::optional<ArgType>>(std::nullopt) {}
   constexpr OptionalEnumTraitFilter(ArgType arg)
-      : BasicTraitFilter<ArgType, absl::optional<ArgType>>(arg) {}
+      : BasicTraitFilter<ArgType, std::optional<ArgType>>(arg) {}
 };
 
 // Tests whether multiple given argtument types are all valid traits according
@@ -224,7 +224,7 @@
 // Helper to make getting an optional enum from a trait with a default more
 // readable.
 template <typename Enum, typename... Args>
-static constexpr absl::optional<Enum> GetOptionalEnum(Args... args) {
+static constexpr std::optional<Enum> GetOptionalEnum(Args... args) {
   return GetTraitFromArgList<OptionalEnumTraitFilter<Enum>>(args...);
 }
 
diff --git a/base/traits_bag_unittest.cc b/base/traits_bag_unittest.cc
index a98805b..bac9f00 100644
--- a/base/traits_bag_unittest.cc
+++ b/base/traits_bag_unittest.cc
@@ -4,8 +4,9 @@
 
 #include "base/traits_bag.h"
 
+#include <optional>
+
 #include "testing/gmock/include/gmock/gmock.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace trait_helpers {
@@ -76,7 +77,7 @@
   constexpr OptionalEnumTestTraits(ArgTypes... args)
       : enum_trait_a(trait_helpers::GetOptionalEnum<EnumTraitA>(args...)) {}
 
-  const absl::optional<EnumTraitA> enum_trait_a;
+  const std::optional<EnumTraitA> enum_trait_a;
 };
 
 }  // namespace
diff --git a/base/types/expected.h b/base/types/expected.h
index 00ec665..bc930dc 100644
--- a/base/types/expected.h
+++ b/base/types/expected.h
@@ -141,11 +141,11 @@
   constexpr explicit ok(U&& val) noexcept : value_(std::forward<U>(val)) {}
 
   template <typename... Args>
-  constexpr explicit ok(absl::in_place_t, Args&&... args) noexcept
+  constexpr explicit ok(std::in_place_t, Args&&... args) noexcept
       : value_(std::forward<Args>(args)...) {}
 
   template <typename U, typename... Args>
-  constexpr explicit ok(absl::in_place_t,
+  constexpr explicit ok(std::in_place_t,
                         std::initializer_list<U> il,
                         Args&&... args) noexcept
       : value_(il, std::forward<Args>(args)...) {}
@@ -212,11 +212,11 @@
       : error_(std::forward<Err>(err)) {}
 
   template <typename... Args>
-  constexpr explicit unexpected(absl::in_place_t, Args&&... args) noexcept
+  constexpr explicit unexpected(std::in_place_t, Args&&... args) noexcept
       : error_(std::forward<Args>(args)...) {}
 
   template <typename U, typename... Args>
-  constexpr explicit unexpected(absl::in_place_t,
+  constexpr explicit unexpected(std::in_place_t,
                                 std::initializer_list<U> il,
                                 Args&&... args) noexcept
       : error_(il, std::forward<Args>(args)...) {}
@@ -346,11 +346,11 @@
       : impl_(kErrTag, std::move(e.error())) {}
 
   template <typename... Args>
-  constexpr explicit expected(absl::in_place_t, Args&&... args) noexcept
+  constexpr explicit expected(std::in_place_t, Args&&... args) noexcept
       : impl_(kValTag, std::forward<Args>(args)...) {}
 
   template <typename U, typename... Args>
-  constexpr explicit expected(absl::in_place_t,
+  constexpr explicit expected(std::in_place_t,
                               std::initializer_list<U> il,
                               Args&&... args) noexcept
       : impl_(kValTag, il, std::forward<Args>(args)...) {}
@@ -704,7 +704,7 @@
       constexpr expected(unexpected<G>&& e) noexcept
       : impl_(kErrTag, std::move(e.error())) {}
 
-  constexpr explicit expected(absl::in_place_t) noexcept {}
+  constexpr explicit expected(std::in_place_t) noexcept {}
 
   template <typename... Args>
   constexpr explicit expected(unexpect_t, Args&&... args) noexcept
diff --git a/base/types/expected_internal.h b/base/types/expected_internal.h
index e6c5832c..3f03d06c 100644
--- a/base/types/expected_internal.h
+++ b/base/types/expected_internal.h
@@ -306,7 +306,7 @@
   }
 
   if constexpr (!std::is_void_v<T>) {
-    return G(absl::in_place, std::forward<Exp>(exp).value());
+    return G(std::in_place, std::forward<Exp>(exp).value());
   } else {
     return G();
   }
@@ -352,7 +352,7 @@
   }
 
   if constexpr (!std::is_void_v<U>) {
-    return expected<U, E>(absl::in_place, invoke_f());
+    return expected<U, E>(std::in_place, invoke_f());
   } else {
     invoke_f();
     return expected<U, E>();
@@ -393,7 +393,7 @@
   if constexpr (std::is_void_v<T>) {
     return expected<T, G>();
   } else {
-    return expected<T, G>(absl::in_place, std::forward<Exp>(exp).value());
+    return expected<T, G>(std::in_place, std::forward<Exp>(exp).value());
   }
 }
 
diff --git a/base/types/expected_unittest.cc b/base/types/expected_unittest.cc
index 1f8ebeb..9f0484dd5 100644
--- a/base/types/expected_unittest.cc
+++ b/base/types/expected_unittest.cc
@@ -91,17 +91,17 @@
 }
 
 TEST(Ok, DefaultConstructor) {
-  constexpr ok<int> o(absl::in_place);
+  constexpr ok<int> o(std::in_place);
   static_assert(o.value() == 0);
 }
 
 TEST(Ok, InPlaceConstructor) {
-  constexpr ok<std::pair<int, double>> o(absl::in_place, 42, 3.14);
+  constexpr ok<std::pair<int, double>> o(std::in_place, 42, 3.14);
   static_assert(o.value() == std::pair(42, 3.14));
 }
 
 TEST(Ok, InPlaceListConstructor) {
-  ok<std::vector<int>> o(absl::in_place, {1, 2, 3});
+  ok<std::vector<int>> o(std::in_place, {1, 2, 3});
   EXPECT_EQ(o.value(), std::vector({1, 2, 3}));
 }
 
@@ -144,17 +144,17 @@
 }
 
 TEST(Unexpected, DefaultConstructor) {
-  constexpr unexpected<int> unex(absl::in_place);
+  constexpr unexpected<int> unex(std::in_place);
   static_assert(unex.error() == 0);
 }
 
 TEST(Unexpected, InPlaceConstructor) {
-  constexpr unexpected<std::pair<int, double>> unex(absl::in_place, 42, 3.14);
+  constexpr unexpected<std::pair<int, double>> unex(std::in_place, 42, 3.14);
   static_assert(unex.error() == std::pair(42, 3.14));
 }
 
 TEST(Unexpected, InPlaceListConstructor) {
-  unexpected<std::vector<int>> unex(absl::in_place, {1, 2, 3});
+  unexpected<std::vector<int>> unex(std::in_place, {1, 2, 3});
   EXPECT_EQ(unex.error(), std::vector({1, 2, 3}));
 }
 
@@ -411,13 +411,13 @@
 }
 
 TEST(Expected, InPlaceConstructor) {
-  constexpr expected<Strong<int>, int> ex(absl::in_place, 42);
+  constexpr expected<Strong<int>, int> ex(std::in_place, 42);
   static_assert(ex.has_value());
   EXPECT_EQ(ex.value().value, 42);
 }
 
 TEST(Expected, InPlaceListConstructor) {
-  expected<std::vector<int>, int> ex(absl::in_place, {1, 2, 3});
+  expected<std::vector<int>, int> ex(std::in_place, {1, 2, 3});
   EXPECT_THAT(ex, test::ValueIs(std::vector({1, 2, 3})));
 }
 
@@ -918,7 +918,7 @@
 }
 
 TEST(ExpectedVoid, InPlaceConstructor) {
-  constexpr expected<void, int> ex(absl::in_place);
+  constexpr expected<void, int> ex(std::in_place);
   static_assert(ex.has_value());
 }
 
diff --git a/base/types/optional_ref.h b/base/types/optional_ref.h
index 94cb1be..76bcced 100644
--- a/base/types/optional_ref.h
+++ b/base/types/optional_ref.h
@@ -12,51 +12,50 @@
 #include "base/check.h"
 #include "base/memory/raw_ptr.h"
 #include "third_party/abseil-cpp/absl/base/attributes.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
-// `optional_ref<T>` is similar to `absl::optional<T>`, except it does not own
+// `optional_ref<T>` is similar to `std::optional<T>`, except it does not own
 // the underlying value.
 //
 // When passing an optional parameter, prefer `optional_ref` to `const
-// absl::optional<T>&` as the latter often results in hidden copies due to
+// std::optional<T>&` as the latter often results in hidden copies due to
 // implicit conversions, e.g. given the function:
 //
-//   void TakesOptionalString(const absl::optional<std::string>& str);
+//   void TakesOptionalString(const std::optional<std::string>& str);
 //
 // And a call to that looks like:
 //
 //   std::string s = "Hello world!";
 //   TakesOptionalString(s);
 //
-// This copies `s` into a temporary `absl::optional<std::string>` in order to
+// This copies `s` into a temporary `std::optional<std::string>` in order to
 // call `TakesOptionalString()`.
 //
 // The C++ style guide recommends using `const T*` instead of `const
-// absl::optional<T>&` when `T` would normally be passed by reference. However
+// std::optional<T>&` when `T` would normally be passed by reference. However
 // `const T*` is not always a good substitute because:
 //
 // - `const T*` disallows the use of temporaries, since it is not possible to
 //   take the address of a temporary.
 // - additional boilerplate (e.g. `OptionalToPtr`) is required to pass an
-//   `absl::optional<T>` to a `const T*` function parameter.
+//   `std::optional<T>` to a `const T*` function parameter.
 //
 // Like `span<T>`, mutability of `optional_ref<T>` is controlled by the template
 // argument `T`; e.g. `optional_ref<const int>` only allows const access to the
 // referenced `int` value.
 //
 // Thus, `optional_ref<const T>` can be constructed from:
-// - `absl::nullopt`
+// - `std::nullopt`
 // - `const T*` or `T*`
 // - `const T&` or `T&`
-// ` `const absl::optional<T>&` or `absl::optional<T>&`
+// ` `const std::optional<T>&` or `std::optional<T>&`
 //
 // While `optional_ref<T>` can only be constructed from:
-// - `absl::nullopt`
+// - `std::nullopt`
 // - `T*`
 // - `T&`
-// - `absl::optional<T>&`
+// - `std::optional<T>&`
 //
 // Implicit conversions are disallowed, e.g. this will not compile:
 //
@@ -69,7 +68,7 @@
 template <typename T>
 class optional_ref {
  private:
-  // Disallowed because `absl::optional` (and `std::optional`) do not allow
+  // Disallowed because `std::optional` (and `std::optional`) do not allow
   // their template argument to be a reference type.
   static_assert(!std::is_reference_v<T>,
                 "T must not be a reference type (use a pointer?)");
@@ -88,9 +87,9 @@
   // Constructs an empty `optional_ref`.
   constexpr optional_ref() = default;
   // NOLINTNEXTLINE(google-explicit-constructor)
-  constexpr optional_ref(absl::nullopt_t) {}
+  constexpr optional_ref(std::nullopt_t) {}
 
-  // Constructs an `optional_ref` from an `absl::optional`; the resulting
+  // Constructs an `optional_ref` from an `std::optional`; the resulting
   // `optional_ref` is empty iff `o` is empty.
   //
   // Note: when constructing from a const reference, `optional_ref`'s template
@@ -100,12 +99,12 @@
     requires(std::is_const_v<T> && IsCompatibleV<U>)
   // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr optional_ref(
-      const absl::optional<U>& o ABSL_ATTRIBUTE_LIFETIME_BOUND)
+      const std::optional<U>& o ABSL_ATTRIBUTE_LIFETIME_BOUND)
       : ptr_(o ? &*o : nullptr) {}
   template <typename U>
     requires(IsCompatibleV<U>)
   // NOLINTNEXTLINE(google-explicit-constructor)
-  constexpr optional_ref(absl::optional<U>& o ABSL_ATTRIBUTE_LIFETIME_BOUND)
+  constexpr optional_ref(std::optional<U>& o ABSL_ATTRIBUTE_LIFETIME_BOUND)
       : ptr_(o ? &*o : nullptr) {}
 
   // Constructs an `optional_ref` from a pointer; the resulting `optional_ref`
@@ -136,7 +135,7 @@
   constexpr optional_ref(U& r ABSL_ATTRIBUTE_LIFETIME_BOUND)
       : ptr_(std::addressof(r)) {}
 
-  // An empty `optional_ref` must be constructed with `absl::nullopt`, not
+  // An empty `optional_ref` must be constructed with `std::nullopt`, not
   // `nullptr`. Otherwise, `optional_ref<T*>` constructed with `nullptr` would
   // be ambiguous: is it empty or is it engaged with a value of `nullptr`?
   constexpr optional_ref(std::nullptr_t) = delete;
@@ -180,12 +179,12 @@
   constexpr T* as_ptr() const { return ptr_; }
 
   // Convenience method for turning a non-owning `optional_ref` into an owning
-  // `absl::optional`. Incurs a copy; useful when saving an `optional_ref`
+  // `std::optional`. Incurs a copy; useful when saving an `optional_ref`
   // function parameter as a field, et cetera.
   template <typename U = std::decay_t<T>>
     requires(std::constructible_from<U, T>)
-  constexpr absl::optional<U> CopyAsOptional() const {
-    return ptr_ ? absl::optional<U>(*ptr_) : absl::nullopt;
+  constexpr std::optional<U> CopyAsOptional() const {
+    return ptr_ ? std::optional<U>(*ptr_) : std::nullopt;
   }
 
  private:
@@ -198,9 +197,9 @@
 optional_ref(T&) -> optional_ref<T>;
 
 template <typename T>
-optional_ref(const absl::optional<T>&) -> optional_ref<const T>;
+optional_ref(const std::optional<T>&) -> optional_ref<const T>;
 template <typename T>
-optional_ref(absl::optional<T>&) -> optional_ref<T>;
+optional_ref(std::optional<T>&) -> optional_ref<T>;
 
 template <typename T>
 optional_ref(T*) -> optional_ref<T>;
diff --git a/base/types/optional_ref_unittest.cc b/base/types/optional_ref_unittest.cc
index 07ef2c71..05cb1cb 100644
--- a/base/types/optional_ref_unittest.cc
+++ b/base/types/optional_ref_unittest.cc
@@ -11,19 +11,18 @@
 
 #include "base/test/gtest_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
 namespace {
 
-// Construction from `std::nullptr_t` is disallowed; `absl::nullopt` must be
+// Construction from `std::nullptr_t` is disallowed; `std::nullopt` must be
 // used to construct an empty `optional_ref`.
 static_assert(!std::is_constructible_v<optional_ref<int>, std::nullptr_t>);
 
 // No-compile asserts for various const -> mutable conversions.
 static_assert(
-    !std::is_constructible_v<optional_ref<int>, const absl::optional<int>&>);
+    !std::is_constructible_v<optional_ref<int>, const std::optional<int>&>);
 static_assert(!std::is_constructible_v<optional_ref<int>, const int*>);
 static_assert(!std::is_constructible_v<optional_ref<int>, const int&>);
 static_assert(!std::is_constructible_v<optional_ref<int>, int&&>);
@@ -57,13 +56,13 @@
 };
 
 TEST(OptionalRefTest, FromNullopt) {
-  [](optional_ref<const int> r) { EXPECT_FALSE(r.has_value()); }(absl::nullopt);
+  [](optional_ref<const int> r) { EXPECT_FALSE(r.has_value()); }(std::nullopt);
 
-  [](optional_ref<int> r) { EXPECT_FALSE(r.has_value()); }(absl::nullopt);
+  [](optional_ref<int> r) { EXPECT_FALSE(r.has_value()); }(std::nullopt);
 }
 
 TEST(OptionalRefTest, FromConstEmptyOptional) {
-  const absl::optional<int> optional_int;
+  const std::optional<int> optional_int;
 
   [](optional_ref<const int> r) { EXPECT_FALSE(r.has_value()); }(optional_int);
 
@@ -71,7 +70,7 @@
 }
 
 TEST(OptionalRefTest, FromMutableEmptyOptional) {
-  absl::optional<int> optional_int;
+  std::optional<int> optional_int;
 
   [](optional_ref<const int> r) { EXPECT_FALSE(r.has_value()); }(optional_int);
 
@@ -79,7 +78,7 @@
 }
 
 TEST(OptionalRefTest, FromConstOptional) {
-  const absl::optional<int> optional_int(6);
+  const std::optional<int> optional_int(6);
 
   [](optional_ref<const int> r) {
     EXPECT_TRUE(r.has_value());
@@ -90,7 +89,7 @@
 }
 
 TEST(OptionalRefTest, FromMutableOptional) {
-  absl::optional<int> optional_int(6);
+  std::optional<int> optional_int(6);
 
   [](optional_ref<const int> r) {
     EXPECT_TRUE(r.has_value());
@@ -213,7 +212,7 @@
   }
 
   {
-    optional_ref<int> r1(absl::nullopt);
+    optional_ref<int> r1(std::nullopt);
     [](optional_ref<int> r2) { EXPECT_FALSE(r2.has_value()); }(r1);
   }
 }
@@ -371,12 +370,12 @@
 
 TEST(OptionalRefTest, CopyAsOptional) {
   optional_ref<int> r1;
-  absl::optional<int> o1 = r1.CopyAsOptional();
-  EXPECT_EQ(absl::nullopt, o1);
+  std::optional<int> o1 = r1.CopyAsOptional();
+  EXPECT_EQ(std::nullopt, o1);
 
   int value = 6;
   optional_ref<int> r2(value);
-  absl::optional<int> o2 = r2.CopyAsOptional();
+  std::optional<int> o2 = r2.CopyAsOptional();
   EXPECT_EQ(6, o2);
 }
 
@@ -398,33 +397,33 @@
 TEST(OptionalRefDeathTest, ArrowOnEmpty) {
   [](optional_ref<const TestClass> r) {
     EXPECT_CHECK_DEATH(r->ConstMethod());
-  }(absl::nullopt);
+  }(std::nullopt);
 
   [](optional_ref<TestClass> r) {
     EXPECT_CHECK_DEATH(r->ConstMethod());
     EXPECT_CHECK_DEATH(r->MutableMethod());
-  }(absl::nullopt);
+  }(std::nullopt);
 }
 
 TEST(OptionalRefDeathTest, StarOnEmpty) {
   [](optional_ref<const TestClass> r) {
     EXPECT_CHECK_DEATH((*r).ConstMethod());
-  }(absl::nullopt);
+  }(std::nullopt);
 
   [](optional_ref<TestClass> r) {
     EXPECT_CHECK_DEATH((*r).ConstMethod());
     EXPECT_CHECK_DEATH((*r).MutableMethod());
-  }(absl::nullopt);
+  }(std::nullopt);
 }
 
 TEST(OptionalRefDeathTest, ValueOnEmpty) {
   [](optional_ref<const TestClass> r) {
     EXPECT_CHECK_DEATH(r.value());
-  }(absl::nullopt);
+  }(std::nullopt);
 
   [](optional_ref<TestClass> r) {
     EXPECT_CHECK_DEATH(r.value());
-  }(absl::nullopt);
+  }(std::nullopt);
 }
 
 TEST(OptionalRefTest, ClassTemplateArgumentDeduction) {
@@ -442,17 +441,17 @@
     static_assert(std::is_same_v<decltype(optional_ref(i)), optional_ref<int>>);
   }
 
-  static_assert(std::is_same_v<decltype(optional_ref(absl::optional<int>())),
+  static_assert(std::is_same_v<decltype(optional_ref(std::optional<int>())),
                                optional_ref<const int>>);
 
   {
-    const absl::optional<int> o;
+    const std::optional<int> o;
     static_assert(
         std::is_same_v<decltype(optional_ref(o)), optional_ref<const int>>);
   }
 
   {
-    absl::optional<int> o;
+    std::optional<int> o;
     static_assert(std::is_same_v<decltype(optional_ref(o)), optional_ref<int>>);
   }
 
diff --git a/base/types/optional_util.h b/base/types/optional_util.h
index ad47321..f539da8 100644
--- a/base/types/optional_util.h
+++ b/base/types/optional_util.h
@@ -5,11 +5,11 @@
 #ifndef BASE_TYPES_OPTIONAL_UTIL_H_
 #define BASE_TYPES_OPTIONAL_UTIL_H_
 
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include <optional>
 
 namespace base {
 
-// Helper for converting an `absl::optional<T>` to a pointer suitable for
+// Helper for converting an `std::optional<T>` to a pointer suitable for
 // passing as a function argument (alternatively, consider using
 // `base::optional_ref`):
 //
@@ -22,42 +22,42 @@
 //   }
 //
 //  private:
-//   absl::optional<std::string> data_;
+//   std::optional<std::string> data_;
 // };
 //
 // Rationale: per the C++ style guide, if `T` would normally be passed by
 // reference, the optional version should be passed as `T*`, and *not* as
-// `const absl::optional<T>&`. Passing as `const absl::optional<T>&` leads to
+// `const std::optional<T>&`. Passing as `const std::optional<T>&` leads to
 // implicit constructions and copies, e.g.:
 //
 // // BAD: a caller passing a `std::string` implicitly copies the entire string
-// // to construct a temporary `absl::optional<std::string>` to use for the
+// // to construct a temporary `std::optional<std::string>` to use for the
 // // function argument.
-// void BadMaybeProcessData(const absl::optional<std::string>& optional_data);
+// void BadMaybeProcessData(const std::optional<std::string>& optional_data);
 //
 // For more background, see https://abseil.io/tips/163. Also see
 // `base/types/optional_ref.h` for an alternative approach to
-// `const absl::optional<T>&` that does not require the use of raw pointers.
+// `const std::optional<T>&` that does not require the use of raw pointers.
 template <class T>
-const T* OptionalToPtr(const absl::optional<T>& optional) {
+const T* OptionalToPtr(const std::optional<T>& optional) {
   return optional.has_value() ? &optional.value() : nullptr;
 }
 
 template <class T>
-T* OptionalToPtr(absl::optional<T>& optional) {
+T* OptionalToPtr(std::optional<T>& optional) {
   return optional.has_value() ? &optional.value() : nullptr;
 }
 
-// Helper for creating an `absl::optional<T>` from a `T*` which may be null.
+// Helper for creating an `std::optional<T>` from a `T*` which may be null.
 //
-// This copies `T` into the `absl::optional`. When you have control over the
+// This copies `T` into the `std::optional`. When you have control over the
 // function that accepts the optional, and it currently expects a
-// `absl::optional<T>&` or `const absl::optional<T>&`, consider changing it to
+// `std::optional<T>&` or `const std::optional<T>&`, consider changing it to
 // accept a `base::optional_ref<T>` / `base::optional_ref<const T>` instead,
 // which can be constructed from `T*` without copying.
 template <class T>
-absl::optional<T> OptionalFromPtr(const T* value) {
-  return value ? absl::optional<T>(*value) : absl::nullopt;
+std::optional<T> OptionalFromPtr(const T* value) {
+  return value ? std::optional<T>(*value) : std::nullopt;
 }
 
 }  // namespace base
diff --git a/base/types/optional_util_unittest.cc b/base/types/optional_util_unittest.cc
index 1af29138..41db0e8 100644
--- a/base/types/optional_util_unittest.cc
+++ b/base/types/optional_util_unittest.cc
@@ -10,7 +10,7 @@
 namespace {
 
 TEST(OptionalUtilTest, OptionalToPtr) {
-  absl::optional<float> optional;
+  std::optional<float> optional;
   EXPECT_EQ(nullptr, OptionalToPtr(optional));
 
   optional = 0.1f;
@@ -20,10 +20,10 @@
 
 TEST(OptionalUtilTest, OptionalFromPtr) {
   float* f_ptr = nullptr;
-  EXPECT_EQ(absl::nullopt, OptionalFromPtr(f_ptr));
+  EXPECT_EQ(std::nullopt, OptionalFromPtr(f_ptr));
 
   float f = 0.1f;
-  absl::optional<float> optional_f(f);
+  std::optional<float> optional_f(f);
   EXPECT_EQ(optional_f, OptionalFromPtr(&f));
 }
 
diff --git a/base/types/token_type.h b/base/types/token_type.h
index 44b843e..abb8b7b 100644
--- a/base/types/token_type.h
+++ b/base/types/token_type.h
@@ -17,7 +17,7 @@
 // A specialization of StrongAlias for UnguessableToken. Unlike
 // UnguessableToken, a TokenType<...> does not default to null and does not
 // expose the concept of null tokens. If you need to indicate a null token,
-// please use absl::optional<TokenType<...>>.
+// please use std::optional<TokenType<...>>.
 template <typename TypeMarker>
 class TokenType : public StrongAlias<TypeMarker, UnguessableToken> {
  private:
diff --git a/base/unguessable_token.cc b/base/unguessable_token.cc
index da65502..1f91a93 100644
--- a/base/unguessable_token.cc
+++ b/base/unguessable_token.cc
@@ -33,25 +33,25 @@
 }
 
 // static
-absl::optional<UnguessableToken> UnguessableToken::Deserialize(uint64_t high,
-                                                               uint64_t low) {
+std::optional<UnguessableToken> UnguessableToken::Deserialize(uint64_t high,
+                                                              uint64_t low) {
   // Receiving a zeroed out UnguessableToken from another process means that it
   // was never initialized via Create(). Since this method might also be used to
   // create an UnguessableToken from data on disk, we will handle this case more
   // gracefully since data could have been corrupted.
   if (high == 0 && low == 0) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return UnguessableToken(Token{high, low});
 }
 
 // static
-absl::optional<UnguessableToken> UnguessableToken::DeserializeFromString(
+std::optional<UnguessableToken> UnguessableToken::DeserializeFromString(
     StringPiece string_representation) {
   auto token = Token::FromString(string_representation);
   // A zeroed out token means that it's not initialized via Create().
   if (!token.has_value() || token.value().is_zero()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return UnguessableToken(token.value());
 }
diff --git a/base/unguessable_token.h b/base/unguessable_token.h
index 91f372f..2ec3340a 100644
--- a/base/unguessable_token.h
+++ b/base/unguessable_token.h
@@ -45,7 +45,7 @@
 // NOTE: It is illegal to send empty UnguessableTokens across processes, and
 // sending/receiving empty tokens should be treated as a security issue. If
 // there is a valid scenario for sending "no token" across processes, use
-// absl::optional instead of an empty token.
+// std::optional instead of an empty token.
 
 class BASE_EXPORT UnguessableToken {
  public:
@@ -61,19 +61,19 @@
   // Return an UnguessableToken built from the high/low bytes provided.
   // It should only be used in deserialization scenarios.
   //
-  // NOTE: If the returned `absl::optional` does not have a value, it means that
+  // NOTE: If the returned `std::optional` does not have a value, it means that
   // `high` and `low` correspond to an `UnguesssableToken` that was never
   // initialized via Create(). This is a security issue, and should be handled.
-  static absl::optional<UnguessableToken> Deserialize(uint64_t high,
-                                                      uint64_t low);
+  static std::optional<UnguessableToken> Deserialize(uint64_t high,
+                                                     uint64_t low);
 
   // Returns an `UnguessableToken` built from its string representation. It
   // should only be used in deserialization scenarios.
   //
-  // NOTE: If the returned `absl::optional` does not have a value, it means that
+  // NOTE: If the returned `std::optional` does not have a value, it means that
   // the given string does not represent a valid serialized `UnguessableToken`.
   // This should be handled as a security issue.
-  static absl::optional<UnguessableToken> DeserializeFromString(
+  static std::optional<UnguessableToken> DeserializeFromString(
       StringPiece string_representation);
 
   // Creates an empty UnguessableToken.
@@ -115,7 +115,7 @@
 
 #if defined(UNIT_TEST)
   static UnguessableToken CreateForTesting(uint64_t high, uint64_t low) {
-    absl::optional<UnguessableToken> token = Deserialize(high, low);
+    std::optional<UnguessableToken> token = Deserialize(high, low);
     DCHECK(token.has_value());
     return token.value();
   }
diff --git a/base/unguessable_token_unittest.cc b/base/unguessable_token_unittest.cc
index e190778d..f996ab7 100644
--- a/base/unguessable_token_unittest.cc
+++ b/base/unguessable_token_unittest.cc
@@ -21,14 +21,14 @@
 }
 
 TEST(UnguessableTokenTest, VerifyEveryBit) {
-  absl::optional<UnguessableToken> token = UnguessableToken::Deserialize(1, 2);
+  std::optional<UnguessableToken> token = UnguessableToken::Deserialize(1, 2);
   ASSERT_TRUE(token.has_value());
   uint64_t high = 1;
   uint64_t low = 2;
 
   for (uint64_t bit = 1; bit != 0; bit <<= 1) {
     uint64_t new_high = high ^ bit;
-    absl::optional<UnguessableToken> new_token =
+    std::optional<UnguessableToken> new_token =
         UnguessableToken::Deserialize(new_high, low);
     ASSERT_TRUE(new_token.has_value());
     EXPECT_FALSE(*token == *new_token);
@@ -36,7 +36,7 @@
 
   for (uint64_t bit = 1; bit != 0; bit <<= 1) {
     uint64_t new_low = low ^ bit;
-    absl::optional<UnguessableToken> new_token =
+    std::optional<UnguessableToken> new_token =
         UnguessableToken::Deserialize(high, new_low);
     ASSERT_TRUE(new_token.has_value());
     EXPECT_FALSE(*token == *new_token);
@@ -96,7 +96,7 @@
   EXPECT_TRUE(high);
   EXPECT_TRUE(low);
 
-  absl::optional<UnguessableToken> Deserialized =
+  std::optional<UnguessableToken> Deserialized =
       UnguessableToken::Deserialize(high, low);
   ASSERT_TRUE(Deserialized.has_value());
   EXPECT_EQ(token, *Deserialized);
@@ -141,7 +141,7 @@
 }
 
 TEST(UnguessableTokenTest, VerifyDeserializeZeroes) {
-  absl::optional<UnguessableToken> token = UnguessableToken::Deserialize(0, 0);
+  std::optional<UnguessableToken> token = UnguessableToken::Deserialize(0, 0);
 
   EXPECT_FALSE(token.has_value());
 }
diff --git a/base/values.cc b/base/values.cc
index b4fcc10..ff66e93b 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -6,6 +6,7 @@
 
 #include <cmath>
 #include <memory>
+#include <optional>
 #include <ostream>
 #include <tuple>
 #include <utility>
@@ -25,7 +26,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/trace_event/base_tracing.h"
 #include "base/tracing_buildflags.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
 
 #if BUILDFLAG(ENABLE_BASE_TRACING)
@@ -231,17 +231,17 @@
   return kTypeNames[static_cast<size_t>(type)];
 }
 
-absl::optional<bool> Value::GetIfBool() const {
-  return is_bool() ? absl::make_optional(GetBool()) : absl::nullopt;
+std::optional<bool> Value::GetIfBool() const {
+  return is_bool() ? std::make_optional(GetBool()) : std::nullopt;
 }
 
-absl::optional<int> Value::GetIfInt() const {
-  return is_int() ? absl::make_optional(GetInt()) : absl::nullopt;
+std::optional<int> Value::GetIfInt() const {
+  return is_int() ? std::make_optional(GetInt()) : std::nullopt;
 }
 
-absl::optional<double> Value::GetIfDouble() const {
-  return (is_int() || is_double()) ? absl::make_optional(GetDouble())
-                                   : absl::nullopt;
+std::optional<double> Value::GetIfDouble() const {
+  return (is_int() || is_double()) ? std::make_optional(GetDouble())
+                                   : std::nullopt;
 }
 
 const std::string* Value::GetIfString() const {
@@ -428,19 +428,19 @@
   return FindPtrOrNull(storage_, key);
 }
 
-absl::optional<bool> Value::Dict::FindBool(StringPiece key) const {
+std::optional<bool> Value::Dict::FindBool(StringPiece key) const {
   const Value* v = Find(key);
-  return v ? v->GetIfBool() : absl::nullopt;
+  return v ? v->GetIfBool() : std::nullopt;
 }
 
-absl::optional<int> Value::Dict::FindInt(StringPiece key) const {
+std::optional<int> Value::Dict::FindInt(StringPiece key) const {
   const Value* v = Find(key);
-  return v ? v->GetIfInt() : absl::nullopt;
+  return v ? v->GetIfInt() : std::nullopt;
 }
 
-absl::optional<double> Value::Dict::FindDouble(StringPiece key) const {
+std::optional<double> Value::Dict::FindDouble(StringPiece key) const {
   const Value* v = Find(key);
-  return v ? v->GetIfDouble() : absl::nullopt;
+  return v ? v->GetIfDouble() : std::nullopt;
 }
 
 const std::string* Value::Dict::FindString(StringPiece key) const {
@@ -603,12 +603,12 @@
   return storage_.erase(key) > 0;
 }
 
-absl::optional<Value> Value::Dict::Extract(StringPiece key) {
+std::optional<Value> Value::Dict::Extract(StringPiece key) {
   DCHECK(IsStringUTF8AllowingNoncharacters(key));
 
   auto it = storage_.find(key);
   if (it == storage_.end()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   Value v = std::move(*it->second);
   storage_.erase(it);
@@ -641,20 +641,20 @@
   return const_cast<Value*>(std::as_const(*this).FindByDottedPath(path));
 }
 
-absl::optional<bool> Value::Dict::FindBoolByDottedPath(StringPiece path) const {
+std::optional<bool> Value::Dict::FindBoolByDottedPath(StringPiece path) const {
   const Value* v = FindByDottedPath(path);
-  return v ? v->GetIfBool() : absl::nullopt;
+  return v ? v->GetIfBool() : std::nullopt;
 }
 
-absl::optional<int> Value::Dict::FindIntByDottedPath(StringPiece path) const {
+std::optional<int> Value::Dict::FindIntByDottedPath(StringPiece path) const {
   const Value* v = FindByDottedPath(path);
-  return v ? v->GetIfInt() : absl::nullopt;
+  return v ? v->GetIfInt() : std::nullopt;
 }
 
-absl::optional<double> Value::Dict::FindDoubleByDottedPath(
+std::optional<double> Value::Dict::FindDoubleByDottedPath(
     StringPiece path) const {
   const Value* v = FindByDottedPath(path);
-  return v ? v->GetIfDouble() : absl::nullopt;
+  return v ? v->GetIfDouble() : std::nullopt;
 }
 
 const std::string* Value::Dict::FindStringByDottedPath(StringPiece path) const {
@@ -835,7 +835,7 @@
   return std::move(*this);
 }
 
-absl::optional<Value> Value::Dict::ExtractByDottedPath(StringPiece path) {
+std::optional<Value> Value::Dict::ExtractByDottedPath(StringPiece path) {
   DCHECK(!path.empty());
   DCHECK(IsStringUTF8AllowingNoncharacters(path));
 
@@ -851,9 +851,9 @@
   StringPiece next_key = path.substr(0, dot_index);
   auto* next_dict = FindDict(next_key);
   if (!next_dict) {
-    return absl::nullopt;
+    return std::nullopt;
   }
-  absl::optional<Value> extracted =
+  std::optional<Value> extracted =
       next_dict->ExtractByDottedPath(path.substr(dot_index + 1));
   if (extracted && next_dict->empty()) {
     Remove(next_key);
diff --git a/base/values.h b/base/values.h
index a6c27642..3a4f2a18 100644
--- a/base/values.h
+++ b/base/values.h
@@ -13,6 +13,7 @@
 #include <iosfwd>
 #include <iterator>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -28,7 +29,6 @@
 #include "base/strings/string_piece.h"
 #include "base/trace_event/base_tracing_forward.h"
 #include "base/value_iterators.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
 
 namespace base {
@@ -72,9 +72,9 @@
 // returned by value. Binary blobs, `std::string`, `Value::Dict`, `Value::List`
 // are returned by reference.
 //
-// `GetIfBool()`, `GetIfInt()`, et cetera return `absl::nullopt`/`nullptr` if
+// `GetIfBool()`, `GetIfInt()`, et cetera return `std::nullopt`/`nullptr` if
 // the `Value` does not have the correct subtype; otherwise, returns the value
-// wrapped in an `absl::optional` (for `bool`, `int`, `double`) or by pointer
+// wrapped in an `std::optional` (for `bool`, `int`, `double`) or by pointer
 // (for binary blobs, `std::string`, `Value::Dict`, `Value::List`).
 //
 // Note: both `GetDouble()` and `GetIfDouble()` still return a non-null result
@@ -109,14 +109,14 @@
 //       is not present.
 // - `FindBool()`, `FindInt()`, ...: Similar to `Find()`, but ensures that the
 //       `Value` also has the correct subtype. Same return semantics as
-//       `GetIfBool()`, `GetIfInt()`, et cetera, returning `absl::nullopt` or
+//       `GetIfBool()`, `GetIfInt()`, et cetera, returning `std::nullopt` or
 //       `nullptr` if the key is not present or the value has the wrong subtype.
 // - `Set()`: Associate a value with a `StringPiece` key. Accepts `Value` or any
 //       of the subtypes that `Value` can hold.
 // - `Remove()`: Remove the key from this dictionary, if present.
 // - `Extract()`: If the key is present in the dictionary, removes the key from
 //       the dictionary and transfers ownership of `Value` to the caller.
-//       Otherwise, returns `absl::nullopt`.
+//       Otherwise, returns `std::nullopt`.
 //
 // Dictionaries also support an additional set of helper methods that operate on
 // "paths": `FindByDottedPath()`, `SetByDottedPath()`, `RemoveByDottedPath()`,
@@ -246,15 +246,15 @@
   bool is_dict() const { return type() == Type::DICT; }
   bool is_list() const { return type() == Type::LIST; }
 
-  // Returns the stored data if the type matches, or `absl::nullopt`/`nullptr`
+  // Returns the stored data if the type matches, or `std::nullopt`/`nullptr`
   // otherwise. `bool`, `int`, and `double` are returned in a wrapped
-  // `absl::optional`; blobs, `Value::Dict`, and `Value::List` are returned by
+  // `std::optional`; blobs, `Value::Dict`, and `Value::List` are returned by
   // pointer.
-  absl::optional<bool> GetIfBool() const;
-  absl::optional<int> GetIfInt() const;
+  std::optional<bool> GetIfBool() const;
+  std::optional<int> GetIfInt() const;
   // Returns a non-null value for both `Value::Type::DOUBLE` and
   // `Value::Type::INT`, converting the latter to a double.
-  absl::optional<double> GetIfDouble() const;
+  std::optional<double> GetIfDouble() const;
   const std::string* GetIfString() const;
   std::string* GetIfString();
   const BlobStorage* GetIfBlob() const;
@@ -371,15 +371,15 @@
     const Value* Find(StringPiece key) const;
     Value* Find(StringPiece key);
 
-    // Similar to `Find()` above, but returns `absl::nullopt`/`nullptr` if the
+    // Similar to `Find()` above, but returns `std::nullopt`/`nullptr` if the
     // type of the entry does not match. `bool`, `int`, and `double` are
-    // returned in a wrapped `absl::optional`; blobs, `Value::Dict`, and
+    // returned in a wrapped `std::optional`; blobs, `Value::Dict`, and
     // `Value::List` are returned by pointer.
-    absl::optional<bool> FindBool(StringPiece key) const;
-    absl::optional<int> FindInt(StringPiece key) const;
+    std::optional<bool> FindBool(StringPiece key) const;
+    std::optional<int> FindInt(StringPiece key) const;
     // Returns a non-null value for both `Value::Type::DOUBLE` and
     // `Value::Type::INT`, converting the latter to a double.
-    absl::optional<double> FindDouble(StringPiece key) const;
+    std::optional<double> FindDouble(StringPiece key) const;
     const std::string* FindString(StringPiece key) const;
     std::string* FindString(StringPiece key);
     const BlobStorage* FindBlob(StringPiece key) const;
@@ -482,8 +482,8 @@
     bool Remove(StringPiece key);
 
     // Similar to `Remove()`, but returns the value corresponding to the removed
-    // entry or `absl::nullopt` otherwise.
-    absl::optional<Value> Extract(StringPiece key);
+    // entry or `std::nullopt` otherwise.
+    std::optional<Value> Extract(StringPiece key);
 
     // Equivalent to the above methods but operating on paths instead of keys.
     // A path is shorthand syntax for referring to a key nested inside
@@ -500,11 +500,11 @@
     const Value* FindByDottedPath(StringPiece path) const;
     Value* FindByDottedPath(StringPiece path);
 
-    absl::optional<bool> FindBoolByDottedPath(StringPiece path) const;
-    absl::optional<int> FindIntByDottedPath(StringPiece path) const;
+    std::optional<bool> FindBoolByDottedPath(StringPiece path) const;
+    std::optional<int> FindIntByDottedPath(StringPiece path) const;
     // Returns a non-null value for both `Value::Type::DOUBLE` and
     // `Value::Type::INT`, converting the latter to a double.
-    absl::optional<double> FindDoubleByDottedPath(StringPiece path) const;
+    std::optional<double> FindDoubleByDottedPath(StringPiece path) const;
     const std::string* FindStringByDottedPath(StringPiece path) const;
     std::string* FindStringByDottedPath(StringPiece path);
     const BlobStorage* FindBlobByDottedPath(StringPiece path) const;
@@ -590,7 +590,7 @@
 
     bool RemoveByDottedPath(StringPiece path);
 
-    absl::optional<Value> ExtractByDottedPath(StringPiece path);
+    std::optional<Value> ExtractByDottedPath(StringPiece path);
 
     // Estimates dynamic memory usage. Requires tracing support
     // (enable_base_tracing gn flag), otherwise always returns 0. See
diff --git a/base/values_unittest.cc b/base/values_unittest.cc
index 04196d1..953bc60 100644
--- a/base/values_unittest.cc
+++ b/base/values_unittest.cc
@@ -27,7 +27,8 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 #if BUILDFLAG(ENABLE_BASE_TRACING)
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include <optional>
+
 #include "third_party/perfetto/include/perfetto/test/traced_value_test_support.h"  // no-presubmit-check nogncheck
 #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
 
@@ -76,9 +77,9 @@
 TEST(ValuesTest, EmptyValue) {
   Value value;
   EXPECT_EQ(Value::Type::NONE, value.type());
-  EXPECT_EQ(absl::nullopt, value.GetIfBool());
-  EXPECT_EQ(absl::nullopt, value.GetIfInt());
-  EXPECT_EQ(absl::nullopt, value.GetIfDouble());
+  EXPECT_EQ(std::nullopt, value.GetIfBool());
+  EXPECT_EQ(std::nullopt, value.GetIfInt());
+  EXPECT_EQ(std::nullopt, value.GetIfDouble());
   EXPECT_EQ(nullptr, value.GetIfString());
   EXPECT_EQ(nullptr, value.GetIfBlob());
 }
@@ -898,14 +899,14 @@
   dict.Set("list", Value::List());
   dict.Set("dict", Value::Dict());
 
-  EXPECT_EQ(absl::nullopt, dict.FindBool("null"));
-  EXPECT_NE(absl::nullopt, dict.FindBool("bool"));
-  EXPECT_EQ(absl::nullopt, dict.FindBool("int"));
-  EXPECT_EQ(absl::nullopt, dict.FindBool("double"));
-  EXPECT_EQ(absl::nullopt, dict.FindBool("string"));
-  EXPECT_EQ(absl::nullopt, dict.FindBool("blob"));
-  EXPECT_EQ(absl::nullopt, dict.FindBool("list"));
-  EXPECT_EQ(absl::nullopt, dict.FindBool("dict"));
+  EXPECT_EQ(std::nullopt, dict.FindBool("null"));
+  EXPECT_NE(std::nullopt, dict.FindBool("bool"));
+  EXPECT_EQ(std::nullopt, dict.FindBool("int"));
+  EXPECT_EQ(std::nullopt, dict.FindBool("double"));
+  EXPECT_EQ(std::nullopt, dict.FindBool("string"));
+  EXPECT_EQ(std::nullopt, dict.FindBool("blob"));
+  EXPECT_EQ(std::nullopt, dict.FindBool("list"));
+  EXPECT_EQ(std::nullopt, dict.FindBool("dict"));
 }
 
 TEST(ValuesTest, FindIntKey) {
@@ -919,14 +920,14 @@
   dict.Set("list", Value::List());
   dict.Set("dict", Value::Dict());
 
-  EXPECT_EQ(absl::nullopt, dict.FindInt("null"));
-  EXPECT_EQ(absl::nullopt, dict.FindInt("bool"));
-  EXPECT_NE(absl::nullopt, dict.FindInt("int"));
-  EXPECT_EQ(absl::nullopt, dict.FindInt("double"));
-  EXPECT_EQ(absl::nullopt, dict.FindInt("string"));
-  EXPECT_EQ(absl::nullopt, dict.FindInt("blob"));
-  EXPECT_EQ(absl::nullopt, dict.FindInt("list"));
-  EXPECT_EQ(absl::nullopt, dict.FindInt("dict"));
+  EXPECT_EQ(std::nullopt, dict.FindInt("null"));
+  EXPECT_EQ(std::nullopt, dict.FindInt("bool"));
+  EXPECT_NE(std::nullopt, dict.FindInt("int"));
+  EXPECT_EQ(std::nullopt, dict.FindInt("double"));
+  EXPECT_EQ(std::nullopt, dict.FindInt("string"));
+  EXPECT_EQ(std::nullopt, dict.FindInt("blob"));
+  EXPECT_EQ(std::nullopt, dict.FindInt("list"));
+  EXPECT_EQ(std::nullopt, dict.FindInt("dict"));
 }
 
 TEST(ValuesTest, FindStringKey) {
@@ -1055,7 +1056,7 @@
 }
 
 TEST(ValuesTest, SetBoolKey) {
-  absl::optional<bool> value;
+  std::optional<bool> value;
 
   Value::Dict dict;
   dict.Set("true_key", true);
@@ -1074,7 +1075,7 @@
 }
 
 TEST(ValuesTest, SetIntKey) {
-  absl::optional<int> value;
+  std::optional<int> value;
 
   Value::Dict dict;
   dict.Set("one_key", 1);
@@ -1326,13 +1327,13 @@
   root.Set("one", Value(123));
 
   // Extraction of missing key should fail.
-  EXPECT_EQ(absl::nullopt, root.Extract("two"));
+  EXPECT_EQ(std::nullopt, root.Extract("two"));
 
   // Extraction of existing key should succeed.
   EXPECT_EQ(Value(123), root.Extract("one"));
 
   // Second extraction of previously existing key should fail.
-  EXPECT_EQ(absl::nullopt, root.Extract("one"));
+  EXPECT_EQ(std::nullopt, root.Extract("one"));
 }
 
 TEST(ValuesTest, RemoveByDottedPath) {
@@ -1366,13 +1367,13 @@
   root.SetByDottedPath("one.two.three", Value(123));
 
   // Extraction of missing key should fail.
-  EXPECT_EQ(absl::nullopt, root.ExtractByDottedPath("one.two.four"));
+  EXPECT_EQ(std::nullopt, root.ExtractByDottedPath("one.two.four"));
 
   // Extraction of existing key should succeed.
   EXPECT_EQ(Value(123), root.ExtractByDottedPath("one.two.three"));
 
   // Second extraction of previously existing key should fail.
-  EXPECT_EQ(absl::nullopt, root.ExtractByDottedPath("one.two.three"));
+  EXPECT_EQ(std::nullopt, root.ExtractByDottedPath("one.two.three"));
 
   // Intermediate empty dictionaries should be cleared.
   EXPECT_EQ(nullptr, root.Find("one"));
diff --git a/base/win/access_control_list.cc b/base/win/access_control_list.cc
index 1a62ba2..f70c0e3d 100644
--- a/base/win/access_control_list.cc
+++ b/base/win/access_control_list.cc
@@ -102,15 +102,15 @@
     default;
 ExplicitAccessEntry::~ExplicitAccessEntry() = default;
 
-absl::optional<AccessControlList> AccessControlList::FromPACL(ACL* acl) {
+std::optional<AccessControlList> AccessControlList::FromPACL(ACL* acl) {
   if (acl && !::IsValidAcl(acl)) {
     ::SetLastError(ERROR_INVALID_ACL);
-    return absl::nullopt;
+    return std::nullopt;
   }
   return AccessControlList{acl};
 }
 
-absl::optional<AccessControlList> AccessControlList::FromMandatoryLabel(
+std::optional<AccessControlList> AccessControlList::FromMandatoryLabel(
     DWORD integrity_level,
     DWORD inheritance,
     DWORD mandatory_policy) {
@@ -123,12 +123,12 @@
   PACL sacl = reinterpret_cast<PACL>(sacl_ptr.get());
 
   if (!::InitializeAcl(sacl, length, ACL_REVISION)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (!::AddMandatoryAce(sacl, ACL_REVISION, inheritance, mandatory_policy,
                          sid.GetPSID())) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   DCHECK(::IsValidAcl(sacl));
diff --git a/base/win/access_control_list.h b/base/win/access_control_list.h
index 5549cc1..b3c18e0 100644
--- a/base/win/access_control_list.h
+++ b/base/win/access_control_list.h
@@ -8,12 +8,12 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "base/base_export.h"
 #include "base/win/sid.h"
 #include "base/win/windows_types.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base::win {
 
@@ -59,13 +59,13 @@
  public:
   // Create from an existing ACL pointer.
   // |acl| The ACL pointer. Passing nullptr will create a null ACL.
-  static absl::optional<AccessControlList> FromPACL(ACL* acl);
+  static std::optional<AccessControlList> FromPACL(ACL* acl);
 
   // Create an AccessControlList from a mandatory label.
   // |integrity_level| is the integrity level for the label.
   // |inheritance| inheritance flags.
   // |mandatory_policy| is the policy, e.g. SYSTEM_MANDATORY_LABEL_NO_WRITE_UP.
-  static absl::optional<AccessControlList> FromMandatoryLabel(
+  static std::optional<AccessControlList> FromMandatoryLabel(
       DWORD integrity_level,
       DWORD inheritance,
       DWORD mandatory_policy);
diff --git a/base/win/access_token.cc b/base/win/access_token.cc
index 328aed3..2e309daa 100644
--- a/base/win/access_token.cc
+++ b/base/win/access_token.cc
@@ -35,41 +35,41 @@
     PSECURITY_CAPABILITIES SecurityCapabilities,
     PHANDLE OutToken);
 
-Sid UnwrapSid(absl::optional<Sid>&& sid) {
+Sid UnwrapSid(std::optional<Sid>&& sid) {
   DCHECK(sid);
   return std::move(*sid);
 }
 
-absl::optional<std::vector<char>> GetTokenInfo(
+std::optional<std::vector<char>> GetTokenInfo(
     HANDLE token,
     TOKEN_INFORMATION_CLASS info_class) {
   // Get the buffer size. The call to GetTokenInformation should never succeed.
   DWORD size = 0;
   if (::GetTokenInformation(token, info_class, nullptr, 0, &size) || !size)
-    return absl::nullopt;
+    return std::nullopt;
 
   std::vector<char> temp_buffer(size);
   if (!::GetTokenInformation(token, info_class, temp_buffer.data(), size,
                              &size)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return std::move(temp_buffer);
 }
 
 template <typename T>
-absl::optional<T> GetTokenInfoFixed(HANDLE token,
-                                    TOKEN_INFORMATION_CLASS info_class) {
+std::optional<T> GetTokenInfoFixed(HANDLE token,
+                                   TOKEN_INFORMATION_CLASS info_class) {
   T result;
   DWORD size = sizeof(T);
   if (!::GetTokenInformation(token, info_class, &result, size, &size))
-    return absl::nullopt;
+    return std::nullopt;
 
   return result;
 }
 
 template <typename T>
-T* GetType(absl::optional<std::vector<char>>& info) {
+T* GetType(std::optional<std::vector<char>>& info) {
   DCHECK(info);
   DCHECK(info->size() >= sizeof(T));
   return reinterpret_cast<T*>(info->data());
@@ -78,7 +78,7 @@
 std::vector<AccessToken::Group> GetGroupsFromToken(
     HANDLE token,
     TOKEN_INFORMATION_CLASS info_class) {
-  absl::optional<std::vector<char>> groups = GetTokenInfo(token, info_class);
+  std::optional<std::vector<char>> groups = GetTokenInfo(token, info_class);
   // Sometimes only the GroupCount field is returned which indicates an empty
   // group set. If the buffer is smaller than the TOKEN_GROUPS structure then
   // just return an empty vector.
@@ -96,7 +96,7 @@
 }
 
 TOKEN_STATISTICS GetTokenStatistics(HANDLE token) {
-  absl::optional<TOKEN_STATISTICS> value =
+  std::optional<TOKEN_STATISTICS> value =
       GetTokenInfoFixed<TOKEN_STATISTICS>(token, TokenStatistics);
   if (!value)
     return {};
@@ -135,10 +135,10 @@
   return ret;
 }
 
-absl::optional<LUID> LookupPrivilege(const std::wstring& name) {
+std::optional<LUID> LookupPrivilege(const std::wstring& name) {
   LUID luid;
   if (!::LookupPrivilegeValue(nullptr, name.c_str(), &luid)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return luid;
 }
@@ -149,7 +149,7 @@
   std::vector<LUID_AND_ATTRIBUTES> ret;
   ret.reserve(privs.size());
   for (const std::wstring& priv : privs) {
-    absl::optional<LUID> luid = LookupPrivilege(priv);
+    std::optional<LUID> luid = LookupPrivilege(priv);
     if (!luid) {
       return {};
     }
@@ -177,14 +177,14 @@
                                  sizeof(value));
 }
 
-absl::optional<DWORD> AdjustPrivilege(const ScopedHandle& token,
-                                      const std::wstring& priv,
-                                      DWORD attributes) {
+std::optional<DWORD> AdjustPrivilege(const ScopedHandle& token,
+                                     const std::wstring& priv,
+                                     DWORD attributes) {
   TOKEN_PRIVILEGES token_privs = {};
   token_privs.PrivilegeCount = 1;
-  absl::optional<LUID> luid = LookupPrivilege(priv);
+  std::optional<LUID> luid = LookupPrivilege(priv);
   if (!luid) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   token_privs.Privileges[0].Luid = *luid;
   token_privs.Privileges[0].Attributes = attributes;
@@ -193,10 +193,10 @@
   DWORD out_length = 0;
   if (!::AdjustTokenPrivileges(token.get(), FALSE, &token_privs,
                                sizeof(out_privs), &out_privs, &out_length)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   if (::GetLastError() == ERROR_NOT_ALL_ASSIGNED) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   if (out_privs.PrivilegeCount == 1) {
     return out_privs.Privileges[0].Attributes;
@@ -245,78 +245,77 @@
 AccessToken::Privilege::Privilege(CHROME_LUID luid, DWORD attributes)
     : luid_(luid), attributes_(attributes) {}
 
-absl::optional<AccessToken> AccessToken::FromToken(HANDLE token,
-                                                   ACCESS_MASK desired_access) {
+std::optional<AccessToken> AccessToken::FromToken(HANDLE token,
+                                                  ACCESS_MASK desired_access) {
   HANDLE new_token;
   if (!::DuplicateHandle(::GetCurrentProcess(), token, ::GetCurrentProcess(),
                          &new_token, TOKEN_QUERY | desired_access, FALSE, 0)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return AccessToken(new_token);
 }
 
-absl::optional<AccessToken> AccessToken::FromToken(ScopedHandle&& token) {
+std::optional<AccessToken> AccessToken::FromToken(ScopedHandle&& token) {
   if (!token.is_valid()) {
     ::SetLastError(ERROR_INVALID_HANDLE);
-    return absl::nullopt;
+    return std::nullopt;
   }
   if (!GetTokenInfoFixed<TOKEN_STATISTICS>(token.get(), TokenStatistics)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return AccessToken(token.release());
 }
 
-absl::optional<AccessToken> AccessToken::FromProcess(
+std::optional<AccessToken> AccessToken::FromProcess(
     HANDLE process,
     bool impersonation,
     ACCESS_MASK desired_access) {
   HANDLE token = nullptr;
   if (impersonation) {
     if (!::OpenProcessToken(process, TOKEN_DUPLICATE, &token))
-      return absl::nullopt;
+      return std::nullopt;
     ScopedHandle primary_token(token);
     token = DuplicateToken(primary_token.get(), desired_access,
                            SecurityIdentification, TokenImpersonation);
     if (!token) {
-      return absl::nullopt;
+      return std::nullopt;
     }
   } else {
     if (!::OpenProcessToken(process, TOKEN_QUERY | desired_access, &token))
-      return absl::nullopt;
+      return std::nullopt;
   }
   return AccessToken(token);
 }
 
-absl::optional<AccessToken> AccessToken::FromCurrentProcess(
+std::optional<AccessToken> AccessToken::FromCurrentProcess(
     bool impersonation,
     ACCESS_MASK desired_access) {
   return FromProcess(::GetCurrentProcess(), impersonation, desired_access);
 }
 
-absl::optional<AccessToken> AccessToken::FromThread(
-    HANDLE thread,
-    bool open_as_self,
-    ACCESS_MASK desired_access) {
+std::optional<AccessToken> AccessToken::FromThread(HANDLE thread,
+                                                   bool open_as_self,
+                                                   ACCESS_MASK desired_access) {
   HANDLE token;
   if (!::OpenThreadToken(thread, TOKEN_QUERY | desired_access, open_as_self,
                          &token))
-    return absl::nullopt;
+    return std::nullopt;
   return AccessToken(token);
 }
 
-absl::optional<AccessToken> AccessToken::FromCurrentThread(
+std::optional<AccessToken> AccessToken::FromCurrentThread(
     bool open_as_self,
     ACCESS_MASK desired_access) {
   return FromThread(::GetCurrentThread(), open_as_self, desired_access);
 }
 
-absl::optional<AccessToken> AccessToken::FromEffective(
+std::optional<AccessToken> AccessToken::FromEffective(
     ACCESS_MASK desired_access) {
-  absl::optional<AccessToken> token = FromCurrentThread(true, desired_access);
+  std::optional<AccessToken> token = FromCurrentThread(true, desired_access);
   if (token)
     return token;
   if (::GetLastError() != ERROR_NO_TOKEN)
-    return absl::nullopt;
+    return std::nullopt;
   return FromCurrentProcess(false, desired_access);
 }
 
@@ -329,37 +328,37 @@
 }
 
 AccessToken::Group AccessToken::UserGroup() const {
-  absl::optional<std::vector<char>> buffer =
+  std::optional<std::vector<char>> buffer =
       GetTokenInfo(token_.get(), TokenUser);
   SID_AND_ATTRIBUTES& user = GetType<TOKEN_USER>(buffer)->User;
   return {UnwrapSid(Sid::FromPSID(user.Sid)), user.Attributes};
 }
 
 Sid AccessToken::Owner() const {
-  absl::optional<std::vector<char>> buffer =
+  std::optional<std::vector<char>> buffer =
       GetTokenInfo(token_.get(), TokenOwner);
   return UnwrapSid(Sid::FromPSID(GetType<TOKEN_OWNER>(buffer)->Owner));
 }
 
 Sid AccessToken::PrimaryGroup() const {
-  absl::optional<std::vector<char>> buffer =
+  std::optional<std::vector<char>> buffer =
       GetTokenInfo(token_.get(), TokenPrimaryGroup);
   return UnwrapSid(
       Sid::FromPSID(GetType<TOKEN_PRIMARY_GROUP>(buffer)->PrimaryGroup));
 }
 
-absl::optional<Sid> AccessToken::LogonId() const {
+std::optional<Sid> AccessToken::LogonId() const {
   std::vector<AccessToken::Group> groups =
       GetGroupsFromToken(token_.get(), TokenLogonSid);
   for (const AccessToken::Group& group : groups) {
     if (group.IsLogonId())
       return group.GetSid().Clone();
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 DWORD AccessToken::IntegrityLevel() const {
-  absl::optional<std::vector<char>> buffer =
+  std::optional<std::vector<char>> buffer =
       GetTokenInfo(token_.get(), TokenIntegrityLevel);
   if (!buffer)
     return MAXDWORD;
@@ -370,7 +369,7 @@
 }
 
 bool AccessToken::SetIntegrityLevel(DWORD integrity_level) {
-  absl::optional<base::win::Sid> sid = Sid::FromIntegrityLevel(integrity_level);
+  std::optional<base::win::Sid> sid = Sid::FromIntegrityLevel(integrity_level);
   if (!sid) {
     ::SetLastError(ERROR_INVALID_SID);
     return false;
@@ -383,7 +382,7 @@
 }
 
 DWORD AccessToken::SessionId() const {
-  absl::optional<DWORD> value =
+  std::optional<DWORD> value =
       GetTokenInfoFixed<DWORD>(token_.get(), TokenSessionId);
   if (!value)
     return MAXDWORD;
@@ -403,23 +402,23 @@
 }
 
 bool AccessToken::IsAppContainer() const {
-  absl::optional<DWORD> value =
+  std::optional<DWORD> value =
       GetTokenInfoFixed<DWORD>(token_.get(), TokenIsAppContainer);
   if (!value)
     return false;
   return !!*value;
 }
 
-absl::optional<Sid> AccessToken::AppContainerSid() const {
-  absl::optional<std::vector<char>> buffer =
+std::optional<Sid> AccessToken::AppContainerSid() const {
+  std::optional<std::vector<char>> buffer =
       GetTokenInfo(token_.get(), TokenAppContainerSid);
   if (!buffer)
-    return absl::nullopt;
+    return std::nullopt;
 
   TOKEN_APPCONTAINER_INFORMATION* info =
       GetType<TOKEN_APPCONTAINER_INFORMATION>(buffer);
   if (!info->TokenAppContainer)
-    return absl::nullopt;
+    return std::nullopt;
   return Sid::FromPSID(info->TokenAppContainer);
 }
 
@@ -427,19 +426,19 @@
   return GetGroupsFromToken(token_.get(), TokenCapabilities);
 }
 
-absl::optional<AccessToken> AccessToken::LinkedToken() const {
-  absl::optional<TOKEN_LINKED_TOKEN> value =
+std::optional<AccessToken> AccessToken::LinkedToken() const {
+  std::optional<TOKEN_LINKED_TOKEN> value =
       GetTokenInfoFixed<TOKEN_LINKED_TOKEN>(token_.get(), TokenLinkedToken);
   if (!value)
-    return absl::nullopt;
+    return std::nullopt;
   return AccessToken(value->LinkedToken);
 }
 
-absl::optional<AccessControlList> AccessToken::DefaultDacl() const {
-  absl::optional<std::vector<char>> dacl_buffer =
+std::optional<AccessControlList> AccessToken::DefaultDacl() const {
+  std::optional<std::vector<char>> dacl_buffer =
       GetTokenInfo(token_.get(), TokenDefaultDacl);
   if (!dacl_buffer)
-    return absl::nullopt;
+    return std::nullopt;
   TOKEN_DEFAULT_DACL* dacl_ptr = GetType<TOKEN_DEFAULT_DACL>(dacl_buffer);
   return AccessControlList::FromPACL(dacl_ptr->DefaultDacl);
 }
@@ -459,7 +458,7 @@
 }
 
 std::vector<AccessToken::Privilege> AccessToken::Privileges() const {
-  absl::optional<std::vector<char>> privileges =
+  std::optional<std::vector<char>> privileges =
       GetTokenInfo(token_.get(), TokenPrivileges);
   if (!privileges)
     return {};
@@ -474,7 +473,7 @@
 }
 
 bool AccessToken::IsElevated() const {
-  absl::optional<TOKEN_ELEVATION> value =
+  std::optional<TOKEN_ELEVATION> value =
       GetTokenInfoFixed<TOKEN_ELEVATION>(token_.get(), TokenElevation);
   if (!value)
     return false;
@@ -509,17 +508,17 @@
       GetTokenStatistics(token_.get()).ImpersonationLevel);
 }
 
-absl::optional<AccessToken> AccessToken::DuplicatePrimary(
+std::optional<AccessToken> AccessToken::DuplicatePrimary(
     ACCESS_MASK desired_access) const {
   HANDLE token = DuplicateToken(token_.get(), desired_access, SecurityAnonymous,
                                 TokenPrimary);
   if (!token) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return AccessToken{token};
 }
 
-absl::optional<AccessToken> AccessToken::DuplicateImpersonation(
+std::optional<AccessToken> AccessToken::DuplicateImpersonation(
     SecurityImpersonationLevel impersonation_level,
     ACCESS_MASK desired_access) const {
   HANDLE token = DuplicateToken(
@@ -527,12 +526,12 @@
       static_cast<SECURITY_IMPERSONATION_LEVEL>(impersonation_level),
       TokenImpersonation);
   if (!token) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return AccessToken(token);
 }
 
-absl::optional<AccessToken> AccessToken::CreateRestricted(
+std::optional<AccessToken> AccessToken::CreateRestricted(
     DWORD flags,
     const std::vector<Sid>& sids_to_disable,
     const std::vector<std::wstring>& privileges_to_delete,
@@ -545,7 +544,7 @@
   std::vector<LUID_AND_ATTRIBUTES> privileges_to_delete_buf =
       ConvertPrivileges(privileges_to_delete, 0);
   if (privileges_to_delete_buf.size() != privileges_to_delete.size()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   HANDLE token;
@@ -556,14 +555,14 @@
           GetPointer(privileges_to_delete_buf),
           checked_cast<DWORD>(sids_to_restrict_buf.size()),
           GetPointer(sids_to_restrict_buf), &token)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   ScopedHandle token_handle(token);
   return FromToken(token_handle.get(), desired_access);
 }
 
-absl::optional<AccessToken> AccessToken::CreateAppContainer(
+std::optional<AccessToken> AccessToken::CreateAppContainer(
     const Sid& appcontainer_sid,
     const std::vector<Sid>& capabilities,
     ACCESS_MASK desired_access) const {
@@ -572,7 +571,7 @@
           ::GetModuleHandle(L"kernelbase.dll"), "CreateAppContainerToken"));
   if (!CreateAppContainerToken) {
     ::SetLastError(ERROR_PROC_NOT_FOUND);
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   std::vector<SID_AND_ATTRIBUTES> capabilities_buf =
@@ -585,19 +584,19 @@
 
   HANDLE token = nullptr;
   if (!CreateAppContainerToken(token_.get(), &security_capabilities, &token)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   ScopedHandle token_handle(token);
   return FromToken(token_handle.get(), desired_access);
 }
 
-absl::optional<bool> AccessToken::SetPrivilege(const std::wstring& name,
-                                               bool enable) {
-  absl::optional<DWORD> attrs =
+std::optional<bool> AccessToken::SetPrivilege(const std::wstring& name,
+                                              bool enable) {
+  std::optional<DWORD> attrs =
       AdjustPrivilege(token_, name.c_str(), enable ? SE_PRIVILEGE_ENABLED : 0);
   if (!attrs) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return !!(*attrs & SE_PRIVILEGE_ENABLED);
 }
@@ -608,7 +607,7 @@
 }
 
 bool AccessToken::RemoveAllPrivileges() {
-  absl::optional<std::vector<char>> privileges_buffer =
+  std::optional<std::vector<char>> privileges_buffer =
       GetTokenInfo(token_.get(), TokenPrivileges);
   if (!privileges_buffer ||
       (privileges_buffer->size() < sizeof(TOKEN_PRIVILEGES))) {
diff --git a/base/win/access_token.h b/base/win/access_token.h
index a6026ee..77747ab 100644
--- a/base/win/access_token.h
+++ b/base/win/access_token.h
@@ -6,6 +6,7 @@
 #define BASE_WIN_ACCESS_TOKEN_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -14,7 +15,6 @@
 #include "base/win/scoped_handle.h"
 #include "base/win/sid.h"
 #include "base/win/windows_types.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base::win {
 
@@ -80,14 +80,14 @@
   // the original can be closed.
   // |desired_access| specifies additional access for the token handle,
   // TOKEN_QUERY will always be requested.
-  static absl::optional<AccessToken> FromToken(HANDLE token,
-                                               ACCESS_MASK desired_access = 0);
+  static std::optional<AccessToken> FromToken(HANDLE token,
+                                              ACCESS_MASK desired_access = 0);
 
   // Creates an AccessToken object from an existing token handle.
   // |token| the token handle. The AccessToken object will take ownership of
   // this handle without duplicating it. It must have been opened with at least
   // TOKEN_QUERY access to succeed.
-  static absl::optional<AccessToken> FromToken(ScopedHandle&& token);
+  static std::optional<AccessToken> FromToken(ScopedHandle&& token);
 
   // Creates an AccessToken object from a process handle.
   // |process| the process handle. The handle needs to have
@@ -99,10 +99,9 @@
   // required.
   // |desired_access| specifies additional access for the token handle,
   // TOKEN_QUERY will always be requested.
-  static absl::optional<AccessToken> FromProcess(
-      HANDLE process,
-      bool impersonation = false,
-      ACCESS_MASK desired_access = 0);
+  static std::optional<AccessToken> FromProcess(HANDLE process,
+                                                bool impersonation = false,
+                                                ACCESS_MASK desired_access = 0);
 
   // Creates an AccessToken object for the current process.
   // |impersonation| if true then the process token will be duplicated to an
@@ -111,7 +110,7 @@
   // required.
   // |desired_access| specifies additional access for the token handle,
   // TOKEN_QUERY will always be requested.
-  static absl::optional<AccessToken> FromCurrentProcess(
+  static std::optional<AccessToken> FromCurrentProcess(
       bool impersonation = false,
       ACCESS_MASK desired_access = 0);
 
@@ -126,9 +125,9 @@
   // Win32 last error code will be ERROR_NO_TOKEN.
   // |desired_access| specifies additional access for the token handle,
   // TOKEN_QUERY will always be requested.
-  static absl::optional<AccessToken> FromThread(HANDLE thread,
-                                                bool open_as_self = true,
-                                                ACCESS_MASK desired_access = 0);
+  static std::optional<AccessToken> FromThread(HANDLE thread,
+                                               bool open_as_self = true,
+                                               ACCESS_MASK desired_access = 0);
 
   // Creates an AccessToken object from the current thread. The thread must be
   // impersonating a token for this to succeed.
@@ -138,7 +137,7 @@
   // Win32 last error code will be ERROR_NO_TOKEN.
   // |desired_access| specifies additional access for the token handle,
   // TOKEN_QUERY will always be requested.
-  static absl::optional<AccessToken> FromCurrentThread(
+  static std::optional<AccessToken> FromCurrentThread(
       bool open_as_self = true,
       ACCESS_MASK desired_access = 0);
 
@@ -147,7 +146,7 @@
   // otherwise it'll open the process token.
   // |desired_access| specifies additional access for the token handle,
   // TOKEN_QUERY will always be requested.
-  static absl::optional<AccessToken> FromEffective(
+  static std::optional<AccessToken> FromEffective(
       ACCESS_MASK desired_access = 0);
 
   AccessToken(const AccessToken&) = delete;
@@ -172,7 +171,7 @@
   // Get the token logon SID. Returns an empty value if the token doesn't have
   // a logon SID. If the logon SID doesn't exist then the Win32 last error code
   // will be ERROR_NOT_FOUND.
-  absl::optional<Sid> LogonId() const;
+  std::optional<Sid> LogonId() const;
 
   // Get the token's integrity level. Returns MAXDWORD if the token doesn't
   // have an integrity level.
@@ -201,17 +200,17 @@
 
   // Get the token's appcontainer SID. If not an appcontainer token this will
   // return an empty value.
-  absl::optional<Sid> AppContainerSid() const;
+  std::optional<Sid> AppContainerSid() const;
 
   // The token's capabilities. If not an appcontainer token this will return an
   // empty vector.
   std::vector<Group> Capabilities() const;
 
   // Get the UAC linked token.
-  absl::optional<AccessToken> LinkedToken() const;
+  std::optional<AccessToken> LinkedToken() const;
 
   // Get the default DACL for the token. Returns an empty value on error.
-  absl::optional<AccessControlList> DefaultDacl() const;
+  std::optional<AccessControlList> DefaultDacl() const;
 
   // Set the default DACL of the token. Token needs to have been opened with
   // TOKEN_ADJUST_DEFAULT access.
@@ -260,7 +259,7 @@
   // TOKEN_QUERY will always be requested.
   // The original token must have TOKEN_DUPLICATE access to successfully
   // duplicate the token.
-  absl::optional<AccessToken> DuplicatePrimary(
+  std::optional<AccessToken> DuplicatePrimary(
       ACCESS_MASK desired_access = 0) const;
 
   // Duplicate the token to a new impersonation token.
@@ -269,7 +268,7 @@
   // TOKEN_QUERY will always be requested.
   // The original token must have TOKEN_DUPLICATE access to successfully
   // duplicate the token.
-  absl::optional<AccessToken> DuplicateImpersonation(
+  std::optional<AccessToken> DuplicateImpersonation(
       SecurityImpersonationLevel impersonation_level =
           SecurityImpersonationLevel::kImpersonation,
       ACCESS_MASK desired_access = 0) const;
@@ -282,7 +281,7 @@
   // |sids_to_restrict| is the list of SIDs to add as restricted SIDs.
   // |desired_access| specifies additional access for the token handle.
   // The token needs to be opened with TOKEN_DUPLICATE access.
-  absl::optional<AccessToken> CreateRestricted(
+  std::optional<AccessToken> CreateRestricted(
       DWORD flags,
       const std::vector<Sid>& sids_to_disable,
       const std::vector<std::wstring>& privileges_to_delete,
@@ -294,7 +293,7 @@
   // |capabilities| the list of AppContainer capabilities.
   // |desired_access| specifies additional access for the token handle.
   // The token needs to be opened with TOKEN_DUPLICATE access.
-  absl::optional<AccessToken> CreateAppContainer(
+  std::optional<AccessToken> CreateAppContainer(
       const Sid& appcontainer_sid,
       const std::vector<Sid>& capabilities,
       ACCESS_MASK desired_access = 0) const;
@@ -304,7 +303,7 @@
   // |enable| specify whether to enable or disable the privilege.
   // Returns the previous enable state of the privilege, or nullopt if failed.
   // The token must be opened with TOKEN_ADJUST_PRIVILEGES access.
-  absl::optional<bool> SetPrivilege(const std::wstring& name, bool enable);
+  std::optional<bool> SetPrivilege(const std::wstring& name, bool enable);
 
   // Remove a privilege permanently from the token.
   // |name| the name of the privilege to remove.
diff --git a/base/win/access_token_unittest.cc b/base/win/access_token_unittest.cc
index e5314083..790e89ee 100644
--- a/base/win/access_token_unittest.cc
+++ b/base/win/access_token_unittest.cc
@@ -9,6 +9,7 @@
 #include <algorithm>
 #include <cstdint>
 #include <map>
+#include <optional>
 #include <utility>
 
 #include "base/win/atl.h"
@@ -16,7 +17,6 @@
 #include "base/win/security_util.h"
 #include "base/win/windows_version.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base::win {
 
@@ -49,7 +49,7 @@
   ASSERT_EQ(sids.GetCount(), attrs.GetCount());
   std::map<std::wstring, DWORD> group_map;
   for (const AccessToken::Group& group : groups) {
-    absl::optional<std::wstring> sddl = group.GetSid().ToSddlString();
+    std::optional<std::wstring> sddl = group.GetSid().ToSddlString();
     ASSERT_TRUE(sddl);
     group_map.insert({*sddl, group.GetAttributes()});
   }
@@ -102,7 +102,7 @@
   TOKEN_MANDATORY_LABEL* label =
       reinterpret_cast<TOKEN_MANDATORY_LABEL*>(buffer);
   ASSERT_TRUE(label->Label.Sid);
-  absl::optional<Sid> il_sid = Sid::FromIntegrityLevel(token.IntegrityLevel());
+  std::optional<Sid> il_sid = Sid::FromIntegrityLevel(token.IntegrityLevel());
   ASSERT_TRUE(il_sid);
   EXPECT_TRUE(il_sid->Equal(label->Label.Sid));
 }
@@ -137,7 +137,7 @@
   CAcl::CAceTypeArray types;
   CAcl::CAceFlagArray flags;
   atl_dacl.GetAclEntries(&sids, &access, &types, &flags);
-  absl::optional<AccessControlList> dacl = token.DefaultDacl();
+  std::optional<AccessControlList> dacl = token.DefaultDacl();
   ASSERT_TRUE(dacl);
   ACL* acl_ptr = dacl->get();
   ASSERT_TRUE(acl_ptr);
@@ -158,7 +158,7 @@
       ACCESS_ALLOWED_ACE* ace =
           reinterpret_cast<ACCESS_ALLOWED_ACE*>(ace_header);
       EXPECT_EQ(ace->Mask, access[index]);
-      absl::optional<Sid> sid = Sid::FromPSID(&ace->SidStart);
+      std::optional<Sid> sid = Sid::FromPSID(&ace->SidStart);
       ASSERT_TRUE(sid);
       EXPECT_TRUE(EqualSid(*sid, sids[index]));
     }
@@ -189,7 +189,7 @@
   ATL::CSid primary_group;
   ASSERT_TRUE(atl_token.GetPrimaryGroup(&primary_group));
   EXPECT_TRUE(EqualSid(token.PrimaryGroup(), primary_group));
-  absl::optional<Sid> logon_sid = token.LogonId();
+  std::optional<Sid> logon_sid = token.LogonId();
   if (!logon_sid) {
     EXPECT_EQ(DWORD{ERROR_NOT_FOUND}, ::GetLastError());
   }
@@ -221,7 +221,7 @@
   ASSERT_TRUE(atl_token.GetPrivileges(&atl_privs));
   ComparePrivileges(token.Privileges(), atl_privs);
   CompareDefaultDacl(token, atl_token);
-  absl::optional<AccessToken> linked_token = token.LinkedToken();
+  std::optional<AccessToken> linked_token = token.LinkedToken();
   ATL::CAccessToken atl_linked_token;
   bool result = GetLinkedToken(atl_token, &atl_linked_token);
   if (!linked_token) {
@@ -253,7 +253,7 @@
   return token.CreateImpersonationToken(imp_token, impersonation_level);
 }
 
-void CheckTokenError(const absl::optional<AccessToken>& token,
+void CheckTokenError(const std::optional<AccessToken>& token,
                      DWORD expected_error) {
   DWORD error = ::GetLastError();
   EXPECT_FALSE(token);
@@ -325,7 +325,7 @@
       cap_count > 0 ? cap_groups->Groups : nullptr, 0, nullptr);
   ASSERT_EQ(0, status);
   ScopedHandle scoped_tmp_token(tmp_token);
-  absl::optional<AccessToken> ac_token =
+  std::optional<AccessToken> ac_token =
       AccessToken::FromToken(scoped_tmp_token.get());
   ASSERT_TRUE(ac_token);
   EXPECT_TRUE(ac_token->IsAppContainer());
@@ -334,7 +334,7 @@
 }
 
 ACCESS_MASK GetTokenAccess(const AccessToken& token) {
-  absl::optional<ACCESS_MASK> granted_access = GetGrantedAccess(token.get());
+  std::optional<ACCESS_MASK> granted_access = GetGrantedAccess(token.get());
   CHECK(granted_access);
   return *granted_access;
 }
@@ -361,13 +361,13 @@
   ATL::CAccessToken atl_token;
   ASSERT_TRUE(atl_token.GetProcessToken(TOKEN_QUERY));
 
-  absl::optional<AccessToken> token =
+  std::optional<AccessToken> token =
       AccessToken::FromToken(atl_token.GetHandle());
   ASSERT_TRUE(token);
   CompareTokens(*token, atl_token);
   EXPECT_EQ(GetTokenAccess(*token), DWORD{TOKEN_QUERY});
 
-  absl::optional<AccessToken> all_access_token =
+  std::optional<AccessToken> all_access_token =
       AccessToken::FromToken(atl_token.GetHandle(), kTokenAllNoQuery);
   ASSERT_TRUE(all_access_token);
   EXPECT_EQ(GetTokenAccess(*all_access_token), DWORD{TOKEN_ALL_ACCESS});
@@ -383,7 +383,7 @@
   // Check that we duplicate with the correct access rights.
   ASSERT_TRUE(atl_token.GetProcessToken(TOKEN_QUERY_SOURCE));
   ASSERT_FALSE(atl_token.GetTokenId(&temp_luid));
-  absl::optional<AccessToken> token2 =
+  std::optional<AccessToken> token2 =
       AccessToken::FromToken(atl_token.GetHandle());
   ASSERT_TRUE(token2);
   EXPECT_TRUE(CompareLuid(token2->Id(), luid));
@@ -420,20 +420,20 @@
   process.Set(::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE,
                             ::GetCurrentProcessId()));
   ASSERT_TRUE(process.is_valid());
-  absl::optional<AccessToken> token = AccessToken::FromProcess(process.get());
+  std::optional<AccessToken> token = AccessToken::FromProcess(process.get());
   ASSERT_TRUE(token);
   EXPECT_EQ(GetTokenAccess(*token), DWORD{TOKEN_QUERY});
   ASSERT_FALSE(token->IsImpersonation());
   ATL::CAccessToken atl_token;
   ASSERT_TRUE(atl_token.GetProcessToken(TOKEN_QUERY, process.get()));
   CompareTokens(*token, atl_token);
-  absl::optional<AccessToken> imp_token =
+  std::optional<AccessToken> imp_token =
       AccessToken::FromProcess(process.get(), true);
   ASSERT_TRUE(imp_token);
   ASSERT_TRUE(imp_token->IsImpersonation());
   ASSERT_TRUE(imp_token->IsIdentification());
 
-  absl::optional<AccessToken> all_access_token =
+  std::optional<AccessToken> all_access_token =
       AccessToken::FromProcess(process.get(), false, kTokenAllNoQuery);
   ASSERT_TRUE(all_access_token);
   EXPECT_EQ(GetTokenAccess(*all_access_token), DWORD{TOKEN_ALL_ACCESS});
@@ -445,18 +445,18 @@
 }
 
 TEST(AccessTokenTest, FromCurrentProcess) {
-  absl::optional<AccessToken> token = AccessToken::FromCurrentProcess();
+  std::optional<AccessToken> token = AccessToken::FromCurrentProcess();
   ASSERT_TRUE(token);
   ASSERT_FALSE(token->IsImpersonation());
   ATL::CAccessToken atl_token;
   ASSERT_TRUE(atl_token.GetProcessToken(TOKEN_QUERY));
   CompareTokens(*token, atl_token);
-  absl::optional<AccessToken> imp_token = AccessToken::FromCurrentProcess(true);
+  std::optional<AccessToken> imp_token = AccessToken::FromCurrentProcess(true);
   ASSERT_TRUE(imp_token);
   ASSERT_TRUE(imp_token->IsImpersonation());
   ASSERT_TRUE(imp_token->IsIdentification());
 
-  absl::optional<AccessToken> all_access_token =
+  std::optional<AccessToken> all_access_token =
       AccessToken::FromCurrentProcess(false, kTokenAllNoQuery);
   ASSERT_TRUE(all_access_token);
   EXPECT_EQ(GetTokenAccess(*all_access_token), DWORD{TOKEN_ALL_ACCESS});
@@ -485,8 +485,8 @@
   thread.Set(::OpenThread(THREAD_QUERY_LIMITED_INFORMATION, FALSE,
                           ::GetCurrentThreadId()));
   ASSERT_TRUE(thread.is_valid());
-  absl::optional<AccessToken> imp_token = AccessToken::FromThread(thread.get());
-  absl::optional<AccessToken> all_access_token =
+  std::optional<AccessToken> imp_token = AccessToken::FromThread(thread.get());
+  std::optional<AccessToken> all_access_token =
       AccessToken::FromThread(thread.get(), true, kTokenAllNoQuery);
   atl_imp_token.Revert();
   ASSERT_TRUE(imp_token);
@@ -503,7 +503,7 @@
   CAutoRevertImpersonation scoped_imp2(&atl_id_token);
   CheckTokenError(AccessToken::FromThread(thread.get(), false),
                   ERROR_BAD_IMPERSONATION_LEVEL);
-  absl::optional<AccessToken> id_token =
+  std::optional<AccessToken> id_token =
       AccessToken::FromThread(thread.get(), true);
   atl_id_token.Revert();
   ASSERT_TRUE(id_token);
@@ -522,8 +522,8 @@
   ASSERT_TRUE(atl_imp_token.Impersonate());
   CAutoRevertImpersonation scoped_imp(&atl_imp_token);
 
-  absl::optional<AccessToken> imp_token = AccessToken::FromCurrentThread();
-  absl::optional<AccessToken> all_access_token =
+  std::optional<AccessToken> imp_token = AccessToken::FromCurrentThread();
+  std::optional<AccessToken> all_access_token =
       AccessToken::FromCurrentThread(true, kTokenAllNoQuery);
   atl_imp_token.Revert();
   ASSERT_TRUE(imp_token);
@@ -540,7 +540,7 @@
   ATL::CAutoRevertImpersonation scoped_imp2(&atl_id_token);
   CheckTokenError(AccessToken::FromCurrentThread(false),
                   ERROR_BAD_IMPERSONATION_LEVEL);
-  absl::optional<AccessToken> id_token = AccessToken::FromCurrentThread(true);
+  std::optional<AccessToken> id_token = AccessToken::FromCurrentThread(true);
   atl_id_token.Revert();
   ASSERT_TRUE(id_token);
   EXPECT_TRUE(id_token->IsIdentification());
@@ -550,9 +550,9 @@
 TEST(AccessTokenTest, FromEffective) {
   // Make sure we have no impersonation token before starting.
   ::RevertToSelf();
-  absl::optional<base::win::AccessToken> primary_token =
+  std::optional<base::win::AccessToken> primary_token =
       AccessToken::FromEffective();
-  absl::optional<base::win::AccessToken> all_access_token =
+  std::optional<base::win::AccessToken> all_access_token =
       AccessToken::FromEffective(kTokenAllNoQuery);
   ASSERT_TRUE(primary_token);
   EXPECT_EQ(GetTokenAccess(*primary_token), DWORD{TOKEN_QUERY});
@@ -569,7 +569,7 @@
   ASSERT_TRUE(atl_imp_token.Impersonate());
   CAutoRevertImpersonation scoped_imp(&atl_imp_token);
 
-  absl::optional<AccessToken> imp_token = AccessToken::FromEffective();
+  std::optional<AccessToken> imp_token = AccessToken::FromEffective();
   all_access_token = AccessToken::FromEffective(kTokenAllNoQuery);
   atl_imp_token.Revert();
   ASSERT_TRUE(imp_token);
@@ -604,16 +604,16 @@
 }
 
 TEST(AccessTokenTest, IsMember) {
-  absl::optional<AccessToken> token = AccessToken::FromCurrentProcess();
+  std::optional<AccessToken> token = AccessToken::FromCurrentProcess();
   ASSERT_TRUE(token);
   ASSERT_FALSE(token->IsImpersonation());
   CheckError(token->IsMember(WellKnownSid::kWorld),
              ERROR_NO_IMPERSONATION_TOKEN);
-  absl::optional<Sid> sid = Sid::FromSddlString(L"S-1-1-2-3-4-5-6-7-8");
+  std::optional<Sid> sid = Sid::FromSddlString(L"S-1-1-2-3-4-5-6-7-8");
   ASSERT_TRUE(sid);
   CheckError(token->IsMember(*sid), ERROR_NO_IMPERSONATION_TOKEN);
 
-  absl::optional<AccessToken> imp_token = AccessToken::FromCurrentProcess(true);
+  std::optional<AccessToken> imp_token = AccessToken::FromCurrentProcess(true);
   EXPECT_TRUE(imp_token->IsMember(WellKnownSid::kWorld));
   EXPECT_FALSE(imp_token->IsMember(WellKnownSid::kNull));
   EXPECT_TRUE(imp_token->IsMember(imp_token->User()));
@@ -631,7 +631,7 @@
   ATL::CAccessToken atl_restricted;
   ASSERT_TRUE(atl_token.CreateRestrictedToken(&atl_restricted, disable_groups,
                                               restrict_groups));
-  absl::optional<AccessToken> restricted =
+  std::optional<AccessToken> restricted =
       AccessToken::FromToken(atl_restricted.GetHandle());
   ASSERT_TRUE(restricted);
   EXPECT_TRUE(restricted->IsRestricted());
@@ -647,10 +647,10 @@
 }
 
 TEST(AccessTokenTest, AppContainer) {
-  absl::optional<Sid> package_sid =
+  std::optional<Sid> package_sid =
       Sid::FromSddlString(L"S-1-15-2-1-2-3-4-5-6-7");
   ASSERT_TRUE(package_sid);
-  absl::optional<std::vector<Sid>> caps =
+  std::optional<std::vector<Sid>> caps =
       Sid::FromKnownCapabilityVector({WellKnownCapability::kInternetClient,
                                       WellKnownCapability::kDocumentsLibrary});
   ASSERT_TRUE(caps);
@@ -665,12 +665,12 @@
   bool result = atl_anon_token.GetThreadToken(TOKEN_ALL_ACCESS);
   ::RevertToSelf();
   ASSERT_TRUE(result);
-  absl::optional<AccessToken> anon_token =
+  std::optional<AccessToken> anon_token =
       AccessToken::FromToken(atl_anon_token.GetHandle());
   ASSERT_TRUE(anon_token);
   CompareTokens(*anon_token, atl_anon_token);
   EXPECT_EQ(Sid(WellKnownSid::kAnonymous), anon_token->User());
-  absl::optional<Sid> logon_sid = anon_token->LogonId();
+  std::optional<Sid> logon_sid = anon_token->LogonId();
   EXPECT_FALSE(anon_token->LogonId());
   EXPECT_EQ(DWORD{ERROR_NOT_FOUND}, ::GetLastError());
 }
@@ -680,14 +680,14 @@
   ASSERT_TRUE(atl_token.GetProcessToken(MAXIMUM_ALLOWED));
   ATL::CAccessToken atl_dup_token;
   ASSERT_TRUE(atl_token.CreatePrimaryToken(&atl_dup_token));
-  absl::optional<AccessToken> read_only_token =
+  std::optional<AccessToken> read_only_token =
       AccessToken::FromToken(atl_dup_token.GetHandle());
   AccessControlList default_dacl;
   Sid world_sid(WellKnownSid::kWorld);
   ASSERT_TRUE(default_dacl.SetEntry(world_sid, SecurityAccessMode::kGrant,
                                     GENERIC_ALL, 0));
   EXPECT_FALSE(read_only_token->SetDefaultDacl(default_dacl));
-  absl::optional<AccessToken> token =
+  std::optional<AccessToken> token =
       AccessToken::FromToken(atl_dup_token.GetHandle(), TOKEN_ADJUST_DEFAULT);
   EXPECT_TRUE(token->SetDefaultDacl(default_dacl));
 
@@ -710,11 +710,11 @@
   ASSERT_TRUE(atl_token.GetProcessToken(MAXIMUM_ALLOWED));
   ATL::CAccessToken atl_dup_token;
   ASSERT_TRUE(atl_token.CreatePrimaryToken(&atl_dup_token));
-  absl::optional<AccessToken> read_only_token =
+  std::optional<AccessToken> read_only_token =
       AccessToken::FromToken(atl_dup_token.GetHandle());
   EXPECT_FALSE(
       read_only_token->SetIntegrityLevel(SECURITY_MANDATORY_UNTRUSTED_RID));
-  absl::optional<AccessToken> token =
+  std::optional<AccessToken> token =
       AccessToken::FromToken(atl_dup_token.GetHandle(), TOKEN_ADJUST_DEFAULT);
   EXPECT_TRUE(token->SetIntegrityLevel(SECURITY_MANDATORY_LOW_RID));
   EXPECT_EQ(token->IntegrityLevel(), DWORD{SECURITY_MANDATORY_LOW_RID});
@@ -723,12 +723,12 @@
 }
 
 TEST(AccessTokenTest, DuplicatePrimary) {
-  absl::optional<AccessToken> token = AccessToken::FromCurrentProcess();
+  std::optional<AccessToken> token = AccessToken::FromCurrentProcess();
   ASSERT_TRUE(token);
   CheckTokenError(token->DuplicatePrimary(), ERROR_ACCESS_DENIED);
   token = AccessToken::FromCurrentProcess(false, TOKEN_DUPLICATE);
   ASSERT_TRUE(token);
-  absl::optional<AccessToken> dup_token = token->DuplicatePrimary();
+  std::optional<AccessToken> dup_token = token->DuplicatePrimary();
   ASSERT_TRUE(dup_token);
   EXPECT_FALSE(dup_token->IsImpersonation());
   EXPECT_EQ(GetTokenAccess(*dup_token), DWORD{TOKEN_QUERY});
@@ -739,14 +739,14 @@
 }
 
 TEST(AccessTokenTest, DuplicateImpersonation) {
-  absl::optional<AccessToken> token = AccessToken::FromCurrentProcess();
+  std::optional<AccessToken> token = AccessToken::FromCurrentProcess();
   ASSERT_TRUE(token);
   CheckTokenError(
       token->DuplicateImpersonation(SecurityImpersonationLevel::kImpersonation),
       ERROR_ACCESS_DENIED);
   token = AccessToken::FromCurrentProcess(false, TOKEN_DUPLICATE);
   ASSERT_TRUE(token);
-  absl::optional<AccessToken> dup_token = token->DuplicateImpersonation();
+  std::optional<AccessToken> dup_token = token->DuplicateImpersonation();
   ASSERT_TRUE(dup_token);
   EXPECT_TRUE(dup_token->IsImpersonation());
   EXPECT_FALSE(dup_token->IsIdentification());
@@ -790,12 +790,12 @@
 }
 
 TEST(AccessTokenTest, CreateRestricted) {
-  absl::optional<AccessToken> primary_token = AccessToken::FromCurrentProcess();
+  std::optional<AccessToken> primary_token = AccessToken::FromCurrentProcess();
   ASSERT_TRUE(primary_token);
   CheckTokenError(primary_token->CreateRestricted(0, {}, {}, {}),
                   ERROR_ACCESS_DENIED);
   primary_token = AccessToken::FromCurrentProcess(false, TOKEN_ALL_ACCESS);
-  absl::optional<AccessToken> restricted_token =
+  std::optional<AccessToken> restricted_token =
       primary_token->CreateRestricted(DISABLE_MAX_PRIVILEGE, {}, {}, {});
   ASSERT_TRUE(restricted_token);
   EXPECT_FALSE(restricted_token->IsRestricted());
@@ -838,15 +838,15 @@
 }
 
 TEST(AccessTokenTest, CreateAppContainer) {
-  absl::optional<AccessToken> primary_token = AccessToken::FromCurrentProcess();
+  std::optional<AccessToken> primary_token = AccessToken::FromCurrentProcess();
   ASSERT_TRUE(primary_token);
-  absl::optional<Sid> package_sid =
+  std::optional<Sid> package_sid =
       Sid::FromSddlString(L"S-1-15-2-1-2-3-4-5-6-7");
   ASSERT_TRUE(package_sid);
   CheckTokenError(primary_token->CreateAppContainer(*package_sid, {}),
                   ERROR_ACCESS_DENIED);
   primary_token = AccessToken::FromCurrentProcess(false, TOKEN_ALL_ACCESS);
-  absl::optional<AccessToken> ac_token =
+  std::optional<AccessToken> ac_token =
       primary_token->CreateAppContainer(*package_sid, {});
   ASSERT_TRUE(ac_token);
   EXPECT_EQ(GetTokenAccess(*ac_token), DWORD{TOKEN_QUERY});
@@ -859,7 +859,7 @@
   EXPECT_TRUE(ac_token->IsAppContainer());
   EXPECT_EQ(GetTokenAccess(*ac_token), DWORD{TOKEN_ALL_ACCESS});
 
-  absl::optional<std::vector<Sid>> caps =
+  std::optional<std::vector<Sid>> caps =
       Sid::FromKnownCapabilityVector({WellKnownCapability::kInternetClient,
                                       WellKnownCapability::kDocumentsLibrary});
   ASSERT_TRUE(caps);
@@ -877,14 +877,14 @@
 }
 
 TEST(AccessTokenTest, SetPrivilege) {
-  absl::optional<AccessToken> token = AccessToken::FromCurrentProcess(true);
+  std::optional<AccessToken> token = AccessToken::FromCurrentProcess(true);
   EXPECT_FALSE(token->SetPrivilege(SE_CHANGE_NOTIFY_NAME, false));
   token = AccessToken::FromCurrentProcess(true, TOKEN_ADJUST_PRIVILEGES);
   EXPECT_FALSE(token->SetPrivilege(L"ThisIsNotValid", false));
-  absl::optional<bool> original_state =
+  std::optional<bool> original_state =
       token->SetPrivilege(SE_CHANGE_NOTIFY_NAME, false);
   EXPECT_TRUE(original_state);
-  absl::optional<bool> curr_state =
+  std::optional<bool> curr_state =
       token->SetPrivilege(SE_CHANGE_NOTIFY_NAME, true);
   EXPECT_TRUE(curr_state);
   EXPECT_FALSE(*curr_state);
@@ -895,7 +895,7 @@
 }
 
 TEST(AccessTokenTest, RemovePrivilege) {
-  absl::optional<AccessToken> token = AccessToken::FromCurrentProcess(true);
+  std::optional<AccessToken> token = AccessToken::FromCurrentProcess(true);
   EXPECT_FALSE(token->RemovePrivilege(SE_CHANGE_NOTIFY_NAME));
   token = AccessToken::FromCurrentProcess(true, TOKEN_ADJUST_PRIVILEGES);
   EXPECT_FALSE(token->RemovePrivilege(L"ThisIsNotValid"));
@@ -904,7 +904,7 @@
 }
 
 TEST(AccessTokenTest, RemoveAllPrivileges) {
-  absl::optional<AccessToken> token = AccessToken::FromCurrentProcess(true);
+  std::optional<AccessToken> token = AccessToken::FromCurrentProcess(true);
   EXPECT_FALSE(token->RemoveAllPrivileges());
   token = AccessToken::FromCurrentProcess(true, TOKEN_ADJUST_PRIVILEGES);
   EXPECT_TRUE(token->RemoveAllPrivileges());
@@ -913,7 +913,7 @@
 }
 
 TEST(AccessTokenTest, CheckRelease) {
-  absl::optional<AccessToken> token = AccessToken::FromCurrentProcess();
+  std::optional<AccessToken> token = AccessToken::FromCurrentProcess();
   ASSERT_TRUE(token);
   EXPECT_TRUE(token->is_valid());
   ScopedHandle handle(token->release());
diff --git a/base/win/com_init_balancer.h b/base/win/com_init_balancer.h
index 1f61b3a..571f2d7 100644
--- a/base/win/com_init_balancer.h
+++ b/base/win/com_init_balancer.h
@@ -9,10 +9,11 @@
 #include <winnt.h>
 #include <wrl/implements.h>
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/threading/thread_checker.h"
 #include "base/win/windows_types.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace win {
@@ -62,7 +63,7 @@
   // call made to CoInitialize or CoUninitialize.
   DWORD reference_count_ = 0;
 
-  absl::optional<ULARGE_INTEGER> spy_cookie_;
+  std::optional<ULARGE_INTEGER> spy_cookie_;
   THREAD_CHECKER(thread_checker_);
 };
 
diff --git a/base/win/registry.cc b/base/win/registry.cc
index 7b9dcb9..29694506 100644
--- a/base/win/registry.cc
+++ b/base/win/registry.cc
@@ -493,11 +493,11 @@
   return unexpected(result);
 }
 
-absl::optional<LONG> RegKey::DeleteIfLink() {
+std::optional<LONG> RegKey::DeleteIfLink() {
   if (auto is_link = IsLink(); !is_link.has_value()) {
     return is_link.error();  // Failed to determine if a link.
   } else if (is_link.value() == false) {
-    return absl::nullopt;  // Not a link.
+    return std::nullopt;  // Not a link.
   }
 
   const NTSTATUS delete_result = ::NtDeleteKey(key_);
diff --git a/base/win/registry.h b/base/win/registry.h
index ea7be2a..91fdd5e 100644
--- a/base/win/registry.h
+++ b/base/win/registry.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -16,7 +17,6 @@
 #include "base/types/expected.h"
 #include "base/types/strong_alias.h"
 #include "base/win/windows_types.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace win {
@@ -171,7 +171,7 @@
   // was a link and was deleted, a Windows error code if checking the key or
   // deleting it failed, or `nullopt` if the key exists and is not a symbolic
   // link.
-  absl::optional<LONG> DeleteIfLink();
+  std::optional<LONG> DeleteIfLink();
 
   // Recursively deletes a key and all of its subkeys.
   static LONG RegDelRecurse(HKEY root_key, const wchar_t* name, REGSAM access);
diff --git a/base/win/scoped_safearray.h b/base/win/scoped_safearray.h
index f9c332f..cd9e604 100644
--- a/base/win/scoped_safearray.h
+++ b/base/win/scoped_safearray.h
@@ -7,11 +7,12 @@
 
 #include <objbase.h>
 
+#include <optional>
+
 #include "base/base_export.h"
 #include "base/check_op.h"
 #include "base/memory/raw_ptr_exclusion.h"
 #include "base/win/variant_conversions.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace win {
@@ -140,21 +141,21 @@
   // Creates a LockScope for accessing the contents of a
   // single-dimensional SAFEARRAYs.
   template <VARTYPE ElementVartype>
-  absl::optional<LockScope<ElementVartype>> CreateLockScope() const {
+  std::optional<LockScope<ElementVartype>> CreateLockScope() const {
     if (!safearray_ || SafeArrayGetDim(safearray_) != 1)
-      return absl::nullopt;
+      return std::nullopt;
 
     VARTYPE vartype;
     HRESULT hr = SafeArrayGetVartype(safearray_, &vartype);
     if (FAILED(hr) ||
         !internal::VariantConverter<ElementVartype>::IsConvertibleTo(vartype)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     typename LockScope<ElementVartype>::pointer array = nullptr;
     hr = SafeArrayAccessData(safearray_, reinterpret_cast<void**>(&array));
     if (FAILED(hr))
-      return absl::nullopt;
+      return std::nullopt;
 
     const size_t array_size = GetCount();
     return LockScope<ElementVartype>(safearray_, vartype, array, array_size);
diff --git a/base/win/scoped_safearray_unittest.cc b/base/win/scoped_safearray_unittest.cc
index 73f2ca0..e1de0d93 100644
--- a/base/win/scoped_safearray_unittest.cc
+++ b/base/win/scoped_safearray_unittest.cc
@@ -7,12 +7,12 @@
 #include <stddef.h>
 
 #include <array>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "base/test/gtest_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace win {
@@ -170,7 +170,7 @@
 
 TEST(ScopedSafearrayTest, ScopedSafearrayInitialLockScope) {
   ScopedSafearray scoped_safe_array;
-  absl::optional<ScopedSafearray::LockScope<VT_I4>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<VT_I4>> lock_scope =
       scoped_safe_array.CreateLockScope<VT_I4>();
   EXPECT_FALSE(lock_scope.has_value());
 }
@@ -179,7 +179,7 @@
   ScopedSafearray scoped_safe_array;
   PopulateScopedSafearrayOfInts(scoped_safe_array);
 
-  absl::optional<ScopedSafearray::LockScope<VT_I4>> first =
+  std::optional<ScopedSafearray::LockScope<VT_I4>> first =
       scoped_safe_array.CreateLockScope<VT_I4>();
   ASSERT_TRUE(first.has_value());
   EXPECT_EQ(first->Type(), VT_I4);
@@ -196,7 +196,7 @@
   ScopedSafearray scoped_safe_array;
   PopulateScopedSafearrayOfInts(scoped_safe_array);
 
-  absl::optional<ScopedSafearray::LockScope<VT_I4>> first =
+  std::optional<ScopedSafearray::LockScope<VT_I4>> first =
       scoped_safe_array.CreateLockScope<VT_I4>();
   ASSERT_TRUE(first.has_value());
   EXPECT_EQ(first->Type(), VT_I4);
@@ -219,13 +219,13 @@
   PopulateScopedSafearrayOfInts(scoped_safe_array);
 
   {
-    absl::optional<ScopedSafearray::LockScope<VT_BSTR>> invalid_lock_scope =
+    std::optional<ScopedSafearray::LockScope<VT_BSTR>> invalid_lock_scope =
         scoped_safe_array.CreateLockScope<VT_BSTR>();
     EXPECT_FALSE(invalid_lock_scope.has_value());
   }
 
   {
-    absl::optional<ScopedSafearray::LockScope<VT_UI4>> invalid_lock_scope =
+    std::optional<ScopedSafearray::LockScope<VT_UI4>> invalid_lock_scope =
         scoped_safe_array.CreateLockScope<VT_UI4>();
     EXPECT_FALSE(invalid_lock_scope.has_value());
   }
@@ -235,7 +235,7 @@
   ScopedSafearray scoped_safe_array;
   PopulateScopedSafearrayOfInts(scoped_safe_array);
 
-  absl::optional<ScopedSafearray::LockScope<VT_I4>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<VT_I4>> lock_scope =
       scoped_safe_array.CreateLockScope<VT_I4>();
   ASSERT_TRUE(lock_scope.has_value());
   EXPECT_EQ(lock_scope->Type(), VT_I4);
@@ -250,7 +250,7 @@
   ScopedSafearray scoped_safe_array;
   PopulateScopedSafearrayOfInts(scoped_safe_array);
 
-  absl::optional<ScopedSafearray::LockScope<VT_I4>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<VT_I4>> lock_scope =
       scoped_safe_array.CreateLockScope<VT_I4>();
 
   std::vector<int> unpacked_vector(lock_scope->begin(), lock_scope->end());
diff --git a/base/win/security_descriptor.cc b/base/win/security_descriptor.cc
index 0daf5db8..d68b1b0 100644
--- a/base/win/security_descriptor.cc
+++ b/base/win/security_descriptor.cc
@@ -24,19 +24,19 @@
 
 namespace {
 template <typename T>
-absl::optional<T> CloneValue(const absl::optional<T>& value) {
+std::optional<T> CloneValue(const std::optional<T>& value) {
   if (!value)
-    return absl::nullopt;
+    return std::nullopt;
   return value->Clone();
 }
 
-PSID UnwrapSid(const absl::optional<Sid>& sid) {
+PSID UnwrapSid(const std::optional<Sid>& sid) {
   if (!sid)
     return nullptr;
   return sid->GetPSID();
 }
 
-PACL UnwrapAcl(const absl::optional<AccessControlList>& acl) {
+PACL UnwrapAcl(const std::optional<AccessControlList>& acl) {
   if (!acl)
     return nullptr;
   return acl->get();
@@ -111,7 +111,7 @@
 }
 
 template <typename T>
-absl::optional<SecurityDescriptor> GetSecurityDescriptor(
+std::optional<SecurityDescriptor> GetSecurityDescriptor(
     T object,
     SecurityObjectType object_type,
     SECURITY_INFORMATION security_info,
@@ -130,7 +130,7 @@
   if (error != ERROR_SUCCESS) {
     ::SetLastError(error);
     DPLOG(ERROR) << "Failed getting security descriptor for object.";
-    return absl::nullopt;
+    return std::nullopt;
   }
   auto sd_ptr = TakeLocalAlloc(sd);
   return SecurityDescriptor::FromPointer(sd_ptr.get());
@@ -177,25 +177,25 @@
   return true;
 }
 
-absl::optional<Sid> GetSecurityDescriptorSid(
+std::optional<Sid> GetSecurityDescriptorSid(
     PSECURITY_DESCRIPTOR sd,
     BOOL(WINAPI* get_sid)(PSECURITY_DESCRIPTOR, PSID*, LPBOOL)) {
   PSID sid;
   BOOL defaulted;
   if (!get_sid(sd, &sid, &defaulted) || !sid) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return Sid::FromPSID(sid);
 }
 
-absl::optional<AccessControlList> GetSecurityDescriptorAcl(
+std::optional<AccessControlList> GetSecurityDescriptorAcl(
     PSECURITY_DESCRIPTOR sd,
     BOOL(WINAPI* get_acl)(PSECURITY_DESCRIPTOR, LPBOOL, PACL*, LPBOOL)) {
   PACL acl;
   BOOL present;
   BOOL defaulted;
   if (!get_acl(sd, &present, &acl, &defaulted) || !present) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return AccessControlList::FromPACL(acl);
 }
@@ -207,17 +207,17 @@
 SecurityDescriptor::SelfRelative::SelfRelative(std::vector<uint8_t>&& sd)
     : sd_(sd) {}
 
-absl::optional<SecurityDescriptor> SecurityDescriptor::FromPointer(
+std::optional<SecurityDescriptor> SecurityDescriptor::FromPointer(
     PSECURITY_DESCRIPTOR sd) {
   if (!sd || !::IsValidSecurityDescriptor(sd)) {
     ::SetLastError(ERROR_INVALID_SECURITY_DESCR);
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   SECURITY_DESCRIPTOR_CONTROL control;
   DWORD revision;
   if (!::GetSecurityDescriptorControl(sd, &control, &revision)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return SecurityDescriptor{
@@ -229,13 +229,13 @@
       !!(control & SE_SACL_PROTECTED)};
 }
 
-absl::optional<SecurityDescriptor> SecurityDescriptor::FromFile(
+std::optional<SecurityDescriptor> SecurityDescriptor::FromFile(
     const base::FilePath& path,
     SECURITY_INFORMATION security_info) {
   return FromName(path.value(), SecurityObjectType::kFile, security_info);
 }
 
-absl::optional<SecurityDescriptor> SecurityDescriptor::FromName(
+std::optional<SecurityDescriptor> SecurityDescriptor::FromName(
     const std::wstring& name,
     SecurityObjectType object_type,
     SECURITY_INFORMATION security_info) {
@@ -243,7 +243,7 @@
                                ::GetNamedSecurityInfo);
 }
 
-absl::optional<SecurityDescriptor> SecurityDescriptor::FromHandle(
+std::optional<SecurityDescriptor> SecurityDescriptor::FromHandle(
     HANDLE handle,
     SecurityObjectType object_type,
     SECURITY_INFORMATION security_info) {
@@ -251,12 +251,12 @@
                                        ::GetSecurityInfo);
 }
 
-absl::optional<SecurityDescriptor> SecurityDescriptor::FromSddl(
+std::optional<SecurityDescriptor> SecurityDescriptor::FromSddl(
     const std::wstring& sddl) {
   PSECURITY_DESCRIPTOR sd;
   if (!::ConvertStringSecurityDescriptorToSecurityDescriptor(
           sddl.c_str(), SDDL_REVISION_1, &sd, nullptr)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   auto sd_ptr = TakeLocalAlloc(sd);
   return FromPointer(sd_ptr.get());
@@ -289,14 +289,14 @@
                                        security_info, ::SetSecurityInfo);
 }
 
-absl::optional<std::wstring> SecurityDescriptor::ToSddl(
+std::optional<std::wstring> SecurityDescriptor::ToSddl(
     SECURITY_INFORMATION security_info) const {
   SECURITY_DESCRIPTOR sd = {};
   ToAbsolute(sd);
   LPWSTR sddl;
   if (!::ConvertSecurityDescriptorToStringSecurityDescriptor(
           &sd, SDDL_REVISION_1, security_info, &sddl, nullptr)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   auto sddl_ptr = TakeLocalAlloc(sddl);
   return sddl_ptr.get();
@@ -324,7 +324,7 @@
   DCHECK(::IsValidSecurityDescriptor(&sd));
 }
 
-absl::optional<SecurityDescriptor::SelfRelative>
+std::optional<SecurityDescriptor::SelfRelative>
 SecurityDescriptor::ToSelfRelative() const {
   SECURITY_DESCRIPTOR sd = {};
   ToAbsolute(sd);
@@ -335,12 +335,12 @@
   }
 
   if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   buffer.resize(size);
   if (!::MakeSelfRelativeSD(&sd, buffer.data(), &size)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return SelfRelative(std::move(buffer));
 }
@@ -354,9 +354,8 @@
 bool SecurityDescriptor::SetMandatoryLabel(DWORD integrity_level,
                                            DWORD inheritance,
                                            DWORD mandatory_policy) {
-  absl::optional<AccessControlList> sacl =
-      AccessControlList::FromMandatoryLabel(integrity_level, inheritance,
-                                            mandatory_policy);
+  std::optional<AccessControlList> sacl = AccessControlList::FromMandatoryLabel(
+      integrity_level, inheritance, mandatory_policy);
   if (!sacl) {
     return false;
   }
@@ -389,7 +388,7 @@
   return SetDaclEntry(Sid(known_sid), mode, access_mask, inheritance);
 }
 
-absl::optional<AccessCheckResult> SecurityDescriptor::AccessCheck(
+std::optional<AccessCheckResult> SecurityDescriptor::AccessCheck(
     const AccessToken& token,
     ACCESS_MASK desired_access,
     const GENERIC_MAPPING& generic_mapping) {
@@ -408,28 +407,28 @@
   if (!::AccessCheck(&sd, token.get(), desired_access, &local_mapping,
                      reinterpret_cast<PPRIVILEGE_SET>(priv_set.data()),
                      &priv_set_length, &granted_access, &access_status)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return AccessCheckResult{granted_access, !!access_status};
 }
 
-absl::optional<AccessCheckResult> SecurityDescriptor::AccessCheck(
+std::optional<AccessCheckResult> SecurityDescriptor::AccessCheck(
     const AccessToken& token,
     ACCESS_MASK desired_access,
     SecurityObjectType object_type) {
   if (object_type == SecurityObjectType::kKernel) {
     ::SetLastError(ERROR_INVALID_PARAMETER);
-    return absl::nullopt;
+    return std::nullopt;
   }
   return AccessCheck(token, desired_access,
                      GetGenericMappingForType(object_type));
 }
 
-SecurityDescriptor::SecurityDescriptor(absl::optional<Sid>&& owner,
-                                       absl::optional<Sid>&& group,
-                                       absl::optional<AccessControlList>&& dacl,
+SecurityDescriptor::SecurityDescriptor(std::optional<Sid>&& owner,
+                                       std::optional<Sid>&& group,
+                                       std::optional<AccessControlList>&& dacl,
                                        bool dacl_protected,
-                                       absl::optional<AccessControlList>&& sacl,
+                                       std::optional<AccessControlList>&& sacl,
                                        bool sacl_protected) {
   owner_.swap(owner);
   group_.swap(group);
diff --git a/base/win/security_descriptor.h b/base/win/security_descriptor.h
index 27003698..489c537 100644
--- a/base/win/security_descriptor.h
+++ b/base/win/security_descriptor.h
@@ -7,6 +7,7 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -16,7 +17,6 @@
 #include "base/win/access_token.h"
 #include "base/win/sid.h"
 #include "base/win/windows_types.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base::win {
 
@@ -62,13 +62,13 @@
   // Create from an existing security descriptor pointer.
   // |security_descriptor| The pointer to a self-relative or absolute security
   // descriptor. This method will copy all security descriptor data.
-  static absl::optional<SecurityDescriptor> FromPointer(
+  static std::optional<SecurityDescriptor> FromPointer(
       PSECURITY_DESCRIPTOR security_descriptor);
 
   // Create from the security descriptor of an existing file.
   // |path| the path to the file.
   // |security_info| indicates what parts to read.
-  static absl::optional<SecurityDescriptor> FromFile(
+  static std::optional<SecurityDescriptor> FromFile(
       const base::FilePath& path,
       SECURITY_INFORMATION security_info);
 
@@ -77,7 +77,7 @@
   // GetNamedSecurityInfo API.
   // |object_type| specifies the type of object the name represents.
   // |security_info| indicates what parts to read.
-  static absl::optional<SecurityDescriptor> FromName(
+  static std::optional<SecurityDescriptor> FromName(
       const std::wstring& name,
       SecurityObjectType object_type,
       SECURITY_INFORMATION security_info);
@@ -86,14 +86,14 @@
   // |handle| the object handle. It must have READ_CONTROL access.
   // |object_type| specifies the type of object the handle represents.
   // |security_info| indicates what parts to read.
-  static absl::optional<SecurityDescriptor> FromHandle(
+  static std::optional<SecurityDescriptor> FromHandle(
       HANDLE handle,
       SecurityObjectType object_type,
       SECURITY_INFORMATION security_info);
 
   // Create from a string representation of a security descriptor.
   // |sddl| the security descriptor in SDDL format.
-  static absl::optional<SecurityDescriptor> FromSddl(const std::wstring& sddl);
+  static std::optional<SecurityDescriptor> FromSddl(const std::wstring& sddl);
 
   SecurityDescriptor();
   SecurityDescriptor(const SecurityDescriptor&) = delete;
@@ -128,7 +128,7 @@
 
   // Convert the SecurityDescriptor to an SDDL string.
   // |security_info| determines what parts are included in the string.
-  absl::optional<std::wstring> ToSddl(SECURITY_INFORMATION security_info) const;
+  std::optional<std::wstring> ToSddl(SECURITY_INFORMATION security_info) const;
 
   // Create an reference to the absolute security descriptor of this instance.
   // |sd| the SECURITY_DESCRIPTOR structure to populate. This is is only valid
@@ -136,7 +136,7 @@
   void ToAbsolute(SECURITY_DESCRIPTOR& sd) const;
 
   // Create a self-relative security descriptor in a single buffer.
-  absl::optional<SelfRelative> ToSelfRelative() const;
+  std::optional<SelfRelative> ToSelfRelative() const;
 
   // Make a clone of the current security descriptor object.
   SecurityDescriptor Clone() const;
@@ -188,7 +188,7 @@
   // |generic_mapping| the generic mapping for the access check.
   // Returns the result of the access check. If an empty result is returned the
   // call to the AccessCheck API failed.
-  absl::optional<AccessCheckResult> AccessCheck(
+  std::optional<AccessCheckResult> AccessCheck(
       const AccessToken& token,
       ACCESS_MASK desired_access,
       const GENERIC_MAPPING& generic_mapping);
@@ -203,24 +203,24 @@
   // configured GENERIC_MAPPING.
   // Returns the result of the access check. If an empty result is returned the
   // call to the AccessCheck API failed.
-  absl::optional<AccessCheckResult> AccessCheck(const AccessToken& token,
-                                                ACCESS_MASK desired_access,
-                                                SecurityObjectType object_type);
+  std::optional<AccessCheckResult> AccessCheck(const AccessToken& token,
+                                               ACCESS_MASK desired_access,
+                                               SecurityObjectType object_type);
 
   // Get, set and clear owner member.
-  const absl::optional<Sid>& owner() const { return owner_; }
+  const std::optional<Sid>& owner() const { return owner_; }
   void set_owner(const Sid& owner) { owner_ = owner.Clone(); }
-  void clear_owner() { owner_ = absl::nullopt; }
+  void clear_owner() { owner_ = std::nullopt; }
 
   // Get, set and clear group member.
-  const absl::optional<Sid>& group() const { return group_; }
+  const std::optional<Sid>& group() const { return group_; }
   void set_group(const Sid& group) { group_ = group.Clone(); }
-  void clear_group() { group_ = absl::nullopt; }
+  void clear_group() { group_ = std::nullopt; }
 
   // Get, set and clear dacl member.
-  const absl::optional<AccessControlList>& dacl() const { return dacl_; }
+  const std::optional<AccessControlList>& dacl() const { return dacl_; }
   void set_dacl(const AccessControlList& dacl) { dacl_ = dacl.Clone(); }
-  void clear_dacl() { dacl_ = absl::nullopt; }
+  void clear_dacl() { dacl_ = std::nullopt; }
 
   // Get and set dacl_protected member.
   bool dacl_protected() const { return dacl_protected_; }
@@ -229,9 +229,9 @@
   }
 
   // Get, set and clear sacl member.
-  const absl::optional<AccessControlList>& sacl() const { return sacl_; }
+  const std::optional<AccessControlList>& sacl() const { return sacl_; }
   void set_sacl(const AccessControlList& sacl) { sacl_ = sacl.Clone(); }
-  void clear_sacl() { sacl_ = absl::nullopt; }
+  void clear_sacl() { sacl_ = std::nullopt; }
 
   // Get and set sacl_protected member.
   bool sacl_protected() const { return sacl_protected_; }
@@ -240,18 +240,18 @@
   }
 
  private:
-  SecurityDescriptor(absl::optional<Sid>&& owner,
-                     absl::optional<Sid>&& group,
-                     absl::optional<AccessControlList>&& dacl,
+  SecurityDescriptor(std::optional<Sid>&& owner,
+                     std::optional<Sid>&& group,
+                     std::optional<AccessControlList>&& dacl,
                      bool dacl_protected,
-                     absl::optional<AccessControlList>&& sacl,
+                     std::optional<AccessControlList>&& sacl,
                      bool sacl_protected);
 
-  absl::optional<Sid> owner_;
-  absl::optional<Sid> group_;
-  absl::optional<AccessControlList> dacl_;
+  std::optional<Sid> owner_;
+  std::optional<Sid> group_;
+  std::optional<AccessControlList> dacl_;
   bool dacl_protected_ = false;
-  absl::optional<AccessControlList> sacl_;
+  std::optional<AccessControlList> sacl_;
   bool sacl_protected_ = false;
 };
 
diff --git a/base/win/security_descriptor_unittest.cc b/base/win/security_descriptor_unittest.cc
index f1003ea5..197c4dd 100644
--- a/base/win/security_descriptor_unittest.cc
+++ b/base/win/security_descriptor_unittest.cc
@@ -8,6 +8,7 @@
 #include <sddl.h>
 #include <windows.h>
 
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -19,7 +20,6 @@
 #include "base/win/scoped_handle.h"
 #include "base/win/scoped_localalloc.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base::win {
 
@@ -103,25 +103,25 @@
   return base::win::ScopedHandle(dup_handle);
 }
 
-void ExpectSid(const absl::optional<Sid>& sid, WellKnownSid known_sid) {
+void ExpectSid(const std::optional<Sid>& sid, WellKnownSid known_sid) {
   ASSERT_TRUE(sid);
   EXPECT_EQ(*sid, Sid(known_sid));
 }
 
-void AccessCheckError(const absl::optional<AccessCheckResult>& result,
+void AccessCheckError(const std::optional<AccessCheckResult>& result,
                       DWORD expected) {
   EXPECT_FALSE(result.has_value());
   EXPECT_EQ(::GetLastError(), expected);
 }
 
-void AccessCheckStatusError(const absl::optional<AccessCheckResult>& result,
+void AccessCheckStatusError(const std::optional<AccessCheckResult>& result,
                             DWORD expected) {
   ASSERT_TRUE(result.has_value());
   EXPECT_FALSE(result->access_status);
   EXPECT_EQ(::GetLastError(), expected);
 }
 
-void AccessCheckTest(const absl::optional<AccessCheckResult>& result,
+void AccessCheckTest(const std::optional<AccessCheckResult>& result,
                      ACCESS_MASK expected_access) {
   ASSERT_TRUE(result.has_value());
   EXPECT_TRUE(result->access_status);
@@ -134,10 +134,10 @@
                      ACCESS_MASK generic_write,
                      ACCESS_MASK generic_execute,
                      ACCESS_MASK generic_all) {
-  absl::optional<SecurityDescriptor> sd =
+  std::optional<SecurityDescriptor> sd =
       SecurityDescriptor::FromSddl(kAccessCheckSd);
   ASSERT_TRUE(sd);
-  absl::optional<AccessToken> token = AccessToken::FromCurrentProcess(
+  std::optional<AccessToken> token = AccessToken::FromCurrentProcess(
       /*impersonation=*/true, TOKEN_ADJUST_DEFAULT);
   ASSERT_TRUE(token.has_value());
   AccessCheckTest(sd->AccessCheck(*token, GENERIC_READ, type), generic_read);
@@ -545,10 +545,10 @@
 }
 
 TEST(SecurityDescriptorTest, AccessCheck) {
-  absl::optional<SecurityDescriptor> sd =
+  std::optional<SecurityDescriptor> sd =
       SecurityDescriptor::FromSddl(kAccessCheckSd);
   ASSERT_TRUE(sd);
-  absl::optional<AccessToken> token = AccessToken::FromCurrentProcess();
+  std::optional<AccessToken> token = AccessToken::FromCurrentProcess();
   ASSERT_TRUE(token);
   AccessCheckError(sd->AccessCheck(*token, 1, SecurityObjectType::kFile),
                    ERROR_NO_IMPERSONATION_TOKEN);
diff --git a/base/win/security_util.cc b/base/win/security_util.cc
index a7c162ea..596da7bc 100644
--- a/base/win/security_util.cc
+++ b/base/win/security_util.cc
@@ -7,6 +7,8 @@
 #include <windows.h>
 #include <winternl.h>
 
+#include <optional>
+
 #include "base/check.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
@@ -14,7 +16,6 @@
 #include "base/win/access_control_list.h"
 #include "base/win/scoped_handle.h"
 #include "base/win/security_descriptor.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace win {
@@ -34,7 +35,7 @@
   base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                 base::BlockingType::MAY_BLOCK);
 
-  absl::optional<SecurityDescriptor> sd =
+  std::optional<SecurityDescriptor> sd =
       SecurityDescriptor::FromFile(path, DACL_SECURITY_INFORMATION);
   if (!sd) {
     return false;
@@ -101,11 +102,11 @@
   }
 }
 
-absl::optional<ACCESS_MASK> GetGrantedAccess(HANDLE handle) {
+std::optional<ACCESS_MASK> GetGrantedAccess(HANDLE handle) {
   PUBLIC_OBJECT_BASIC_INFORMATION basic_info = {};
   if (!NT_SUCCESS(::NtQueryObject(handle, ObjectBasicInformation, &basic_info,
                                   sizeof(basic_info), nullptr))) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return basic_info.GrantedAccess;
 }
diff --git a/base/win/security_util.h b/base/win/security_util.h
index 0de1262d..20eab85 100644
--- a/base/win/security_util.h
+++ b/base/win/security_util.h
@@ -5,12 +5,12 @@
 #ifndef BASE_WIN_SECURITY_UTIL_H_
 #define BASE_WIN_SECURITY_UTIL_H_
 
+#include <optional>
 #include <vector>
 
 #include "base/base_export.h"
 #include "base/win/sid.h"
 #include "base/win/windows_types.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -47,7 +47,7 @@
 
 // Gets the granted access for an open handle.
 // |handle| specifies any kernel object handle to query.
-BASE_EXPORT absl::optional<ACCESS_MASK> GetGrantedAccess(HANDLE handle);
+BASE_EXPORT std::optional<ACCESS_MASK> GetGrantedAccess(HANDLE handle);
 
 }  // namespace win
 }  // namespace base
diff --git a/base/win/sid.cc b/base/win/sid.cc
index 3323cc7c..ccaf033 100644
--- a/base/win/sid.cc
+++ b/base/win/sid.cc
@@ -209,19 +209,19 @@
   }
 }
 
-absl::optional<Sid> Sid::FromSddlString(const std::wstring& sddl_sid) {
+std::optional<Sid> Sid::FromSddlString(const std::wstring& sddl_sid) {
   PSID psid = nullptr;
   if (!::ConvertStringSidToSid(sddl_sid.c_str(), &psid)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   auto psid_alloc = TakeLocalAlloc(psid);
   return FromPSID(psid_alloc.get());
 }
 
-absl::optional<Sid> Sid::FromPSID(PSID sid) {
+std::optional<Sid> Sid::FromPSID(PSID sid) {
   DCHECK(sid);
   if (!sid || !::IsValidSid(sid))
-    return absl::nullopt;
+    return std::nullopt;
   return Sid(sid, ::GetLengthSid(sid));
 }
 
@@ -237,14 +237,14 @@
                             &integrity_level);
 }
 
-absl::optional<std::vector<Sid>> Sid::FromSddlStringVector(
+std::optional<std::vector<Sid>> Sid::FromSddlStringVector(
     const std::vector<std::wstring>& sddl_sids) {
   std::vector<Sid> converted_sids;
   converted_sids.reserve(sddl_sids.size());
   for (const std::wstring& sddl_sid : sddl_sids) {
-    absl::optional<Sid> sid = FromSddlString(sddl_sid);
+    std::optional<Sid> sid = FromSddlString(sddl_sid);
     if (!sid)
-      return absl::nullopt;
+      return std::nullopt;
     converted_sids.push_back(std::move(*sid));
   }
   return converted_sids;
@@ -285,10 +285,10 @@
   return const_cast<char*>(sid_.data());
 }
 
-absl::optional<std::wstring> Sid::ToSddlString() const {
+std::optional<std::wstring> Sid::ToSddlString() const {
   LPWSTR sid = nullptr;
   if (!::ConvertSidToStringSid(GetPSID(), &sid))
-    return absl::nullopt;
+    return std::nullopt;
   auto sid_ptr = TakeLocalAlloc(sid);
   return sid_ptr.get();
 }
diff --git a/base/win/sid.h b/base/win/sid.h
index 0396847..de255c17 100644
--- a/base/win/sid.h
+++ b/base/win/sid.h
@@ -5,12 +5,12 @@
 #ifndef BASE_WIN_SID_H_
 #define BASE_WIN_SID_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "base/base_export.h"
 #include "base/win/windows_types.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base::win {
 
@@ -75,10 +75,10 @@
   static Sid FromKnownSid(WellKnownSid type);
 
   // Create a Sid from a SDDL format string, such as S-1-1-0.
-  static absl::optional<Sid> FromSddlString(const std::wstring& sddl_sid);
+  static std::optional<Sid> FromSddlString(const std::wstring& sddl_sid);
 
   // Create a Sid from a PSID pointer.
-  static absl::optional<Sid> FromPSID(const PSID sid);
+  static std::optional<Sid> FromPSID(const PSID sid);
 
   // Generate a random SID value.
   static Sid GenerateRandomSid();
@@ -87,7 +87,7 @@
   static Sid FromIntegrityLevel(DWORD integrity_level);
 
   // Create a vector of SIDs from a vector of SDDL format strings.
-  static absl::optional<std::vector<Sid>> FromSddlStringVector(
+  static std::optional<std::vector<Sid>> FromSddlStringVector(
       const std::vector<std::wstring>& sddl_sids);
 
   // Create a vector of SIDs from a vector of capability names.
@@ -117,7 +117,7 @@
   PSID GetPSID() const;
 
   // Converts the SID to a SDDL format string.
-  absl::optional<std::wstring> ToSddlString() const;
+  std::optional<std::wstring> ToSddlString() const;
 
   // Make a clone of the current Sid object.
   Sid Clone() const;
diff --git a/base/win/sid_unittest.cc b/base/win/sid_unittest.cc
index 5391d67..620974f 100644
--- a/base/win/sid_unittest.cc
+++ b/base/win/sid_unittest.cc
@@ -12,6 +12,8 @@
 
 #include <sddl.h>
 
+#include <optional>
+
 #include "base/ranges/algorithm.h"
 #include "base/win/atl.h"
 #include "base/win/scoped_handle.h"
@@ -19,13 +21,12 @@
 #include "base/win/win_util.h"
 #include "build/branding_buildflags.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base::win {
 
 namespace {
 
-bool EqualSid(const absl::optional<Sid>& sid, const ATL::CSid& compare_sid) {
+bool EqualSid(const std::optional<Sid>& sid, const ATL::CSid& compare_sid) {
   if (!sid)
     return false;
   return sid->Equal(const_cast<SID*>(compare_sid.GetPSID()));
@@ -40,7 +41,7 @@
   return sid.Equal(sid_ptr.get());
 }
 
-bool EqualSid(const absl::optional<Sid>& sid, WELL_KNOWN_SID_TYPE known_sid) {
+bool EqualSid(const std::optional<Sid>& sid, WELL_KNOWN_SID_TYPE known_sid) {
   if (!sid)
     return false;
   char known_sid_buffer[SECURITY_MAX_SID_SIZE] = {};
@@ -51,7 +52,7 @@
   return sid->Equal(known_sid_buffer);
 }
 
-bool TestSidVector(absl::optional<std::vector<Sid>> sids,
+bool TestSidVector(std::optional<std::vector<Sid>> sids,
                    const std::vector<std::wstring>& sddl) {
   return sids && ranges::equal(*sids, sddl,
                                [](const Sid& sid, const std::wstring& sddl) {
@@ -134,13 +135,13 @@
   PSID sid_world_pointer = const_cast<SID*>(sid_world.GetPSID());
 
   // Check the PSID constructor.
-  absl::optional<Sid> sid_sid_star = Sid::FromPSID(sid_world_pointer);
+  std::optional<Sid> sid_sid_star = Sid::FromPSID(sid_world_pointer);
   ASSERT_TRUE(EqualSid(sid_sid_star, sid_world));
 
   char invalid_sid[16] = {};
   ASSERT_FALSE(Sid::FromPSID(invalid_sid));
 
-  absl::optional<Sid> sid_sddl = Sid::FromSddlString(L"S-1-1-0");
+  std::optional<Sid> sid_sddl = Sid::FromSddlString(L"S-1-1-0");
   ASSERT_TRUE(sid_sddl);
   ASSERT_TRUE(EqualSid(sid_sddl, sid_world));
 }
@@ -240,9 +241,9 @@
 }
 
 TEST(SidTest, SddlString) {
-  absl::optional<Sid> sid_sddl = Sid::FromSddlString(L"S-1-1-0");
+  std::optional<Sid> sid_sddl = Sid::FromSddlString(L"S-1-1-0");
   ASSERT_TRUE(sid_sddl);
-  absl::optional<std::wstring> sddl_str = sid_sddl->ToSddlString();
+  std::optional<std::wstring> sddl_str = sid_sddl->ToSddlString();
   ASSERT_TRUE(sddl_str);
   ASSERT_EQ(L"S-1-1-0", *sddl_str);
   ASSERT_FALSE(Sid::FromSddlString(L"X-1-1-0"));
diff --git a/base/win/variant_vector.cc b/base/win/variant_vector.cc
index db2365b..55ba46f 100644
--- a/base/win/variant_vector.cc
+++ b/base/win/variant_vector.cc
@@ -4,13 +4,14 @@
 
 #include "base/win/variant_vector.h"
 
+#include <optional>
+
 #include "base/check_op.h"
 #include "base/notreached.h"
 #include "base/numerics/checked_math.h"
 #include "base/process/memory.h"
 #include "base/win/scoped_safearray.h"
 #include "base/win/scoped_variant.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace win {
@@ -22,7 +23,7 @@
 int CompareAgainstSafearray(const std::vector<ScopedVariant>& vector,
                             const ScopedSafearray& safearray,
                             bool ignore_case) {
-  absl::optional<ScopedSafearray::LockScope<ElementVartype>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<ElementVartype>> lock_scope =
       safearray.CreateLockScope<ElementVartype>();
   // If we fail to create a lock scope, then arbitrarily treat |this| as
   // greater. This should only happen when the SAFEARRAY fails to be locked,
@@ -329,7 +330,7 @@
                                       (Size() * kElementSize));
   }
 
-  absl::optional<ScopedSafearray::LockScope<ElementVartype>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<ElementVartype>> lock_scope =
       scoped_safearray.CreateLockScope<ElementVartype>();
   DCHECK(lock_scope);
 
diff --git a/base/win/variant_vector_unittest.cc b/base/win/variant_vector_unittest.cc
index c1e13d46..301dca8 100644
--- a/base/win/variant_vector_unittest.cc
+++ b/base/win/variant_vector_unittest.cc
@@ -8,11 +8,12 @@
 #include <windows.foundation.h>
 #include <wrl/client.h>
 
+#include <optional>
+
 #include "base/test/gtest_util.h"
 #include "base/win/dispatch_stub.h"
 #include "base/win/scoped_safearray.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using base::win::test::DispatchStub;
 
@@ -626,7 +627,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 1U);
@@ -648,7 +649,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 1U);
@@ -670,7 +671,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 1U);
@@ -692,7 +693,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 1U);
@@ -714,7 +715,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 1U);
@@ -736,7 +737,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 1U);
@@ -758,7 +759,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 1U);
@@ -780,7 +781,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 1U);
@@ -802,7 +803,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 1U);
@@ -824,7 +825,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 1U);
@@ -846,7 +847,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 1U);
@@ -873,7 +874,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 1U);
@@ -896,7 +897,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 1U);
@@ -921,7 +922,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 1U);
@@ -946,7 +947,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 1U);
@@ -970,7 +971,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 3U);
@@ -996,7 +997,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 3U);
@@ -1022,7 +1023,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 3U);
@@ -1048,7 +1049,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 3U);
@@ -1074,7 +1075,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 3U);
@@ -1100,7 +1101,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 3U);
@@ -1126,7 +1127,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 3U);
@@ -1152,7 +1153,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 3U);
@@ -1178,7 +1179,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 3U);
@@ -1203,7 +1204,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 2U);
@@ -1227,7 +1228,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 2U);
@@ -1255,7 +1256,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 2U);
@@ -1280,7 +1281,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 2U);
@@ -1309,7 +1310,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 2U);
@@ -1338,7 +1339,7 @@
   EXPECT_EQ(variant.type(), VT_ARRAY | kVariantType);
 
   ScopedSafearray safearray(V_ARRAY(variant.ptr()));
-  absl::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
+  std::optional<ScopedSafearray::LockScope<kVariantType>> lock_scope =
       safearray.CreateLockScope<kVariantType>();
   ASSERT_TRUE(lock_scope.has_value());
   ASSERT_EQ(lock_scope->size(), 2U);
diff --git a/base/win/win_util.cc b/base/win/win_util.cc
index 25cc9b48..544d8275 100644
--- a/base/win/win_util.cc
+++ b/base/win/win_util.cc
@@ -7,19 +7,18 @@
 #include <aclapi.h>
 #include <cfgmgr32.h>
 #include <initguid.h>
-#include <lm.h>
-#include <powrprof.h>
-#include <shobjidl.h>  // Must be before propkey.
-
 #include <inspectable.h>
+#include <lm.h>
 #include <mdmregistration.h>
 #include <objbase.h>
+#include <powrprof.h>
 #include <propkey.h>
 #include <psapi.h>
 #include <roapi.h>
 #include <sddl.h>
 #include <setupapi.h>
 #include <shellscalingapi.h>
+#include <shobjidl.h>  // Must be before propkey.
 #include <signal.h>
 #include <stddef.h>
 #include <stdlib.h>
@@ -34,6 +33,7 @@
 
 #include <limits>
 #include <memory>
+#include <optional>
 #include <string_view>
 #include <utility>
 
@@ -61,7 +61,6 @@
 #include "base/win/shlwapi.h"
 #include "base/win/static_constants.h"
 #include "base/win/windows_version.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace win {
@@ -385,10 +384,10 @@
 static bool g_crash_on_process_detach = false;
 
 bool GetUserSidString(std::wstring* user_sid) {
-  absl::optional<AccessToken> token = AccessToken::FromCurrentProcess();
+  std::optional<AccessToken> token = AccessToken::FromCurrentProcess();
   if (!token)
     return false;
-  absl::optional<std::wstring> sid_string = token->User().ToSddlString();
+  std::optional<std::wstring> sid_string = token->User().ToSddlString();
   if (!sid_string)
     return false;
   *user_sid = *sid_string;
@@ -527,7 +526,7 @@
   // Once this is set, it shouldn't be overridden, and it should be the ultimate
   // return value, so that this method returns the same result whether or not
   // reason is NULL.
-  absl::optional<bool> ret;
+  std::optional<bool> ret;
 
   if (GetSystemMetrics(SM_MAXIMUMTOUCHES) == 0) {
     if (reason) {
diff --git a/base/win/winrt_foundation_helpers.h b/base/win/winrt_foundation_helpers.h
index 26def75..2f17e68 100644
--- a/base/win/winrt_foundation_helpers.h
+++ b/base/win/winrt_foundation_helpers.h
@@ -9,10 +9,10 @@
 #include <wrl/client.h>
 
 #include <algorithm>
+#include <optional>
 #include <vector>
 
 #include "base/check.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // This file provides helpers for WinRT types.
 
@@ -63,13 +63,13 @@
     Microsoft::WRL::ComPtr<std::remove_pointer_t<AbiType<TComplex>>>,
     AbiType<TComplex>>;
 
-// Similar to StorageType, but returns a absl::optional in case underlying Abi
+// Similar to StorageType, but returns a std::optional in case underlying Abi
 // type is not a pointer to IUnknown.
 template <typename TComplex>
 using OptionalStorageType = std::conditional_t<
     std::is_convertible_v<AbiType<TComplex>, IUnknown*>,
     Microsoft::WRL::ComPtr<std::remove_pointer_t<AbiType<TComplex>>>,
-    absl::optional<AbiType<TComplex>>>;
+    std::optional<AbiType<TComplex>>>;
 
 template <typename T>
 HRESULT CopyTo(const T& value, T* ptr) {
@@ -83,7 +83,7 @@
 }
 
 template <typename T>
-HRESULT CopyTo(const absl::optional<T>& value, T* ptr) {
+HRESULT CopyTo(const std::optional<T>& value, T* ptr) {
   *ptr = *value;
   return S_OK;
 }
diff --git a/base/win/wmi.cc b/base/win/wmi.cc
index b5b384e..479da96 100644
--- a/base/win/wmi.cc
+++ b/base/win/wmi.cc
@@ -35,7 +35,7 @@
 
 // Instantiates `wmi_services` with a connection to `server_name` in WMI. Will
 // set a security blanket if `set_blanket` is true.
-absl::optional<WmiError> CreateLocalWmiConnection(
+std::optional<WmiError> CreateLocalWmiConnection(
     bool set_blanket,
     const std::wstring& server_name,
     ComPtr<IWbemServices>* wmi_services) {
@@ -63,7 +63,7 @@
   }
 
   *wmi_services = std::move(wmi_services_r);
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 // Runs `query` through `wmi_services` and sets the results' `enumerator`.
@@ -89,9 +89,9 @@
 
 }  // namespace
 
-absl::optional<WmiError> RunWmiQuery(const std::wstring& server_name,
-                                     const std::wstring& query,
-                                     ComPtr<IEnumWbemClassObject>* enumerator) {
+std::optional<WmiError> RunWmiQuery(const std::wstring& server_name,
+                                    const std::wstring& query,
+                                    ComPtr<IEnumWbemClassObject>* enumerator) {
   SCOPED_MAY_LOAD_LIBRARY_AT_BACKGROUND_PRIORITY();
 
   DCHECK(enumerator);
@@ -106,7 +106,7 @@
   if (!TryRunQuery(query, wmi_services, enumerator))
     return WmiError::kFailedToExecWMIQuery;
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool CreateLocalWmiConnection(bool set_blanket,
diff --git a/base/win/wmi.h b/base/win/wmi.h
index 065e880b..914f2591 100644
--- a/base/win/wmi.h
+++ b/base/win/wmi.h
@@ -23,11 +23,11 @@
 #include <wbemidl.h>
 #include <wrl/client.h>
 
+#include <optional>
 #include <string>
 #include <string_view>
 
 #include "base/base_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 namespace win {
@@ -53,8 +53,8 @@
 // Connects to a server named `server_name` on the local computer through COM
 // and run the given WQL `query`. Sets `enumerator` with the values returned by
 // that `query`. Will return a WmiError value if an error occurs, else returns
-// absl::nullopt.
-BASE_EXPORT absl::optional<WmiError> RunWmiQuery(
+// std::nullopt.
+BASE_EXPORT std::optional<WmiError> RunWmiQuery(
     const std::wstring& server_name,
     const std::wstring& query,
     Microsoft::WRL::ComPtr<IEnumWbemClassObject>* enumerator);
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 544011d..ae3c239e 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -2123,7 +2123,7 @@
     // we can repaint the PaintWorklet during impl side invalidation.
     if (base::Contains(prop_ids, key) &&
         entry.first->ValueChangeShouldCauseRepaint(prev, next)) {
-      entry.second.second = absl::nullopt;
+      entry.second.second = std::nullopt;
     }
   }
 }
diff --git a/chrome/browser/ash/events/event_rewriter_unittest.cc b/chrome/browser/ash/events/event_rewriter_unittest.cc
index d1d189d..3b04adab 100644
--- a/chrome/browser/ash/events/event_rewriter_unittest.cc
+++ b/chrome/browser/ash/events/event_rewriter_unittest.cc
@@ -139,7 +139,7 @@
       ui::EventRewriterAsh::Delegate* ash_delegate)
       : ash_delegate_(ash_delegate) {}
 
-  absl::optional<ui::mojom::ModifierKey> GetKeyboardRemappedModifierValue(
+  std::optional<ui::mojom::ModifierKey> GetKeyboardRemappedModifierValue(
       int device_id,
       ui::mojom::ModifierKey modifier_key,
       const std::string& pref_name) const override {
diff --git a/chrome/browser/ash/file_manager/file_manager_policy_browsertest.cc b/chrome/browser/ash/file_manager/file_manager_policy_browsertest.cc
index 4181699..b2e088d 100644
--- a/chrome/browser/ash/file_manager/file_manager_policy_browsertest.cc
+++ b/chrome/browser/ash/file_manager/file_manager_policy_browsertest.cc
@@ -698,7 +698,7 @@
           /*username*/ kUserName,
           /*profile_identifier*/ profile->GetPath().AsUTF8Unsafe(),
           /*scan_ids*/ expected_scan_ids,
-          /*content_transfer_method*/ absl::nullopt);
+          /*content_transfer_method*/ std::nullopt);
 
       return true;
     }
diff --git a/chrome/browser/ash/file_suggest/drive_recent_file_suggestion_provider.cc b/chrome/browser/ash/file_suggest/drive_recent_file_suggestion_provider.cc
index 7e9362a..05a192be 100644
--- a/chrome/browser/ash/file_suggest/drive_recent_file_suggestion_provider.cc
+++ b/chrome/browser/ash/file_suggest/drive_recent_file_suggestion_provider.cc
@@ -107,7 +107,7 @@
 
   // If the file was shared with user, but not yet viewed by the user, surface
   // it as a shared file.
-  if (const absl::optional<base::Time>& shared_time =
+  if (const std::optional<base::Time>& shared_time =
           file_metadata.shared_with_me_time;
       shared_time && !shared_time->is_null() && viewed_time.is_null()) {
     if ((base::Time::Now() - *shared_time).magnitude() >
diff --git a/chrome/browser/ash/kcer/kcer_factory_ash.cc b/chrome/browser/ash/kcer/kcer_factory_ash.cc
index 975c685..42a5cdf 100644
--- a/chrome/browser/ash/kcer/kcer_factory_ash.cc
+++ b/chrome/browser/ash/kcer/kcer_factory_ash.cc
@@ -107,8 +107,8 @@
   const user_manager::User* user = GetUserByContext(context);
   if (!user) {
     return KcerFactory::InitializeKcerInstanceWithoutNss(
-        kcer_service, /*user_token_id=*/absl::nullopt,
-        /*device_token_id=*/absl::nullopt);
+        kcer_service, /*user_token_id=*/std::nullopt,
+        /*device_token_id=*/std::nullopt);
   }
 
   if (user->IsAffiliated()) {
@@ -117,7 +117,7 @@
 
   return GetUserTokenInfo(std::move(kcer_service), user->GetAccountId(),
                           /*scoped_device_token_info_getter=*/nullptr,
-                          /*device_token_info=*/absl::nullopt);
+                          /*device_token_info=*/std::nullopt);
 }
 
 void KcerFactoryAsh::GetDeviceTokenInfo(
@@ -148,7 +148,7 @@
     base::WeakPtr<internal::KcerImpl> kcer_service,
     AccountId account_id,
     std::unique_ptr<ash::TPMTokenInfoGetter> scoped_device_token_info_getter,
-    absl::optional<user_data_auth::TpmTokenInfo> device_token_info) {
+    std::optional<user_data_auth::TpmTokenInfo> device_token_info) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (!kcer_service) {
     return;
@@ -172,20 +172,20 @@
 
 void KcerFactoryAsh::GotAllTokenInfos(
     base::WeakPtr<internal::KcerImpl> kcer_service,
-    absl::optional<user_data_auth::TpmTokenInfo> device_token_info,
+    std::optional<user_data_auth::TpmTokenInfo> device_token_info,
     std::unique_ptr<ash::TPMTokenInfoGetter> scoped_user_token_info_getter,
-    absl::optional<user_data_auth::TpmTokenInfo> user_token_info) {
+    std::optional<user_data_auth::TpmTokenInfo> user_token_info) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (!kcer_service) {
     return;
   }
 
-  absl::optional<SessionChapsClient::SlotId> user_token_id;
+  std::optional<SessionChapsClient::SlotId> user_token_id;
   if (user_token_info) {
     user_token_id = SessionChapsClient::SlotId(
         static_cast<uint64_t>(user_token_info->slot()));
   }
-  absl::optional<SessionChapsClient::SlotId> device_token_id;
+  std::optional<SessionChapsClient::SlotId> device_token_id;
   if (device_token_info) {
     device_token_id = SessionChapsClient::SlotId(
         static_cast<uint64_t>(device_token_info->slot()));
@@ -249,10 +249,10 @@
 
 void KcerFactoryAsh::InitializeDeviceKcerWithoutNss(
     std::unique_ptr<ash::TPMTokenInfoGetter> scoped_device_token_info_getter,
-    absl::optional<user_data_auth::TpmTokenInfo> device_token_info) {
+    std::optional<user_data_auth::TpmTokenInfo> device_token_info) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  absl::optional<SessionChapsClient::SlotId> device_token_id;
+  std::optional<SessionChapsClient::SlotId> device_token_id;
   if (device_token_info) {
     device_token_id = SessionChapsClient::SlotId(
         static_cast<uint64_t>(device_token_info->slot()));
diff --git a/chrome/browser/ash/kcer/kcer_factory_ash.h b/chrome/browser/ash/kcer/kcer_factory_ash.h
index 2fe0b72..1a271144 100644
--- a/chrome/browser/ash/kcer/kcer_factory_ash.h
+++ b/chrome/browser/ash/kcer/kcer_factory_ash.h
@@ -35,12 +35,12 @@
       base::WeakPtr<internal::KcerImpl> kcer_service,
       AccountId account_id,
       std::unique_ptr<ash::TPMTokenInfoGetter> scoped_device_token_info_getter,
-      absl::optional<user_data_auth::TpmTokenInfo> device_token_info);
+      std::optional<user_data_auth::TpmTokenInfo> device_token_info);
   void GotAllTokenInfos(
       base::WeakPtr<internal::KcerImpl> kcer_service,
-      absl::optional<user_data_auth::TpmTokenInfo> device_token_info,
+      std::optional<user_data_auth::TpmTokenInfo> device_token_info,
       std::unique_ptr<ash::TPMTokenInfoGetter> scoped_user_token_info_getter,
-      absl::optional<user_data_auth::TpmTokenInfo> user_token_info);
+      std::optional<user_data_auth::TpmTokenInfo> user_token_info);
 
   void StartInitializingDeviceKcerForNss();
   void InitializeDeviceKcerForNss(
@@ -50,7 +50,7 @@
   void StartInitializingDeviceKcerWithoutNss();
   void InitializeDeviceKcerWithoutNss(
       std::unique_ptr<ash::TPMTokenInfoGetter> scoped_device_token_info_getter,
-      absl::optional<user_data_auth::TpmTokenInfo> device_token_info);
+      std::optional<user_data_auth::TpmTokenInfo> device_token_info);
 };
 
 }  // namespace kcer
diff --git a/chrome/browser/ash/login/app_mode/test/web_kiosk_browsertest.cc b/chrome/browser/ash/login/app_mode/test/web_kiosk_browsertest.cc
index 4f4377b..ea2206e 100644
--- a/chrome/browser/ash/login/app_mode/test/web_kiosk_browsertest.cc
+++ b/chrome/browser/ash/login/app_mode/test/web_kiosk_browsertest.cc
@@ -54,12 +54,12 @@
                                                             "continueButton"};
 
 std::optional<Profile*> LoadKioskProfile(const AccountId& account_id) {
-  TestFuture<absl::optional<Profile*>> profile_future;
+  TestFuture<std::optional<Profile*>> profile_future;
   auto profile_loader = LoadProfile(
       account_id, KioskAppType::kWebApp,
       base::BindOnce([](KioskProfileLoader::Result result) {
-        return result.has_value() ? absl::make_optional(result.value())
-                                  : absl::nullopt;
+        return result.has_value() ? std::make_optional(result.value())
+                                  : std::nullopt;
       }).Then(profile_future.GetCallback()));
   return profile_future.Take();
 }
diff --git a/chrome/browser/ash/system_web_apps/apps/personalization_app/wallpaper_metrics_provider_unittest.cc b/chrome/browser/ash/system_web_apps/apps/personalization_app/wallpaper_metrics_provider_unittest.cc
index 89f99bd..4b0b412 100644
--- a/chrome/browser/ash/system_web_apps/apps/personalization_app/wallpaper_metrics_provider_unittest.cc
+++ b/chrome/browser/ash/system_web_apps/apps/personalization_app/wallpaper_metrics_provider_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/ash/system_web_apps/apps/personalization_app/wallpaper_metrics_provider.h"
 
+#include <optional>
+
 #include "ash/public/cpp/wallpaper/wallpaper_types.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
@@ -12,7 +14,6 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "components/account_id/account_id.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -34,7 +35,7 @@
   ash::WallpaperInfo info;
   info.type = ash::WallpaperType::kOnline;
   // Explicitly set unit_id to nullopt.
-  info.unit_id = absl::nullopt;
+  info.unit_id = std::nullopt;
   info.collection_id = "test_collection_id";
   wallpaper_controller->SetUserWallpaperInfo(account_id, info);
 
diff --git a/chrome/browser/chromeos/kcer/kcer_factory.cc b/chrome/browser/chromeos/kcer/kcer_factory.cc
index 31913f6..b405f94 100644
--- a/chrome/browser/chromeos/kcer/kcer_factory.cc
+++ b/chrome/browser/chromeos/kcer/kcer_factory.cc
@@ -321,8 +321,8 @@
 
 void KcerFactory::InitializeKcerInstanceWithoutNss(
     base::WeakPtr<internal::KcerImpl> kcer_service,
-    absl::optional<SessionChapsClient::SlotId> user_token_id,
-    absl::optional<SessionChapsClient::SlotId> device_token_id) {
+    std::optional<SessionChapsClient::SlotId> user_token_id,
+    std::optional<SessionChapsClient::SlotId> device_token_id) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (!kcer_service) {
     return;
@@ -334,7 +334,7 @@
 }
 
 base::WeakPtr<internal::KcerToken> KcerFactory::GetTokenWithoutNss(
-    absl::optional<SessionChapsClient::SlotId> token_id,
+    std::optional<SessionChapsClient::SlotId> token_id,
     Token token_type) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
diff --git a/chrome/browser/chromeos/kcer/kcer_factory.h b/chrome/browser/chromeos/kcer/kcer_factory.h
index fb7c405..89bd520b 100644
--- a/chrome/browser/chromeos/kcer/kcer_factory.h
+++ b/chrome/browser/chromeos/kcer/kcer_factory.h
@@ -113,12 +113,12 @@
   // `device_token_id` respectively, initializes `kcer_service` with the tokens.
   void InitializeKcerInstanceWithoutNss(
       base::WeakPtr<internal::KcerImpl> kcer_service,
-      absl::optional<SessionChapsClient::SlotId> user_token_id,
-      absl::optional<SessionChapsClient::SlotId> device_token_id);
+      std::optional<SessionChapsClient::SlotId> user_token_id,
+      std::optional<SessionChapsClient::SlotId> device_token_id);
 
   // Initializes a single token.
   base::WeakPtr<internal::KcerToken> GetTokenWithoutNss(
-      absl::optional<SessionChapsClient::SlotId> token_id,
+      std::optional<SessionChapsClient::SlotId> token_id,
       Token token_type);
 
   // Returns whether the Kcer-without-NSS experiment is enabled.
diff --git a/chrome/browser/chromeos/kcer/kcer_factory_lacros.cc b/chrome/browser/chromeos/kcer/kcer_factory_lacros.cc
index 0ea0d96..7e37325 100644
--- a/chrome/browser/chromeos/kcer/kcer_factory_lacros.cc
+++ b/chrome/browser/chromeos/kcer/kcer_factory_lacros.cc
@@ -44,8 +44,8 @@
   if (!IsPrimaryContext(context) || !lacros_service ||
       !lacros_service->IsAvailable<crosapi::mojom::CertDatabase>()) {
     return KcerFactory::InitializeKcerInstanceWithoutNss(
-        kcer_service, /*user_token_id=*/absl::nullopt,
-        /*device_token_id=*/absl::nullopt);
+        kcer_service, /*user_token_id=*/std::nullopt,
+        /*device_token_id=*/std::nullopt);
   }
 
   // `Unretained` is safe, the factory is never destroyed.
@@ -64,10 +64,10 @@
     return;
   }
 
-  absl::optional<SessionChapsClient::SlotId> user_token_id(
+  std::optional<SessionChapsClient::SlotId> user_token_id(
       cert_db_info->private_slot_id);
 
-  absl::optional<SessionChapsClient::SlotId> device_token_id;
+  std::optional<SessionChapsClient::SlotId> device_token_id;
   if (cert_db_info->enable_system_slot) {
     device_token_id = SessionChapsClient::SlotId(cert_db_info->system_slot_id);
   }
diff --git a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.cc b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.cc
index 7ca2f3a..1b96ab5 100644
--- a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.cc
+++ b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.cc
@@ -239,10 +239,10 @@
   // data.
   base::optional_ref<const ui::DataTransferEndpoint> source =
       data_src.has_value() && !data_src->off_the_record() ? data_src
-                                                          : absl::nullopt;
+                                                          : std::nullopt;
   base::optional_ref<const ui::DataTransferEndpoint> destination =
       data_dst.has_value() && !data_dst->off_the_record() ? data_dst
-                                                          : absl::nullopt;
+                                                          : std::nullopt;
 
   std::string src_pattern;
   std::string dst_pattern;
@@ -321,10 +321,10 @@
   // data.
   base::optional_ref<const ui::DataTransferEndpoint> source =
       data_src.has_value() && !data_src->off_the_record() ? data_src
-                                                          : absl::nullopt;
+                                                          : std::nullopt;
   base::optional_ref<const ui::DataTransferEndpoint> destination =
       data_dst.has_value() && !data_dst->off_the_record() ? data_dst
-                                                          : absl::nullopt;
+                                                          : std::nullopt;
 
   if (absl::holds_alternative<std::vector<base::FilePath>>(pasted_content) &&
       !IsFilesApp(destination)) {
diff --git a/chrome/browser/compose/chrome_compose_client.cc b/chrome/browser/compose/chrome_compose_client.cc
index f161e1d..00f9b42 100644
--- a/chrome/browser/compose/chrome_compose_client.cc
+++ b/chrome/browser/compose/chrome_compose_client.cc
@@ -270,7 +270,7 @@
 
 void ChromeComposeClient::GetInnerText(
     content::RenderFrameHost& host,
-    absl::optional<int> node_id,
+    std::optional<int> node_id,
     content_extraction::InnerTextCallback callback) {
   content_extraction::GetInnerText(host, node_id, std::move(callback));
 }
diff --git a/chrome/browser/compose/chrome_compose_client.h b/chrome/browser/compose/chrome_compose_client.h
index 6e409d1..1a62060 100644
--- a/chrome/browser/compose/chrome_compose_client.h
+++ b/chrome/browser/compose/chrome_compose_client.h
@@ -78,7 +78,7 @@
 
   // InnerTextProvider
   void GetInnerText(content::RenderFrameHost& host,
-                    absl::optional<int> node_id,
+                    std::optional<int> node_id,
                     content_extraction::InnerTextCallback callback) override;
 
   bool GetMSBBStateFromPrefs();
diff --git a/chrome/browser/compose/chrome_compose_client_unittest.cc b/chrome/browser/compose/chrome_compose_client_unittest.cc
index 4e735e1..81965a9 100644
--- a/chrome/browser/compose/chrome_compose_client_unittest.cc
+++ b/chrome/browser/compose/chrome_compose_client_unittest.cc
@@ -71,7 +71,7 @@
   MOCK_METHOD(void,
               GetInnerText,
               (content::RenderFrameHost & host,
-               absl::optional<int> node_id,
+               std::optional<int> node_id,
                content_extraction::InnerTextCallback callback));
 };
 
diff --git a/chrome/browser/compose/compose_session.h b/chrome/browser/compose/compose_session.h
index 9963d51..c9ed912 100644
--- a/chrome/browser/compose/compose_session.h
+++ b/chrome/browser/compose/compose_session.h
@@ -40,7 +40,7 @@
 class InnerTextProvider {
  public:
   virtual void GetInnerText(content::RenderFrameHost& host,
-                            absl::optional<int> node_id,
+                            std::optional<int> node_id,
                             content_extraction::InnerTextCallback callback) = 0;
 
  protected:
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_browsertest.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_browsertest.cc
index 25c03d4f..a83ed9af 100644
--- a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_browsertest.cc
+++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_browsertest.cc
@@ -616,7 +616,7 @@
       /*username*/ kUserName,
       /*profile_identifier*/ GetProfileIdentifier(),
       /*scan_id*/ kScanId1,
-      /*content_transfer_method*/ absl::nullopt);
+      /*content_transfer_method*/ std::nullopt);
 
   bool called = false;
   base::RunLoop run_loop;
diff --git a/chrome/browser/enterprise/connectors/analysis/file_transfer_analysis_delegate_unittest.cc b/chrome/browser/enterprise/connectors/analysis/file_transfer_analysis_delegate_unittest.cc
index c4963d8..8123fba 100644
--- a/chrome/browser/enterprise/connectors/analysis/file_transfer_analysis_delegate_unittest.cc
+++ b/chrome/browser/enterprise/connectors/analysis/file_transfer_analysis_delegate_unittest.cc
@@ -1003,7 +1003,7 @@
       /*username*/ kUserName,
       /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
       /*scan_id*/ scan_id,
-      /*content_transfer_method*/ absl::nullopt);
+      /*content_transfer_method*/ std::nullopt);
 
   ScanUpload(source_url, destination_directory_url_);
 
@@ -1056,7 +1056,7 @@
         /*username*/ kUserName,
         /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
         /*scan_id*/ scan_id,
-        /*content_transfer_method*/ absl::nullopt);
+        /*content_transfer_method*/ std::nullopt);
 
     ScanUpload(source_url, destination_directory_url_);
   }
@@ -1116,7 +1116,7 @@
         /*username*/ kUserName,
         /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
         /*scan_id*/ scan_id,
-        /*content_transfer_method*/ absl::nullopt);
+        /*content_transfer_method*/ std::nullopt);
 
     ScanUpload(source_url, destination_directory_url_);
   }
@@ -1156,7 +1156,7 @@
         /*username*/ kUserName,
         /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
         /*scan_id*/ scan_id,
-        /*content_transfer_method*/ absl::nullopt);
+        /*content_transfer_method*/ std::nullopt);
 
     file_transfer_analysis_delegate_->BypassWarnings(std::nullopt);
   }
@@ -1331,7 +1331,7 @@
       /*username*/ kUserName,
       /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
       /*scan_id*/ scan_id,
-      /*content_transfer_method*/ absl::nullopt);
+      /*content_transfer_method*/ std::nullopt);
 
   ScanUpload(source_url, destination_url);
 
@@ -1443,7 +1443,7 @@
       safe_browsing::EventResultToString(safe_browsing::EventResult::ALLOWED),
       /*username*/ kUserName,
       /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
-      /*content_transfer_method*/ absl::nullopt);
+      /*content_transfer_method*/ std::nullopt);
 
   ScanUpload(source_url, destination_directory_url_);
 
@@ -1516,7 +1516,7 @@
       /*username*/ kUserName,
       /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
       /*scan_id*/ scan_id,
-      /*content_transfer_method*/ absl::nullopt);
+      /*content_transfer_method*/ std::nullopt);
 
   ScanUpload(source_directory_url_, destination_directory_url_);
 
@@ -1599,7 +1599,7 @@
       /*username*/ kUserName,
       /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
       /*scan_ids*/ {scan_id, scan_id, scan_id},
-      /*content_transfer_method*/ absl::nullopt);
+      /*content_transfer_method*/ std::nullopt);
 
   ScanUpload(source_directory_url_, destination_directory_url_);
 
@@ -1664,7 +1664,7 @@
       /*username*/ kUserName,
       /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
       /*scan_ids*/ {scan_id, scan_id},
-      /*content_transfer_method*/ absl::nullopt);
+      /*content_transfer_method*/ std::nullopt);
 
   ScanUpload(source_directory_url_, destination_directory_url_);
 
@@ -1752,7 +1752,7 @@
       /*username*/ kUserName,
       /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
       /*scan_ids*/ expected_scan_ids,
-      /*content_transfer_method*/ absl::nullopt);
+      /*content_transfer_method*/ std::nullopt);
 
   ScanUpload(source_directory_url_, destination_directory_url_);
 
@@ -1856,7 +1856,7 @@
         /*username*/ kUserName,
         /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
         /*scan_ids*/ expected_scan_ids,
-        /*content_transfer_method*/ absl::nullopt);
+        /*content_transfer_method*/ std::nullopt);
 
     ScanUpload(source_directory_url_, destination_directory_url_);
   }
@@ -1936,7 +1936,7 @@
         /*username*/ kUserName,
         /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
         /*scan_ids*/ expected_scan_ids,
-        /*content_transfer_method*/ absl::nullopt);
+        /*content_transfer_method*/ std::nullopt);
 
     file_transfer_analysis_delegate_->BypassWarnings(std::nullopt);
   }
diff --git a/chrome/browser/enterprise/connectors/common_unittest.cc b/chrome/browser/enterprise/connectors/common_unittest.cc
index 512dd6a..be492551 100644
--- a/chrome/browser/enterprise/connectors/common_unittest.cc
+++ b/chrome/browser/enterprise/connectors/common_unittest.cc
@@ -195,7 +195,7 @@
   std::u16string expected_message() const { return std::get<1>(GetParam()); }
 
   AnalysisSettings settings() {
-    absl::optional<AnalysisSettings> settings =
+    std::optional<AnalysisSettings> settings =
         ConnectorsServiceFactory::GetForBrowserContext(profile())
             ->GetAnalysisSettings(GURL(kTestUrl), FILE_ATTACHED);
     EXPECT_TRUE(settings.has_value());
diff --git a/chrome/browser/enterprise/connectors/test/deep_scanning_test_utils.cc b/chrome/browser/enterprise/connectors/test/deep_scanning_test_utils.cc
index 5d7fe8a..2b968bc 100644
--- a/chrome/browser/enterprise/connectors/test/deep_scanning_test_utils.cc
+++ b/chrome/browser/enterprise/connectors/test/deep_scanning_test_utils.cc
@@ -55,7 +55,7 @@
     const std::string& expected_result,
     const std::string& expected_profile_username,
     const std::string& expected_profile_identifier,
-    const absl::optional<std::string>& expected_content_transfer_method) {
+    const std::optional<std::string>& expected_content_transfer_method) {
   event_key_ = SafeBrowsingPrivateEventRouter::kKeyUnscannedFileEvent;
   url_ = expected_url;
   tab_url_ = expected_tab_url;
@@ -97,7 +97,7 @@
     const std::string& expected_result,
     const std::string& expected_profile_username,
     const std::string& expected_profile_identifier,
-    const absl::optional<std::string>& expected_content_transfer_method) {
+    const std::optional<std::string>& expected_content_transfer_method) {
   DCHECK_EQ(expected_filenames.size(), expected_sha256s.size());
   for (size_t i = 0; i < expected_filenames.size(); ++i) {
     filenames_and_hashes_[expected_filenames[i]] = expected_sha256s[i];
@@ -184,7 +184,7 @@
     const std::string& expected_profile_username,
     const std::string& expected_profile_identifier,
     const std::string& expected_scan_id,
-    const absl::optional<std::string>& expected_content_transfer_method) {
+    const std::optional<std::string>& expected_content_transfer_method) {
   event_key_ = SafeBrowsingPrivateEventRouter::kKeySensitiveDataEvent;
   url_ = expected_url;
   tab_url_ = expected_tab_url;
@@ -228,7 +228,7 @@
     const std::string& expected_profile_username,
     const std::string& expected_profile_identifier,
     const std::vector<std::string>& expected_scan_ids,
-    const absl::optional<std::string>& expected_content_transfer_method) {
+    const std::optional<std::string>& expected_content_transfer_method) {
   for (size_t i = 0; i < expected_filenames.size(); ++i) {
     filenames_and_hashes_[expected_filenames[i]] = expected_sha256s[i];
     dlp_verdicts_[expected_filenames[i]] = expected_dlp_verdicts[i];
@@ -274,7 +274,7 @@
         const std::string& expected_profile_username,
         const std::string& expected_profile_identifier,
         const std::string& expected_scan_id,
-        const absl::optional<std::string>& expected_content_transfer_method) {
+        const std::optional<std::string>& expected_content_transfer_method) {
   event_key_ = SafeBrowsingPrivateEventRouter::kKeyDangerousDownloadEvent;
   url_ = expected_url;
   tab_url_ = expected_tab_url;
diff --git a/chrome/browser/enterprise/connectors/test/deep_scanning_test_utils.h b/chrome/browser/enterprise/connectors/test/deep_scanning_test_utils.h
index 65e48d4..9da706c 100644
--- a/chrome/browser/enterprise/connectors/test/deep_scanning_test_utils.h
+++ b/chrome/browser/enterprise/connectors/test/deep_scanning_test_utils.h
@@ -65,7 +65,7 @@
       const std::string& expected_profile_username,
       const std::string& expected_profile_identifier,
       const std::string& expected_scan_id,
-      const absl::optional<std::string>& expected_content_transfer_method);
+      const std::optional<std::string>& expected_content_transfer_method);
 
   void ExpectSensitiveDataEvents(
       const std::string& expected_url,
@@ -82,7 +82,7 @@
       const std::string& expected_profile_username,
       const std::string& expected_profile_identifier,
       const std::vector<std::string>& expected_scan_ids,
-      const absl::optional<std::string>& expected_content_transfer_method);
+      const std::optional<std::string>& expected_content_transfer_method);
 
   void ExpectDangerousDeepScanningResultAndSensitiveDataEvent(
       const std::string& expected_url,
@@ -100,7 +100,7 @@
       const std::string& expected_profile_username,
       const std::string& expected_profile_identifier,
       const std::string& expected_scan_id,
-      const absl::optional<std::string>& expected_content_transfer_method);
+      const std::optional<std::string>& expected_content_transfer_method);
 
   void ExpectSensitiveDataEventAndDangerousDeepScanningResult(
       const std::string& expected_url,
@@ -133,7 +133,7 @@
       const std::string& expected_result,
       const std::string& expected_profile_username,
       const std::string& expected_profile_identifier,
-      const absl::optional<std::string>& expected_content_transfer_method);
+      const std::optional<std::string>& expected_content_transfer_method);
 
   void ExpectUnscannedFileEvents(
       const std::string& expected_url,
@@ -149,7 +149,7 @@
       const std::string& expected_result,
       const std::string& expected_profile_username,
       const std::string& expected_profile_identifier,
-      const absl::optional<std::string>& expected_content_transfer_method);
+      const std::optional<std::string>& expected_content_transfer_method);
 
   void ExpectDangerousDownloadEvent(
       const std::string& expected_url,
@@ -217,8 +217,8 @@
   std::optional<std::string> trigger_ = std::nullopt;
   std::optional<std::string> threat_type_ = std::nullopt;
   std::optional<std::string> unscanned_reason_ = std::nullopt;
-  absl::optional<std::string> content_transfer_method_ = absl::nullopt;
-  absl::optional<int64_t> content_size_ = absl::nullopt;
+  std::optional<std::string> content_transfer_method_ = std::nullopt;
+  std::optional<int64_t> content_size_ = std::nullopt;
   raw_ptr<const std::set<std::string>> mimetypes_ = nullptr;
   std::string username_;
   std::string profile_identifier_;
diff --git a/chrome/browser/enterprise/data_protection/data_protection_clipboard_utils_browsertests.cc b/chrome/browser/enterprise/data_protection/data_protection_clipboard_utils_browsertests.cc
index 581d870..4ef3ba6 100644
--- a/chrome/browser/enterprise/data_protection/data_protection_clipboard_utils_browsertests.cc
+++ b/chrome/browser/enterprise/data_protection/data_protection_clipboard_utils_browsertests.cc
@@ -102,9 +102,9 @@
 
 IN_PROC_BROWSER_TEST_F(DataControlsClipboardUtilsBrowserTest,
                        PasteAllowed_NoSource) {
-  base::test::TestFuture<absl::optional<content::ClipboardPasteData>> future;
+  base::test::TestFuture<std::optional<content::ClipboardPasteData>> future;
   PasteIfAllowedByPolicy(
-      /*source=*/content::ClipboardEndpoint(absl::nullopt),
+      /*source=*/content::ClipboardEndpoint(std::nullopt),
       /*destination=*/
       content::ClipboardEndpoint(
           ui::DataTransferEndpoint(GURL("https://google.com")),
@@ -125,7 +125,7 @@
 
 IN_PROC_BROWSER_TEST_F(DataControlsClipboardUtilsBrowserTest,
                        PasteAllowed_SameSource) {
-  base::test::TestFuture<absl::optional<content::ClipboardPasteData>> future;
+  base::test::TestFuture<std::optional<content::ClipboardPasteData>> future;
   PasteIfAllowedByPolicy(
       /*source=*/content::ClipboardEndpoint(
           ui::DataTransferEndpoint(GURL("https://google.com")),
@@ -163,9 +163,9 @@
   set_expected_dialog_type(
       data_controls::DataControlsDialog::Type::kClipboardPasteBlock);
 
-  base::test::TestFuture<absl::optional<content::ClipboardPasteData>> future;
+  base::test::TestFuture<std::optional<content::ClipboardPasteData>> future;
   PasteIfAllowedByPolicy(
-      /*source=*/content::ClipboardEndpoint(absl::nullopt),
+      /*source=*/content::ClipboardEndpoint(std::nullopt),
       /*destination=*/
       content::ClipboardEndpoint(
           ui::DataTransferEndpoint(GURL("https://google.com")),
@@ -209,7 +209,7 @@
         /*delegate=*/nullptr, Profile::CreateMode::CREATE_MODE_SYNCHRONOUS);
   }
 
-  base::test::TestFuture<absl::optional<content::ClipboardPasteData>> future;
+  base::test::TestFuture<std::optional<content::ClipboardPasteData>> future;
   PasteIfAllowedByPolicy(
       /*destination=*/content::ClipboardEndpoint(
           ui::DataTransferEndpoint(GURL("https://foo.com")),
diff --git a/chrome/browser/enterprise/data_protection/data_protection_clipboard_utils_unittest.cc b/chrome/browser/enterprise/data_protection/data_protection_clipboard_utils_unittest.cc
index b2821e7..ba352cd 100644
--- a/chrome/browser/enterprise/data_protection/data_protection_clipboard_utils_unittest.cc
+++ b/chrome/browser/enterprise/data_protection/data_protection_clipboard_utils_unittest.cc
@@ -184,7 +184,7 @@
        DataProtectionPaste_NoDestinationWebContents) {
   // Missing a destination WebContents implies the tab is gone, so null should
   // always be returned even if no DC rule is set.
-  base::test::TestFuture<absl::optional<content::ClipboardPasteData>> future;
+  base::test::TestFuture<std::optional<content::ClipboardPasteData>> future;
   PasteIfAllowedByPolicy(
       SourceEndpoint(),
       content::ClipboardEndpoint(
diff --git a/chrome/browser/enterprise/data_protection/print_utils_unittest.cc b/chrome/browser/enterprise/data_protection/print_utils_unittest.cc
index 397604f..e637512 100644
--- a/chrome/browser/enterprise/data_protection/print_utils_unittest.cc
+++ b/chrome/browser/enterprise/data_protection/print_utils_unittest.cc
@@ -456,7 +456,7 @@
       /*username*/ kUserName,
       /*profile_identifier*/ profile()->GetPath().AsUTF8Unsafe(),
       /*scan_id*/ kScanId,
-      /*content_transfer_method*/ absl::nullopt);
+      /*content_transfer_method*/ std::nullopt);
 
   auto data = CreateData();
   base::RunLoop run_loop;
@@ -520,7 +520,7 @@
       /*username*/ kUserName,
       /*profile_identifier*/ profile()->GetPath().AsUTF8Unsafe(),
       /*scan_id*/ kScanId,
-      /*content_transfer_method*/ absl::nullopt);
+      /*content_transfer_method*/ std::nullopt);
 
   auto data = CreateData();
   base::RunLoop run_loop;
@@ -587,7 +587,7 @@
           /*username*/ kUserName,
           /*profile_identifier*/ profile()->GetPath().AsUTF8Unsafe(),
           /*scan_id*/ kScanId,
-          /*content_transfer_method*/ absl::nullopt);
+          /*content_transfer_method*/ std::nullopt);
       ASSERT_TRUE(test_delegate_);
       test_delegate_->SetPageWarningForTesting(
           CreateResponse(ContentAnalysisResponse::Result::TriggeredRule::WARN));
@@ -613,7 +613,7 @@
       /*username*/ kUserName,
       /*profile_identifier*/ profile()->GetPath().AsUTF8Unsafe(),
       /*scan_id*/ kScanId,
-      /*content_transfer_method*/ absl::nullopt);
+      /*content_transfer_method*/ std::nullopt);
 
   auto data = CreateData();
   base::RunLoop run_loop;
@@ -671,7 +671,7 @@
       /*username*/ kUserName,
       /*profile_identifier*/ profile()->GetPath().AsUTF8Unsafe(),
       /*scan_id*/ kScanId,
-      /*content_transfer_method*/ absl::nullopt);
+      /*content_transfer_method*/ std::nullopt);
 
   auto data = CreateData();
   base::RunLoop run_loop;
diff --git a/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc b/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc
index ee0e3dc..07062bc 100644
--- a/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc
+++ b/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc
@@ -1051,7 +1051,7 @@
     return RespondNow(Error(kErrorDataUnavailable));
   }
 
-  absl::optional<api::autofill_private::SetAutofillSyncToggleEnabled::Params>
+  std::optional<api::autofill_private::SetAutofillSyncToggleEnabled::Params>
       parameters =
           api::autofill_private::SetAutofillSyncToggleEnabled::Params::Create(
               args());
diff --git a/chrome/browser/extensions/api/cookies/cookies_helpers.cc b/chrome/browser/extensions/api/cookies/cookies_helpers.cc
index e3119d4..833ec1f 100644
--- a/chrome/browser/extensions/api/cookies/cookies_helpers.cc
+++ b/chrome/browser/extensions/api/cookies/cookies_helpers.cc
@@ -251,7 +251,7 @@
 bool CanonicalCookiePartitionKeyMatchesApiCookiePartitionKey(
     const std::optional<extensions::api::cookies::CookiePartitionKey>&
         api_partition_key,
-    const absl::optional<net::CookiePartitionKey>& net_partition_key) {
+    const std::optional<net::CookiePartitionKey>& net_partition_key) {
   if (!api_partition_key.has_value()) {
     return !net_partition_key.has_value();
   }
diff --git a/chrome/browser/extensions/api/cookies/cookies_helpers.h b/chrome/browser/extensions/api/cookies/cookies_helpers.h
index f591ab6f..e0ca036b 100644
--- a/chrome/browser/extensions/api/cookies/cookies_helpers.h
+++ b/chrome/browser/extensions/api/cookies/cookies_helpers.h
@@ -127,7 +127,7 @@
 bool CanonicalCookiePartitionKeyMatchesApiCookiePartitionKey(
     const std::optional<extensions::api::cookies::CookiePartitionKey>&
         api_partition_key,
-    const absl::optional<net::CookiePartitionKey>& net_partition_key);
+    const std::optional<net::CookiePartitionKey>& net_partition_key);
 
 // A class representing the cookie filter parameters passed into
 // cookies.getAll().
diff --git a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc
index cf8aaa7c..b28384b4 100644
--- a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc
+++ b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc
@@ -578,7 +578,7 @@
     const std::string& evidence_locker_filepath,
     const std::string& scan_id,
     const std::string& content_transfer_method) {
-  absl::optional<enterprise_connectors::ReportingSettings> settings =
+  std::optional<enterprise_connectors::ReportingSettings> settings =
       reporting_client_->GetReportingSettings();
   if (!settings.has_value() ||
       settings->enabled_event_names.count(kKeyDangerousDownloadEvent) == 0) {
diff --git a/chrome/browser/history/history_tab_helper.h b/chrome/browser/history/history_tab_helper.h
index 3fc5d3b1..ea157dd 100644
--- a/chrome/browser/history/history_tab_helper.h
+++ b/chrome/browser/history/history_tab_helper.h
@@ -122,7 +122,7 @@
   std::optional<NavigationState> cached_navigation_state_;
 
   // The package name of an app that opens a Custom Tab and visits a URL.
-  absl::optional<std::string> app_id_ = absl::nullopt;
+  std::optional<std::string> app_id_ = std::nullopt;
 
   // Set to true in unit tests to avoid need for a Browser instance.
   bool force_eligible_tab_for_testing_ = false;
diff --git a/chrome/browser/k_anonymity_service/k_anonymity_service_client_browsertest.cc b/chrome/browser/k_anonymity_service/k_anonymity_service_client_browsertest.cc
index 3976d456..d24de94 100644
--- a/chrome/browser/k_anonymity_service/k_anonymity_service_client_browsertest.cc
+++ b/chrome/browser/k_anonymity_service/k_anonymity_service_client_browsertest.cc
@@ -165,7 +165,7 @@
           << request.all_headers;
       return MakeTrustTokenFailureResponse();
     }
-    absl::optional<std::string> operation_result = trust_token_handler_.Issue(
+    std::optional<std::string> operation_result = trust_token_handler_.Issue(
         request.headers.at("Sec-Private-State-Token"));
     if (!operation_result) {
       ADD_FAILURE() << "Trust token issue request operation failed.";
@@ -214,7 +214,7 @@
     quiche::BinaryHttpResponse response(net::HTTP_OK);
 
     std::string path = request.control_data().path;
-    absl::optional<std::string> redemption_result;
+    std::optional<std::string> redemption_result;
     for (const auto& header : request.GetHeaderFields()) {
       if (base::EqualsCaseInsensitiveASCII(header.name,
                                            "Sec-Private-State-Token")) {
@@ -250,7 +250,7 @@
         quiche::BinaryHttpRequest::Create(plaintext_request.first).value();
     std::string path = bhttp_request.control_data().path;
 
-    absl::optional<quiche::BinaryHttpResponse> response;
+    std::optional<quiche::BinaryHttpResponse> response;
     if (path.starts_with("/v1:query?key=")) {
       response.emplace(HandleBhttpQueryRequest(bhttp_request));
     } else if (path.starts_with("/v1/types/fledge/sets/")) {
diff --git a/chrome/browser/media/webrtc/desktop_capture_devices_util.cc b/chrome/browser/media/webrtc/desktop_capture_devices_util.cc
index 02da50a..0e375158 100644
--- a/chrome/browser/media/webrtc/desktop_capture_devices_util.cc
+++ b/chrome/browser/media/webrtc/desktop_capture_devices_util.cc
@@ -104,20 +104,20 @@
   return result;
 }
 
-absl::optional<int> GetZoomLevel(content::WebContents* capturer,
-                                 const content::DesktopMediaID& captured_id) {
+std::optional<int> GetZoomLevel(content::WebContents* capturer,
+                                const content::DesktopMediaID& captured_id) {
   content::RenderFrameHost* const captured_rfh =
       content::RenderFrameHost::FromID(
           captured_id.web_contents_id.render_process_id,
           captured_id.web_contents_id.main_render_frame_id);
   if (!captured_rfh || !captured_rfh->IsActive()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   content::WebContents* const captured_wc =
       content::WebContents::FromRenderFrameHost(captured_rfh);
   if (!captured_wc) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   double zoom_level = blink::PageZoomLevelToZoomFactor(
diff --git a/chrome/browser/net/cert_verifier_service_browsertest.cc b/chrome/browser/net/cert_verifier_service_browsertest.cc
index f950a236..b10f484 100644
--- a/chrome/browser/net/cert_verifier_service_browsertest.cc
+++ b/chrome/browser/net/cert_verifier_service_browsertest.cc
@@ -281,7 +281,7 @@
     policy::PolicyTest::SetUpInProcessBrowserTestFixture();
     policy::PolicyMap policies;
     SetPolicy(&policies, policy::key::kCAPlatformIntegrationEnabled,
-              absl::optional<base::Value>(platform_root_store_enabled()));
+              std::optional<base::Value>(platform_root_store_enabled()));
     UpdateProviderPolicy(policies);
   }
 
diff --git a/chrome/browser/net/profile_network_context_service.cc b/chrome/browser/net/profile_network_context_service.cc
index 0525b84..da1e68f 100644
--- a/chrome/browser/net/profile_network_context_service.cc
+++ b/chrome/browser/net/profile_network_context_service.cc
@@ -552,7 +552,7 @@
 
   for (const base::Value& cert_b64 :
        prefs->GetList(prefs::kCAHintCertificates)) {
-    absl::optional<std::vector<uint8_t>> decoded_opt =
+    std::optional<std::vector<uint8_t>> decoded_opt =
         base::Base64Decode(cert_b64.GetString());
 
     if (decoded_opt.has_value()) {
@@ -561,7 +561,7 @@
   }
 
   for (const base::Value& cert_b64 : prefs->GetList(prefs::kCACertificates)) {
-    absl::optional<std::vector<uint8_t>> decoded_opt =
+    std::optional<std::vector<uint8_t>> decoded_opt =
         base::Base64Decode(cert_b64.GetString());
 
     if (decoded_opt.has_value()) {
diff --git a/chrome/browser/new_tab_page/modules/history_clusters/ranking/history_clusters_module_ranker_unittest.cc b/chrome/browser/new_tab_page/modules/history_clusters/ranking/history_clusters_module_ranker_unittest.cc
index b5e15bdbf..cf04dfa 100644
--- a/chrome/browser/new_tab_page/modules/history_clusters/ranking/history_clusters_module_ranker_unittest.cc
+++ b/chrome/browser/new_tab_page/modules/history_clusters/ranking/history_clusters_module_ranker_unittest.cc
@@ -890,7 +890,7 @@
   visit.content_annotations.model_annotations.categories = {
       {"category1", 90}, {"boostedbuthidden", 84}};
   cluster1.visits = {history_clusters::testing::CreateClusterVisit(
-      visit, /*normalized_url=*/absl::nullopt, 0.0)};
+      visit, /*normalized_url=*/std::nullopt, 0.0)};
 
   history::Cluster cluster2 = cluster1;
   cluster2.cluster_id = 2;
diff --git a/chrome/browser/notifications/notification_platform_bridge_android.cc b/chrome/browser/notifications/notification_platform_bridge_android.cc
index e2fd7f4f..b3b2757 100644
--- a/chrome/browser/notifications/notification_platform_bridge_android.cc
+++ b/chrome/browser/notifications/notification_platform_bridge_android.cc
@@ -273,8 +273,8 @@
                      NotificationOperation::kDisablePermission,
                      notification_type,
                      GURL(ConvertJavaStringToUTF8(env, java_origin)),
-                     notification_id, absl::nullopt /* action index */,
-                     absl::nullopt /* reply */, absl::nullopt /* by_user */));
+                     notification_id, std::nullopt /* action index */,
+                     std::nullopt /* reply */, std::nullopt /* by_user */));
 }
 
 void NotificationPlatformBridgeAndroid::Display(
diff --git a/chrome/browser/push_notification/server_client/push_notification_desktop_api_call_flow_impl.cc b/chrome/browser/push_notification/server_client/push_notification_desktop_api_call_flow_impl.cc
index 05e8362..d640030 100644
--- a/chrome/browser/push_notification/server_client/push_notification_desktop_api_call_flow_impl.cc
+++ b/chrome/browser/push_notification/server_client/push_notification_desktop_api_call_flow_impl.cc
@@ -134,7 +134,7 @@
     int net_error,
     const network::mojom::URLResponseHead* head,
     std::unique_ptr<std::string> body) {
-  absl::optional<PushNotificationApiCallFlowError> error;
+  std::optional<PushNotificationApiCallFlowError> error;
   std::string error_message;
   if (net_error == net::OK) {
     int response_code = -1;
diff --git a/chrome/browser/push_notification/server_client/push_notification_desktop_api_call_flow_impl.h b/chrome/browser/push_notification/server_client/push_notification_desktop_api_call_flow_impl.h
index 333cd65..5cb6e457 100644
--- a/chrome/browser/push_notification/server_client/push_notification_desktop_api_call_flow_impl.h
+++ b/chrome/browser/push_notification/server_client/push_notification_desktop_api_call_flow_impl.h
@@ -6,13 +6,13 @@
 #define CHROME_BROWSER_PUSH_NOTIFICATION_SERVER_CLIENT_PUSH_NOTIFICATION_DESKTOP_API_CALL_FLOW_IMPL_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "chrome/browser/push_notification/server_client/push_notification_desktop_api_call_flow.h"
 #include "google_apis/gaia/oauth2_api_call_flow.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace push_notification {
 
@@ -89,12 +89,12 @@
 
   // Serialized request message proto that will be sent in the request body.
   // Null if request is GET.
-  absl::optional<std::string> serialized_request_;
+  std::optional<std::string> serialized_request_;
 
   // The request message proto represented as key-value pairs that will be sent
   // as query parameters in the API GET request. Note: A key can have multiple
   // values. Null if HTTP method is not GET.
-  absl::optional<QueryParameters> request_as_query_parameters_;
+  std::optional<QueryParameters> request_as_query_parameters_;
 
   // Callback invoked with the serialized response message proto when the flow
   // completes successfully.
diff --git a/chrome/browser/push_notification/server_client/push_notification_desktop_api_call_flow_impl_unittest.cc b/chrome/browser/push_notification/server_client/push_notification_desktop_api_call_flow_impl_unittest.cc
index 90e41eea..a810cf0 100644
--- a/chrome/browser/push_notification/server_client/push_notification_desktop_api_call_flow_impl_unittest.cc
+++ b/chrome/browser/push_notification/server_client/push_notification_desktop_api_call_flow_impl_unittest.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/push_notification/server_client/push_notification_desktop_api_call_flow_impl.h"
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -18,7 +19,6 @@
 #include "services/network/test/test_url_loader_factory.h"
 #include "services/network/test/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -47,7 +47,7 @@
 // 'request_as_query_parameters' is only non-null for GET requests.
 GURL UrlWithQueryParameters(
     const std::string& url,
-    const absl::optional<
+    const std::optional<
         push_notification::PushNotificationDesktopApiCallFlow::QueryParameters>&
         request_as_query_parameters) {
   GURL url_with_qp(url);
@@ -153,7 +153,7 @@
     const network::ResourceRequest& request = pending[0].request;
 
     EXPECT_EQ(UrlWithQueryParameters(
-                  kRequestUrl, absl::nullopt /* request_as_query_parameters */),
+                  kRequestUrl, std::nullopt /* request_as_query_parameters */),
               request.url);
 
     EXPECT_EQ(kPost, request.method);
@@ -174,7 +174,7 @@
     const network::ResourceRequest& request = pending[0].request;
 
     EXPECT_EQ(UrlWithQueryParameters(
-                  kRequestUrl, absl::nullopt /* request_as_query_parameters */),
+                  kRequestUrl, std::nullopt /* request_as_query_parameters */),
               request.url);
 
     EXPECT_EQ(kPatch, request.method);
@@ -210,8 +210,8 @@
   // then the 'response_code' and 'response_string' are null.
   void CompleteCurrentPostRequest(
       net::Error error,
-      absl::optional<int> response_code = absl::nullopt,
-      const absl::optional<std::string>& response_string = absl::nullopt) {
+      std::optional<int> response_code = std::nullopt,
+      const std::optional<std::string>& response_string = std::nullopt) {
     network::URLLoaderCompletionStatus completion_status(error);
     auto response_head = network::mojom::URLResponseHead::New();
     std::string content;
@@ -233,8 +233,8 @@
   // then the 'response_code' and 'response_string' are null.
   void CompleteCurrentPatchRequest(
       net::Error error,
-      absl::optional<int> response_code = absl::nullopt,
-      const absl::optional<std::string>& response_string = absl::nullopt) {
+      std::optional<int> response_code = std::nullopt,
+      const std::optional<std::string>& response_string = std::nullopt) {
     network::URLLoaderCompletionStatus completion_status(error);
     auto response_head = network::mojom::URLResponseHead::New();
     std::string content;
@@ -256,8 +256,8 @@
   // then the 'response_code' and 'response_string' are null.
   void CompleteCurrentGetRequest(
       net::Error error,
-      absl::optional<int> response_code = absl::nullopt,
-      const absl::optional<std::string>& response_string = absl::nullopt) {
+      std::optional<int> response_code = std::nullopt,
+      const std::optional<std::string>& response_string = std::nullopt) {
     network::URLLoaderCompletionStatus completion_status(error);
     auto response_head = network::mojom::URLResponseHead::New();
     std::string content;
diff --git a/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos_unittest.cc b/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos_unittest.cc
index ca03493..d45b9c9 100644
--- a/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos_unittest.cc
+++ b/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos_unittest.cc
@@ -540,7 +540,7 @@
 
   tab_manager_delegate.LowMemoryKillImpl(
       base::TimeTicks::Now(), ::mojom::LifecycleUnitDiscardReason::EXTERNAL,
-      TabManager::TabDiscardDoneCB(base::DoNothing()), absl::nullopt);
+      TabManager::TabDiscardDoneCB(base::DoNothing()), std::nullopt);
 
   auto killed_tabs = tab_manager_delegate.GetKilledTabs();
 
diff --git a/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.cc b/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.cc
index f14ba99..6fb67f2 100644
--- a/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.cc
+++ b/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.cc
@@ -40,7 +40,7 @@
     const GURL& main_frame_url,
     const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources,
     bool should_trigger_reporting,
-    absl::optional<base::TimeTicks> blocked_page_shown_timestamp) {
+    std::optional<base::TimeTicks> blocked_page_shown_timestamp) {
   auto* profile =
       Profile::FromBrowserContext(web_contents->GetBrowserContext());
   // Create appropriate display options for this blocking page.
@@ -141,7 +141,7 @@
     content::WebContents* web_contents,
     const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources,
     const BaseUIManager* ui_manager,
-    absl::optional<base::TimeTicks> blocked_page_shown_timestamp) {
+    std::optional<base::TimeTicks> blocked_page_shown_timestamp) {
   Profile* profile =
       Profile::FromBrowserContext(web_contents->GetBrowserContext());
   DCHECK(profile);
diff --git a/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.h b/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.h
index 755b3e5d..e6858828 100644
--- a/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.h
+++ b/chrome/browser/safe_browsing/chrome_safe_browsing_blocking_page_factory.h
@@ -19,7 +19,7 @@
       const GURL& main_frame_url,
       const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources,
       bool should_trigger_reporting,
-      absl::optional<base::TimeTicks> blocked_page_shown_timestamp) override;
+      std::optional<base::TimeTicks> blocked_page_shown_timestamp) override;
 
 #if !BUILDFLAG(IS_ANDROID)
   security_interstitials::SecurityInterstitialPage* CreateEnterpriseWarnPage(
@@ -51,7 +51,7 @@
       content::WebContents* web_contents,
       const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources,
       const BaseUIManager* ui_manager,
-      absl::optional<base::TimeTicks> blocked_page_shown_timestamp);
+      std::optional<base::TimeTicks> blocked_page_shown_timestamp);
 };
 
 }  // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/download_protection/deep_scanning_browsertest.cc b/chrome/browser/safe_browsing/download_protection/deep_scanning_browsertest.cc
index 8af3fb5..238cda59 100644
--- a/chrome/browser/safe_browsing/download_protection/deep_scanning_browsertest.cc
+++ b/chrome/browser/safe_browsing/download_protection/deep_scanning_browsertest.cc
@@ -1313,7 +1313,7 @@
       /*username*/ kUserName,
       /*profile_identifier*/ GetProfileIdentifier(),
       /*scan_id*/ last_request().request_token(),
-      /*content_transfer_method*/ absl::nullopt);
+      /*content_transfer_method*/ std::nullopt);
 
   SendFcmMessage(response);
   run_loop.Run();
@@ -1385,7 +1385,7 @@
       /*username*/ kUserName,
       /*profile_identifier*/ GetProfileIdentifier(),
       /*scan_id*/ last_request().request_token(),
-      /*content_transfer_method*/ absl::nullopt);
+      /*content_transfer_method*/ std::nullopt);
 
   SendFcmMessage(response);
   validator_run_loop.Run();
@@ -1423,7 +1423,7 @@
       /*username*/ kUserName,
       /*profile_identifier*/ GetProfileIdentifier(),
       /*scan_id*/ last_request().request_token(),
-      /*content_transfer_method*/ absl::nullopt);
+      /*content_transfer_method*/ std::nullopt);
 
   DownloadItemModel model(item);
   DownloadCommands(model.GetWeakPtr()).ExecuteCommand(DownloadCommands::KEEP);
@@ -1495,7 +1495,7 @@
       /*username*/ kUserName,
       /*profile_identifier*/ GetProfileIdentifier(),
       /*scan_id*/ last_request().request_token(),
-      /*content_transfer_method*/ absl::nullopt);
+      /*content_transfer_method*/ std::nullopt);
 
   SendFcmMessage(response);
   validator_run_loop.Run();
@@ -1598,7 +1598,7 @@
       /*username*/ kUserName,
       /*profile_identifier*/ GetProfileIdentifier(),
       /*scan_id*/ last_request().request_token(),
-      /*content_transfer_method*/ absl::nullopt);
+      /*content_transfer_method*/ std::nullopt);
 
   SendFcmMessage(response);
   validator_run_loop.Run();
diff --git a/chrome/browser/safe_browsing/download_protection/deep_scanning_request_unittest.cc b/chrome/browser/safe_browsing/download_protection/deep_scanning_request_unittest.cc
index 7d3ef8ad..34e0833 100644
--- a/chrome/browser/safe_browsing/download_protection/deep_scanning_request_unittest.cc
+++ b/chrome/browser/safe_browsing/download_protection/deep_scanning_request_unittest.cc
@@ -717,7 +717,7 @@
         /*username*/ kUserName,
         /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
         /*scan_id*/ kScanId,
-        /*content_transfer_method*/ absl::nullopt);
+        /*content_transfer_method*/ std::nullopt);
 
     request.Start();
 
@@ -791,7 +791,7 @@
         /*username*/ kUserName,
         /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
         /*scan_id*/ kScanId,
-        /*content_transfer_method*/ absl::nullopt);
+        /*content_transfer_method*/ std::nullopt);
 
     request.Start();
 
@@ -855,7 +855,7 @@
         /*username*/ kUserName,
         /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
         /*scan_id*/ kScanId,
-        /*content_transfer_method*/ absl::nullopt);
+        /*content_transfer_method*/ std::nullopt);
 
     request.Start();
 
@@ -919,7 +919,7 @@
         /*username*/ kUserName,
         /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
         /*scan_id*/ kScanId,
-        /*content_transfer_method*/ absl::nullopt);
+        /*content_transfer_method*/ std::nullopt);
 
     request.Start();
 
@@ -987,7 +987,7 @@
         /*username*/ kUserName,
         /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
         /*scan_id*/ kScanId,
-        /*content_transfer_method*/ absl::nullopt);
+        /*content_transfer_method*/ std::nullopt);
 
     request.Start();
 
@@ -1046,7 +1046,7 @@
         EventResultToString(EventResult::ALLOWED),
         /*username*/ kUserName,
         /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
-        /*content_transfer_method*/ absl::nullopt);
+        /*content_transfer_method*/ std::nullopt);
 
     request.Start();
 
@@ -1105,7 +1105,7 @@
         EventResultToString(EventResult::ALLOWED),
         /*username*/ kUserName,
         /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
-        /*content_transfer_method*/ absl::nullopt);
+        /*content_transfer_method*/ std::nullopt);
 
     request.Start();
 
@@ -1169,7 +1169,7 @@
         EventResultToString(EventResult::WARNED),
         /*username*/ kUserName,
         /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
-        /*content_transfer_reason*/ absl::nullopt);
+        /*content_transfer_reason*/ std::nullopt);
 
     request.Start();
 
@@ -1451,7 +1451,7 @@
         /*result*/ EventResultToString(EventResult::ALLOWED),
         /*username*/ kUserName,
         /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
-        /*content_transfer_reason*/ absl::nullopt);
+        /*content_transfer_reason*/ std::nullopt);
 
     request.Start();
     run_loop.Run();
@@ -1562,7 +1562,7 @@
             kScanId + std::string("0"),
             kScanId + std::string("1"),
         },
-        /*content_transfer_reason*/ absl::nullopt);
+        /*content_transfer_reason*/ std::nullopt);
 
     request.Start();
     run_loop.Run();
@@ -1617,7 +1617,7 @@
       EventResultToString(EventResult::ALLOWED),
       /*username*/ kUserName,
       /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
-      /*content_transfer_reason*/ absl::nullopt);
+      /*content_transfer_reason*/ std::nullopt);
 
   request.Start();
 
@@ -1864,7 +1864,7 @@
         EventResultToString(expected_event_result_for_safe_large_file()),
         /*username*/ kUserName,
         /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
-        /*content_transfer_reason*/ absl::nullopt);
+        /*content_transfer_reason*/ std::nullopt);
 
     request.Start();
 
@@ -1924,7 +1924,7 @@
         /*result*/ EventResultToString(expected_event_result_for_malware()),
         /*username*/ kUserName,
         /*profile_identifier*/ profile_->GetPath().AsUTF8Unsafe(),
-        /*content_transfer_reason*/ absl::nullopt);
+        /*content_transfer_reason*/ std::nullopt);
 
     request.Start();
 
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc
index da99a48..66bb580 100644
--- a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc
+++ b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc
@@ -3030,7 +3030,7 @@
           safe_browsing::EventResult::BYPASSED),  // expected_result
       "",                                         // expected_username
       profile()->GetPath().AsUTF8Unsafe(),        // expected_profile_identifier
-      {} /* expected_scan_id */, absl::nullopt /* content_transfer_reason */);
+      {} /* expected_scan_id */, std::nullopt /* content_transfer_reason */);
 
   download_service_->MaybeSendDangerousDownloadOpenedReport(&item, false);
   EXPECT_EQ(1, sb_service_->download_report_count());
@@ -3148,7 +3148,7 @@
           safe_browsing::EventResult::BYPASSED),  // expected_result
       "",                                         // expected_username
       profile()->GetPath().AsUTF8Unsafe(),        // expected_profile_identifier
-      {} /* expected_scan_id */, absl::nullopt /* content_transfer_method */);
+      {} /* expected_scan_id */, std::nullopt /* content_transfer_method */);
 
   download_service_->ReportDelayedBypassEvent(
       &item, download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_WARNING);
@@ -3212,7 +3212,7 @@
           safe_browsing::EventResult::BYPASSED),  // expected_result
       "",                                         // expected_username
       profile()->GetPath().AsUTF8Unsafe(),        // expected_profile_identifier
-      {} /* expected_scan_id */, absl::nullopt /* content_transfer_method */);
+      {} /* expected_scan_id */, std::nullopt /* content_transfer_method */);
 
   download_service_->ReportDelayedBypassEvent(
       &item, download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_BLOCK);
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
index f478a70..cec2dad 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -488,7 +488,7 @@
       bool is_safe_browsing_surveys_enabled,
       base::OnceCallback<void(bool, SBThreatType)>
           trust_safety_sentiment_service_trigger,
-      absl::optional<base::TimeTicks> blocked_page_shown_timestamp)
+      std::optional<base::TimeTicks> blocked_page_shown_timestamp)
       : SafeBrowsingBlockingPage(
             manager,
             web_contents,
@@ -549,7 +549,7 @@
       const GURL& main_frame_url,
       const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources,
       bool should_trigger_reporting,
-      absl::optional<base::TimeTicks> blocked_page_shown_timestamp) override {
+      std::optional<base::TimeTicks> blocked_page_shown_timestamp) override {
     PrefService* prefs =
         Profile::FromBrowserContext(web_contents->GetBrowserContext())
             ->GetPrefs();
@@ -3265,7 +3265,7 @@
         contents,
         is_subresource ? GURL("http://mainframe.example.com/") : request_url,
         {resource}, /*forward_extension_event=*/false,
-        /*blocked_page_shown_timestamp=*/absl::nullopt);
+        /*blocked_page_shown_timestamp=*/std::nullopt);
   }
 };
 
diff --git a/chrome/browser/safe_browsing/test_safe_browsing_blocking_page_quiet.cc b/chrome/browser/safe_browsing/test_safe_browsing_blocking_page_quiet.cc
index 51b122f..5bc0041b 100644
--- a/chrome/browser/safe_browsing/test_safe_browsing_blocking_page_quiet.cc
+++ b/chrome/browser/safe_browsing/test_safe_browsing_blocking_page_quiet.cc
@@ -30,7 +30,7 @@
                            ui_manager,
                            nullptr,
                            /* settings_page_helper */ nullptr,
-                           /* blocked_page_shown_timestamp */ absl::nullopt),
+                           /* blocked_page_shown_timestamp */ std::nullopt),
                        display_options),
       sb_error_ui_(unsafe_resources[0].url,
                    main_frame_url,
diff --git a/chrome/browser/screen_ai/screen_ai_service_router_browsertest.cc b/chrome/browser/screen_ai/screen_ai_service_router_browsertest.cc
index d368daf..06cc4e8 100644
--- a/chrome/browser/screen_ai/screen_ai_service_router_browsertest.cc
+++ b/chrome/browser/screen_ai/screen_ai_service_router_browsertest.cc
@@ -53,7 +53,7 @@
     run_loop.Run();
   }
 
-  void ResetResult() { result_ = absl::nullopt; }
+  void ResetResult() { result_ = std::nullopt; }
 
   bool GetResult() {
     EXPECT_TRUE(result_);
diff --git a/chrome/browser/ui/ash/birch/birch_file_suggest_provider.cc b/chrome/browser/ui/ash/birch/birch_file_suggest_provider.cc
index 5864a7f2..727a22c 100644
--- a/chrome/browser/ui/ash/birch/birch_file_suggest_provider.cc
+++ b/chrome/browser/ui/ash/birch/birch_file_suggest_provider.cc
@@ -43,7 +43,7 @@
 }
 
 void BirchFileSuggestProvider::OnSuggestedFileDataUpdated(
-    const absl::optional<std::vector<FileSuggestData>>& suggest_results) {
+    const std::optional<std::vector<FileSuggestData>>& suggest_results) {
   if (!suggest_results) {
     Shell::Get()->birch_model()->SetFileSuggestItems({});
     return;
diff --git a/chrome/browser/ui/ash/birch/birch_file_suggest_provider.h b/chrome/browser/ui/ash/birch/birch_file_suggest_provider.h
index bb660c39..8e5bcab 100644
--- a/chrome/browser/ui/ash/birch/birch_file_suggest_provider.h
+++ b/chrome/browser/ui/ash/birch/birch_file_suggest_provider.h
@@ -5,12 +5,13 @@
 #ifndef CHROME_BROWSER_UI_ASH_BIRCH_BIRCH_FILE_SUGGEST_PROVIDER_H_
 #define CHROME_BROWSER_UI_ASH_BIRCH_BIRCH_FILE_SUGGEST_PROVIDER_H_
 
+#include <optional>
+
 #include "ash/ash_export.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/scoped_observation.h"
 #include "chrome/browser/ash/file_suggest/file_suggest_keyed_service.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class Profile;
 
@@ -32,7 +33,7 @@
   void OnFileSuggestionUpdated(FileSuggestionType type) override;
 
   void OnSuggestedFileDataUpdated(
-      const absl::optional<std::vector<FileSuggestData>>& suggest_results);
+      const std::optional<std::vector<FileSuggestData>>& suggest_results);
 
   void set_file_suggest_service_for_test(
       FileSuggestKeyedService* suggest_service) {
diff --git a/chrome/browser/ui/download/download_bubble_security_view_info.cc b/chrome/browser/ui/download/download_bubble_security_view_info.cc
index f04cae8..3fc3fda1 100644
--- a/chrome/browser/ui/download/download_bubble_security_view_info.cc
+++ b/chrome/browser/ui/download/download_bubble_security_view_info.cc
@@ -35,7 +35,7 @@
     DownloadCommands::Command command,
     std::u16string label,
     bool is_prominent,
-    absl::optional<ui::ColorId> text_color)
+    std::optional<ui::ColorId> text_color)
     : command(command),
       label(label),
       is_prominent(is_prominent),
diff --git a/chrome/browser/ui/download/download_bubble_security_view_info.h b/chrome/browser/ui/download/download_bubble_security_view_info.h
index f97d3e6..f912e038 100644
--- a/chrome/browser/ui/download/download_bubble_security_view_info.h
+++ b/chrome/browser/ui/download/download_bubble_security_view_info.h
@@ -50,12 +50,12 @@
 
     // Controls the text color of the button. Only applied for some secondary
     // buttons.
-    absl::optional<ui::ColorId> text_color;
+    std::optional<ui::ColorId> text_color;
 
     SubpageButton(DownloadCommands::Command command,
                   std::u16string label,
                   bool is_prominent,
-                  absl::optional<ui::ColorId> text_color = absl::nullopt);
+                  std::optional<ui::ColorId> text_color = std::nullopt);
   };
 
   DownloadBubbleSecurityViewInfo();
@@ -88,7 +88,7 @@
   const gfx::VectorIcon* warning_secondary_icon() const {
     return warning_secondary_icon_;
   }
-  const absl::optional<LabelWithLink>& learn_more_link() const {
+  const std::optional<LabelWithLink>& learn_more_link() const {
     return learn_more_link_;
   }
   bool has_primary_button() const { return subpage_buttons_.size() > 0; }
@@ -169,7 +169,7 @@
 
   // Text with link to go at the bottom of the subpage summary, such as "Learn
   // why Chrome blocks some downloads".
-  absl::optional<LabelWithLink> learn_more_link_;
+  std::optional<LabelWithLink> learn_more_link_;
 
   // Subpage buttons
   std::vector<SubpageButton> subpage_buttons_;
diff --git a/chrome/browser/ui/performance_controls/tab_resource_usage_collector.cc b/chrome/browser/ui/performance_controls/tab_resource_usage_collector.cc
index 1df38aa..31621f9 100644
--- a/chrome/browser/ui/performance_controls/tab_resource_usage_collector.cc
+++ b/chrome/browser/ui/performance_controls/tab_resource_usage_collector.cc
@@ -47,7 +47,7 @@
 
 void TabResourceUsageCollector::ImmediatelyRefreshMetrics(
     content::WebContents* web_contents) {
-  absl::optional<PageContext> page_context =
+  std::optional<PageContext> page_context =
       PageContext::FromWebContents(web_contents);
   if (page_context.has_value()) {
     QueryBuilder()
diff --git a/chrome/browser/ui/safety_hub/unused_site_permissions_service.cc b/chrome/browser/ui/safety_hub/unused_site_permissions_service.cc
index e952bb9c..8411611 100644
--- a/chrome/browser/ui/safety_hub/unused_site_permissions_service.cc
+++ b/chrome/browser/ui/safety_hub/unused_site_permissions_service.cc
@@ -429,8 +429,7 @@
 void UnusedSitePermissionsService::UndoRegrantPermissionsForOrigin(
     const std::set<ContentSettingsType>& permissions,
     const base::Value::Dict& chooser_permissions_data,
-    const absl::optional<content_settings::ContentSettingConstraints>
-        constraint,
+    const std::optional<content_settings::ContentSettingConstraints> constraint,
     const url::Origin origin) {
   for (const auto& permission : permissions) {
     if (IsContentSetting(permission)) {
@@ -681,7 +680,7 @@
     // Store revoked permissions on HCSM.
     if (!revoked_permissions.empty()) {
       StorePermissionInRevokedPermissionSetting(
-          revoked_permissions, chooser_permissions_data, absl::nullopt,
+          revoked_permissions, chooser_permissions_data, std::nullopt,
           primary_pattern, secondary_pattern);
     }
 
@@ -706,8 +705,7 @@
 void UnusedSitePermissionsService::StorePermissionInRevokedPermissionSetting(
     const std::set<ContentSettingsType>& permissions,
     const base::Value::Dict& chooser_permissions_data,
-    const absl::optional<content_settings::ContentSettingConstraints>
-        constraint,
+    const std::optional<content_settings::ContentSettingConstraints> constraint,
     const url::Origin origin) {
   // The |secondary_pattern| for
   // |ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS| is always wildcard.
@@ -720,8 +718,7 @@
 void UnusedSitePermissionsService::StorePermissionInRevokedPermissionSetting(
     const std::set<ContentSettingsType>& permissions,
     const base::Value::Dict& chooser_permissions_data,
-    const absl::optional<content_settings::ContentSettingConstraints>
-        constraint,
+    const std::optional<content_settings::ContentSettingConstraints> constraint,
     const ContentSettingsPattern& primary_pattern,
     const ContentSettingsPattern& secondary_pattern) {
   GURL url = GURL(primary_pattern.ToString());
diff --git a/chrome/browser/ui/safety_hub/unused_site_permissions_service.h b/chrome/browser/ui/safety_hub/unused_site_permissions_service.h
index 1e11918..4337d11 100644
--- a/chrome/browser/ui/safety_hub/unused_site_permissions_service.h
+++ b/chrome/browser/ui/safety_hub/unused_site_permissions_service.h
@@ -178,7 +178,7 @@
   void UndoRegrantPermissionsForOrigin(
       const std::set<ContentSettingsType>& permissions,
       const base::Value::Dict& chooser_permissions_data,
-      const absl::optional<content_settings::ContentSettingConstraints>
+      const std::optional<content_settings::ContentSettingConstraints>
           constraint,
       const url::Origin origin);
 
@@ -190,7 +190,7 @@
   void StorePermissionInRevokedPermissionSetting(
       const std::set<ContentSettingsType>& permissions,
       const base::Value::Dict& chooser_permissions_data,
-      const absl::optional<content_settings::ContentSettingConstraints>
+      const std::optional<content_settings::ContentSettingConstraints>
           constraint,
       const url::Origin origin);
 
@@ -242,7 +242,7 @@
   void StorePermissionInRevokedPermissionSetting(
       const std::set<ContentSettingsType>& permissions,
       const base::Value::Dict& chooser_permissions_data,
-      const absl::optional<content_settings::ContentSettingConstraints>
+      const std::optional<content_settings::ContentSettingConstraints>
           constraint,
       const ContentSettingsPattern& primary_pattern,
       const ContentSettingsPattern& secondary_pattern);
diff --git a/chrome/browser/ui/safety_hub/unused_site_permissions_service_unittest.cc b/chrome/browser/ui/safety_hub/unused_site_permissions_service_unittest.cc
index db7dd95..c4928595 100644
--- a/chrome/browser/ui/safety_hub/unused_site_permissions_service_unittest.cc
+++ b/chrome/browser/ui/safety_hub/unused_site_permissions_service_unittest.cc
@@ -557,7 +557,7 @@
       base::Value::Dict().Set(
           base::NumberToString(static_cast<int32_t>(chooser_type)),
           base::Value::Dict().Set("foo", "bar")),
-      absl::nullopt, url::Origin::Create(GURL(url1)));
+      std::nullopt, url::Origin::Create(GURL(url1)));
 
   revoked_permissions_list = hcsm()->GetSettingsForOneType(
       ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS);
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc
index c6c9e0b1..cca5874 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc
@@ -389,10 +389,10 @@
 
   // Extensions button has left flat edge iff request access button is visible.
   // This will also update the button's background.
-  absl::optional<ToolbarButton::Edge> extensions_button_edge =
+  std::optional<ToolbarButton::Edge> extensions_button_edge =
       request_access_button_->GetVisible()
-          ? absl::optional<ToolbarButton::Edge>(ToolbarButton::Edge::kLeft)
-          : absl::nullopt;
+          ? std::optional<ToolbarButton::Edge>(ToolbarButton::Edge::kLeft)
+          : std::nullopt;
   extensions_button_->SetFlatEdge(extensions_button_edge);
 }
 
diff --git a/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc b/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc
index 1d77db9d..dd27c73 100644
--- a/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc
+++ b/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc
@@ -671,7 +671,7 @@
       id, item, BuildFooter(id, item, profile_, media_color_theme_),
       BuildDeviceSelector(id, item, service_, service_, profile_, entry_point_,
                           show_devices, media_color_theme_),
-      /*notification_theme=*/absl::nullopt, media_color_theme_,
+      /*notification_theme=*/std::nullopt, media_color_theme_,
       global_media_controls::MediaDisplayPage::kMediaDialogView);
 }
 
diff --git a/chrome/browser/ui/views/permissions/permission_prompt_notifications_mac.cc b/chrome/browser/ui/views/permissions/permission_prompt_notifications_mac.cc
index 324e3b1..15358213 100644
--- a/chrome/browser/ui/views/permissions/permission_prompt_notifications_mac.cc
+++ b/chrome/browser/ui/views/permissions/permission_prompt_notifications_mac.cc
@@ -66,7 +66,7 @@
 
 std::optional<gfx::Rect>
 PermissionPromptNotificationsMac::GetViewBoundsInScreen() const {
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool PermissionPromptNotificationsMac::ShouldFinalizeRequestAfterDecided()
diff --git a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc
index f7ad7c29..b6b7d494 100644
--- a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc
+++ b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc
@@ -1757,7 +1757,7 @@
       LoadWholeAppIsDraggableTestPageWithDataAndGetURL()));
   content::WaitForLoadStop(helper()->browser_view()->GetActiveWebContents());
 
-  absl::optional<SkRegion> draggable_region =
+  std::optional<SkRegion> draggable_region =
       helper()->browser_view()->browser()->app_controller()->draggable_region();
 
   EXPECT_TRUE(draggable_region.has_value());
diff --git a/chrome/browser/ui/views/webid/account_selection_modal_view.cc b/chrome/browser/ui/views/webid/account_selection_modal_view.cc
index 0417430..c879ef7c 100644
--- a/chrome/browser/ui/views/webid/account_selection_modal_view.cc
+++ b/chrome/browser/ui/views/webid/account_selection_modal_view.cc
@@ -74,7 +74,7 @@
   SetButtonLabel(ui::DIALOG_BUTTON_CANCEL,
                  l10n_util::GetStringUTF16(IDS_ACCOUNT_SELECTION_CANCEL));
 
-  title_ = GetTitle(top_frame_for_display, /*iframe_for_display=*/absl::nullopt,
+  title_ = GetTitle(top_frame_for_display, /*iframe_for_display=*/std::nullopt,
                     idp_title, rp_context);
   SetAccessibleTitle(title_);
 }
diff --git a/chrome/browser/ui/views/webid/account_selection_modal_view_browsertest.cc b/chrome/browser/ui/views/webid/account_selection_modal_view_browsertest.cc
index 8998f883..9bb4d2a 100644
--- a/chrome/browser/ui/views/webid/account_selection_modal_view_browsertest.cc
+++ b/chrome/browser/ui/views/webid/account_selection_modal_view_browsertest.cc
@@ -111,7 +111,7 @@
         CreateTestClientMetadata(terms_of_service_url), {account},
         /*request_permission=*/true, /*has_login_status_mismatch=*/false);
     dialog_->ShowSingleAccountConfirmDialog(
-        kTopFrameETLDPlusOne, /*iframe_for_display=*/absl::nullopt, account,
+        kTopFrameETLDPlusOne, /*iframe_for_display=*/std::nullopt, account,
         idp_data, show_back_button);
   }
 
diff --git a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
index 0f869e7e..acda48e 100644
--- a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
+++ b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
@@ -339,7 +339,7 @@
       ui_manager->CreateBlockingPage(
           web_contents, main_frame_url, {resource},
           /*forward_extension_event=*/false,
-          /*blocked_page_shown_timestamp=*/absl::nullopt));
+          /*blocked_page_shown_timestamp=*/std::nullopt));
 }
 
 std::unique_ptr<EnterpriseBlockPage> CreateEnterpriseBlockPage(
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chrome/browser/ui/webui/settings/site_settings_handler.cc
index 089db60..a80f9f19 100644
--- a/chrome/browser/ui/webui/settings/site_settings_handler.cc
+++ b/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -1168,7 +1168,7 @@
 
   // The group key should always be an eTLD+1 because there aren't any
   // partitioned entries for IWAs (which have a non-eTLD+1 grouping key).
-  absl::optional<std::string> group_etld_plus1 = grouping_key.GetEtldPlusOne();
+  std::optional<std::string> group_etld_plus1 = grouping_key.GetEtldPlusOne();
   DCHECK(group_etld_plus1);
 
   net::SchemefulSite https_top_level_site(
@@ -2331,8 +2331,8 @@
       if (!cookie) {
         continue;
       }
-      absl::optional<std::string> partition_etld_plus1 = absl::nullopt;
-      absl::optional<GroupingKey> partition_grouping_key = absl::nullopt;
+      std::optional<std::string> partition_etld_plus1 = std::nullopt;
+      std::optional<GroupingKey> partition_grouping_key = std::nullopt;
       if (cookie->IsPartitioned()) {
         partition_etld_plus1 = cookie->PartitionKey()->site().GetURL().host();
         partition_grouping_key =
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
index 40d7f65..985dc42 100644
--- a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
@@ -269,10 +269,10 @@
 std::unique_ptr<net::CanonicalCookie> CreateCookieKey(
     const GURL& url,
     const std::string& cookie_line,
-    absl::optional<net::CookiePartitionKey> cookie_partition_key =
-        absl::nullopt) {
+    std::optional<net::CookiePartitionKey> cookie_partition_key =
+        std::nullopt) {
   return net::CanonicalCookie::Create(url, cookie_line, base::Time::Now(),
-                                      absl::nullopt /* server_time */,
+                                      std::nullopt /* server_time */,
                                       cookie_partition_key);
 }
 
diff --git a/chrome/browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_handler.cc b/chrome/browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_handler.cc
index 5dc42ca..1c5be09 100644
--- a/chrome/browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_handler.cc
+++ b/chrome/browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_handler.cc
@@ -232,7 +232,7 @@
 
 void WallpaperSearchHandler::GetInspirations(GetInspirationsCallback callback) {
   callback = mojo::WrapCallbackWithDefaultInvokeIfNotRun(std::move(callback),
-                                                         absl::nullopt);
+                                                         std::nullopt);
 
   net::NetworkTrafficAnnotationTag traffic_annotation =
       net::DefineNetworkTrafficAnnotation(
@@ -757,7 +757,7 @@
     // Network errors (i.e. the server did not provide a response).
     DVLOG(1) << "Request failed with error: "
              << inspirations_simple_url_loader_->NetError();
-    std::move(callback).Run(absl::nullopt);
+    std::move(callback).Run(std::nullopt);
     return;
   }
 
@@ -780,7 +780,7 @@
     data_decoder::DataDecoder::ValueOrError result) {
   if (!result.has_value() || !result->is_list()) {
     DVLOG(1) << "Parsing JSON failed: " << result.error();
-    std::move(callback).Run(absl::nullopt);
+    std::move(callback).Run(std::nullopt);
     return;
   }
   std::vector<side_panel::customize_chrome::mojom::InspirationGroupPtr>
@@ -834,7 +834,7 @@
       if (!background_image || !thumbnail_image || !description || !id_string) {
         continue;
       }
-      const absl::optional<base::Token> id_token =
+      const std::optional<base::Token> id_token =
           base::Token::FromString(*id_string);
       if (!id_token.has_value()) {
         continue;
@@ -857,7 +857,7 @@
   if (mojo_inspiration_groups.size() > 0) {
     std::move(callback).Run(std::move(mojo_inspiration_groups));
   } else {
-    std::move(callback).Run(absl::nullopt);
+    std::move(callback).Run(std::nullopt);
   }
 }
 
diff --git a/chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_policy_manager_unittest.cc b/chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_policy_manager_unittest.cc
index e4daec1..b0cd7e9 100644
--- a/chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_policy_manager_unittest.cc
+++ b/chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_policy_manager_unittest.cc
@@ -410,8 +410,8 @@
       test_managed_guest_session_;
   data_decoder::test::InProcessDataDecoder data_decoder_;
 
-  absl::optional<web_package::SignedWebBundleId> lazy_app1_id_;
-  absl::optional<web_package::SignedWebBundleId> lazy_app2_id_;
+  std::optional<web_package::SignedWebBundleId> lazy_app1_id_;
+  std::optional<web_package::SignedWebBundleId> lazy_app2_id_;
 };
 
 class IsolatedWebAppPolicyManagerTest
@@ -464,7 +464,7 @@
 
  private:
   InstallIsolatedWebAppCallback stashed_callback_;
-  absl::optional<web_package::SignedWebBundleId> id_;
+  std::optional<web_package::SignedWebBundleId> id_;
 };
 
 template <typename T>
diff --git a/chrome/browser/web_applications/web_app_sync_bridge.cc b/chrome/browser/web_applications/web_app_sync_bridge.cc
index e6e1add..ee10252 100644
--- a/chrome/browser/web_applications/web_app_sync_bridge.cc
+++ b/chrome/browser/web_applications/web_app_sync_bridge.cc
@@ -127,7 +127,7 @@
 // Get the UserDisplayMode for the app on the current platform (may be absent
 // for not-yet-migrated apps loaded from the database). Use
 // `WebApp::user_display_mode` instead for migrated apps.
-absl::optional<mojom::UserDisplayMode> GetCurrentPlatformUserDisplayMode(
+std::optional<mojom::UserDisplayMode> GetCurrentPlatformUserDisplayMode(
     const WebApp& app) {
 #if BUILDFLAG(IS_CHROMEOS)
   return app.user_display_mode_cros();
diff --git a/chrome/browser/web_applications/web_app_sync_bridge_unittest.cc b/chrome/browser/web_applications/web_app_sync_bridge_unittest.cc
index 3c8ae028..aafe4fd 100644
--- a/chrome/browser/web_applications/web_app_sync_bridge_unittest.cc
+++ b/chrome/browser/web_applications/web_app_sync_bridge_unittest.cc
@@ -1537,7 +1537,7 @@
 TEST_P(WebAppSyncBridgeTest_UserDisplayModeSplit, SyncUpdateToUserDisplayMode) {
   GURL start_url = GURL("https://example.com/app");
   webapps::AppId app_id =
-      GenerateAppId(/*manifest_id_path=*/absl::nullopt, start_url);
+      GenerateAppId(/*manifest_id_path=*/std::nullopt, start_url);
 
   // Install an app.
   if (installed_before_sync()) {
diff --git a/chrome/browser/web_applications/web_app_utils.cc b/chrome/browser/web_applications/web_app_utils.cc
index ba8d301..9726553 100644
--- a/chrome/browser/web_applications/web_app_utils.cc
+++ b/chrome/browser/web_applications/web_app_utils.cc
@@ -283,7 +283,7 @@
     mojom::UserDisplayMode user_display_mode,
     bool is_shortcut_app,
     bool ignore_shortstand) {
-  const absl::optional<DisplayMode> resolved_display_mode =
+  const std::optional<DisplayMode> resolved_display_mode =
       ShouldResolveShortstandDisplayMode(ignore_shortstand)
           ? TryResolveShortstandUserDisplayMode(is_shortcut_app)
           : TryResolveUserDisplayMode(user_display_mode);
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
index 9cd7c2f6..865d88e 100644
--- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
+++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
@@ -1411,7 +1411,7 @@
       CHECK(entity);
 
       if (entity->key_version()) {
-        absl::optional<std::vector<uint8_t>> wrapped_secret =
+        std::optional<std::vector<uint8_t>> wrapped_secret =
             enclave_manager_->GetWrappedSecret(entity->key_version());
         if (wrapped_secret) {
           request->wrapped_secrets.emplace_back(std::move(*wrapped_secret));
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.h b/chrome/browser/webauthn/chrome_authenticator_request_delegate.h
index 5f736b4..0a925984 100644
--- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.h
+++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.h
@@ -389,14 +389,14 @@
   std::unique_ptr<device::FidoRequestHandlerBase::TransportAvailabilityInfo>
       pending_transport_availability_info_;
 
-  absl::optional<device::FidoRequestType> request_type_;
+  std::optional<device::FidoRequestType> request_type_;
 
   std::optional<device::UserVerificationRequirement>
       user_verification_requirement_;
 
   // The set of pertinent synced passkeys for this request. Persisted here
   // so that a consistent set of passkeys is used throughout the transaction.
-  absl::optional<std::vector<sync_pb::WebauthnCredentialSpecifics>>
+  std::optional<std::vector<sync_pb::WebauthnCredentialSpecifics>>
       gpm_credentials_;
 
   // The pending request to fetch the state of the trusted vault.
diff --git a/chrome/browser/webauthn/enclave_manager.cc b/chrome/browser/webauthn/enclave_manager.cc
index a096c5e..9365a601 100644
--- a/chrome/browser/webauthn/enclave_manager.cc
+++ b/chrome/browser/webauthn/enclave_manager.cc
@@ -135,7 +135,7 @@
     return __LINE__;
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 // Build an enclave request that registers a new device and requests a new
@@ -609,7 +609,7 @@
   CHECK(is_ready());
   const auto it = user_->wrapped_security_domain_secrets().find(version);
   if (it == user_->wrapped_security_domain_secrets().end()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return ToVector(it->second);
 }
@@ -1305,7 +1305,7 @@
       *primary_account_info_, store_keys_args_for_joining_->keys,
       store_keys_args_for_joining_->last_key_version, *secure_box_pub_key,
       trusted_vault::AuthenticationFactorType::kPhysicalDevice,
-      /*authentication_factor_type_hint=*/absl::nullopt,
+      /*authentication_factor_type_hint=*/std::nullopt,
       base::BindOnce(
           [](base::WeakPtr<EnclaveManager> client,
              trusted_vault::TrustedVaultRegistrationStatus status) {
diff --git a/chrome/services/sharing/nearby/test_support/mock_webrtc_dependencies.h b/chrome/services/sharing/nearby/test_support/mock_webrtc_dependencies.h
index 886636e..140c89e 100644
--- a/chrome/services/sharing/nearby/test_support/mock_webrtc_dependencies.h
+++ b/chrome/services/sharing/nearby/test_support/mock_webrtc_dependencies.h
@@ -55,7 +55,7 @@
        const network::P2PPortRange& port_range,
        const network::P2PHostAndIPEndPoint& remote_address,
        const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
-       const absl::optional<base::UnguessableToken>& devtools_token,
+       const std::optional<base::UnguessableToken>& devtools_token,
        mojo::PendingRemote<network::mojom::P2PSocketClient> client,
        mojo::PendingReceiver<network::mojom::P2PSocket> receiver),
       (override));
diff --git a/chrome/services/sharing/webrtc/p2p_socket_client.cc b/chrome/services/sharing/webrtc/p2p_socket_client.cc
index 8de60ed..b0f78b0 100644
--- a/chrome/services/sharing/webrtc/p2p_socket_client.cc
+++ b/chrome/services/sharing/webrtc/p2p_socket_client.cc
@@ -59,7 +59,7 @@
       type, local_address, network::P2PPortRange(min_port, max_port),
       remote_address,
       net::MutableNetworkTrafficAnnotationTag(traffic_annotation_),
-      /*devtools_token=*/absl::nullopt, receiver_.BindNewPipeAndPassRemote(),
+      /*devtools_token=*/std::nullopt, receiver_.BindNewPipeAndPassRemote(),
       socket_.BindNewPipeAndPassReceiver());
   receiver_.set_disconnect_handler(base::BindOnce(
       &P2PSocketClient::OnConnectionError, base::Unretained(this)));
diff --git a/chrome/test/base/chromeos/crosier/chromeos_integration_arc_mixin.h b/chrome/test/base/chromeos/crosier/chromeos_integration_arc_mixin.h
index eb1e1b3..745e8bb 100644
--- a/chrome/test/base/chromeos/crosier/chromeos_integration_arc_mixin.h
+++ b/chrome/test/base/chromeos/crosier/chromeos_integration_arc_mixin.h
@@ -5,12 +5,12 @@
 #ifndef CHROME_TEST_BASE_CHROMEOS_CROSIER_CHROMEOS_INTEGRATION_ARC_MIXIN_H_
 #define CHROME_TEST_BASE_CHROMEOS_CROSIER_CHROMEOS_INTEGRATION_ARC_MIXIN_H_
 
+#include <optional>
 #include <string>
 
 #include "base/test/scoped_feature_list.h"
 #include "chrome/test/base/chromeos/crosier/adb_helper.h"
 #include "chrome/test/base/mixin_based_in_process_browser_test.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace aura {
 class Window;
@@ -68,7 +68,7 @@
 
   bool setup_called_ = false;
   Mode mode_ = Mode::kNone;
-  absl::optional<base::test::ScopedFeatureList> scoped_feature_list_;
+  std::optional<base::test::ScopedFeatureList> scoped_feature_list_;
 
   AdbHelper adb_helper_;
 };
diff --git a/chrome/test/chromedriver/fedcm_commands.cc b/chrome/test/chromedriver/fedcm_commands.cc
index 578d4710..57f9c05d 100644
--- a/chrome/test/chromedriver/fedcm_commands.cc
+++ b/chrome/test/chromedriver/fedcm_commands.cc
@@ -84,7 +84,7 @@
 
   std::string button = *params.FindString("dialogButton");
   if (button == "TermsOfService" || button == "PrivacyPolicy") {
-    absl::optional<int> index = params.FindInt("index");
+    std::optional<int> index = params.FindInt("index");
     if (!index) {
       return Status(kInvalidArgument, "index must be specified");
     }
diff --git a/chrome/test/supervised_user/test_state_seeded_observer.h b/chrome/test/supervised_user/test_state_seeded_observer.h
index 5fe9887..8e68801 100644
--- a/chrome/test/supervised_user/test_state_seeded_observer.h
+++ b/chrome/test/supervised_user/test_state_seeded_observer.h
@@ -6,6 +6,7 @@
 #define CHROME_TEST_SUPERVISED_USER_TEST_STATE_SEEDED_OBSERVER_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "base/functional/callback_forward.h"
@@ -15,7 +16,6 @@
 #include "components/supervised_user/core/browser/proto_fetcher.h"
 #include "components/supervised_user/core/browser/supervised_user_service_observer.h"
 #include "components/supervised_user/core/browser/supervised_user_url_filter.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/interaction/state_observer.h"
 
 namespace supervised_user {
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc
index d62a582b..d08e3b9 100644
--- a/chromecast/browser/cast_content_browser_client.cc
+++ b/chromecast/browser/cast_content_browser_client.cc
@@ -890,7 +890,7 @@
     const base::RepeatingCallback<content::WebContents*()>& wc_getter,
     content::NavigationUIData* navigation_ui_data,
     int frame_tree_node_id,
-    absl::optional<int64_t> navigation_id) {
+    std::optional<int64_t> navigation_id) {
   std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles;
   if (frame_tree_node_id == content::RenderFrameHost::kNoFrameTreeNodeId) {
     // No support for service workers.
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h
index 318ec21e..454758e 100644
--- a/chromecast/browser/cast_content_browser_client.h
+++ b/chromecast/browser/cast_content_browser_client.h
@@ -270,7 +270,7 @@
       const base::RepeatingCallback<content::WebContents*()>& wc_getter,
       content::NavigationUIData* navigation_ui_data,
       int frame_tree_node_id,
-      absl::optional<int64_t> navigation_id) override;
+      std::optional<int64_t> navigation_id) override;
 
   CastFeatureListCreator* GetCastFeatureListCreator() {
     return cast_feature_list_creator_;
diff --git a/chromecast/cast_core/runtime/browser/cast_runtime_content_browser_client.cc b/chromecast/cast_core/runtime/browser/cast_runtime_content_browser_client.cc
index 43d1067..bac130da 100644
--- a/chromecast/cast_core/runtime/browser/cast_runtime_content_browser_client.cc
+++ b/chromecast/cast_core/runtime/browser/cast_runtime_content_browser_client.cc
@@ -121,7 +121,7 @@
     const base::RepeatingCallback<content::WebContents*()>& wc_getter,
     content::NavigationUIData* navigation_ui_data,
     int frame_tree_node_id,
-    absl::optional<int64_t> navigation_id) {
+    std::optional<int64_t> navigation_id) {
   return cast_browser_client_mixins_->CreateURLLoaderThrottles(
       std::move(wc_getter), frame_tree_node_id,
       base::BindRepeating(&IsCorsExemptHeader));
diff --git a/chromecast/cast_core/runtime/browser/cast_runtime_content_browser_client.h b/chromecast/cast_core/runtime/browser/cast_runtime_content_browser_client.h
index d438684..3dd4ddc 100644
--- a/chromecast/cast_core/runtime/browser/cast_runtime_content_browser_client.h
+++ b/chromecast/cast_core/runtime/browser/cast_runtime_content_browser_client.h
@@ -56,7 +56,7 @@
       const base::RepeatingCallback<content::WebContents*()>& wc_getter,
       content::NavigationUIData* navigation_ui_data,
       int frame_tree_node_id,
-      absl::optional<int64_t> navigation_id) override;
+      std::optional<int64_t> navigation_id) override;
 
  protected:
   void InitializeCoreComponents(CastWebService* web_service);
diff --git a/chromeos/ash/components/emoji/emoji_search.cc b/chromeos/ash/components/emoji/emoji_search.cc
index 6d7187d..a38b0a49 100644
--- a/chromeos/ash/components/emoji/emoji_search.cc
+++ b/chromeos/ash/components/emoji/emoji_search.cc
@@ -70,7 +70,7 @@
   }
 
   // TODO(b/309343774): switch to JSON reading service
-  absl::optional<base::Value> json = base::JSONReader::Read(json_string);
+  std::optional<base::Value> json = base::JSONReader::Read(json_string);
   CHECK(json) << "parse failed for " << file_id_in_resources << ":"
               << json_string << "EOF";
   base::Value::List groups = std::move(*json).TakeList();
diff --git a/chromeos/ash/components/network/metrics/default_network_metrics_logger.cc b/chromeos/ash/components/network/metrics/default_network_metrics_logger.cc
index f6f0a993..7dea8b83 100644
--- a/chromeos/ash/components/network/metrics/default_network_metrics_logger.cc
+++ b/chromeos/ash/components/network/metrics/default_network_metrics_logger.cc
@@ -69,7 +69,7 @@
 DefaultNetworkMetricsLogger::GetNetworkTechnologyMeterSubtype(
     const NetworkState* network) {
   if (!network) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   switch (network->GetNetworkTechnologyType()) {
@@ -92,7 +92,7 @@
     case NetworkState::NetworkTechnologyType::kUnknown:
       [[fallthrough]];
     default:
-      return absl::nullopt;
+      return std::nullopt;
   }
 }
 
diff --git a/chromeos/ash/components/tether/wifi_hotspot_connector.cc b/chromeos/ash/components/tether/wifi_hotspot_connector.cc
index 8f0633c..76b180d 100644
--- a/chromeos/ash/components/tether/wifi_hotspot_connector.cc
+++ b/chromeos/ash/components/tether/wifi_hotspot_connector.cc
@@ -253,7 +253,7 @@
 // TODO(b/318534727): Record the number of attempts before completion in a
 // metric.
 void WifiHotspotConnector::CompleteActiveConnectionAttempt(
-    absl::optional<WifiHotspotConnectionError> error) {
+    std::optional<WifiHotspotConnectionError> error) {
   if (wifi_network_guid_.empty()) {
     PA_LOG(ERROR) << "CompleteActiveConnectionAttempt"
                   << "was called, but no connection attempt is in progress.";
diff --git a/chromeos/ash/components/tether/wifi_hotspot_connector.h b/chromeos/ash/components/tether/wifi_hotspot_connector.h
index d5edc74..f14b16b 100644
--- a/chromeos/ash/components/tether/wifi_hotspot_connector.h
+++ b/chromeos/ash/components/tether/wifi_hotspot_connector.h
@@ -79,7 +79,7 @@
   void UpdateWaitingForWifi();
   void InitiateConnectionToCurrentNetwork();
   void CompleteActiveConnectionAttempt(
-      absl::optional<WifiHotspotConnectionError> error);
+      std::optional<WifiHotspotConnectionError> error);
   void CreateWifiConfiguration();
   void RequestWifiScan();
   base::Value::Dict CreateWifiPropertyDictionary(const std::string& ssid,
diff --git a/chromeos/ash/services/network_config/cros_network_config_unittest.cc b/chromeos/ash/services/network_config/cros_network_config_unittest.cc
index 13317a4b..9fd7558 100644
--- a/chromeos/ash/services/network_config/cros_network_config_unittest.cc
+++ b/chromeos/ash/services/network_config/cros_network_config_unittest.cc
@@ -1712,7 +1712,7 @@
   // Any attempt to unlock carrier locked sim with the pin should fail and
   // should not change the carrier lock status.
   EXPECT_FALSE(SetCellularSimState(FakeShillDeviceClient::kDefaultSimPin,
-                                   /*new_pin=*/absl::nullopt,
+                                   /*new_pin=*/std::nullopt,
                                    /*require_pin=*/false));
 
   // Sim should continue to be carrier locked.
diff --git a/chromeos/ash/services/secure_channel/ble_scanner.cc b/chromeos/ash/services/secure_channel/ble_scanner.cc
index 14f242db..c4d0a8c3 100644
--- a/chromeos/ash/services/secure_channel/ble_scanner.cc
+++ b/chromeos/ash/services/secure_channel/ble_scanner.cc
@@ -76,7 +76,7 @@
 void BleScanner::NotifyBleDiscoverySessionFailed(
     const DeviceIdPair& device_id_pair,
     mojom::DiscoveryResult discovery_result,
-    absl::optional<mojom::DiscoveryErrorCode> error_code) {
+    std::optional<mojom::DiscoveryErrorCode> error_code) {
   for (auto& observer : observer_list_) {
     observer.OnDiscoveryFailed(device_id_pair, discovery_result, error_code);
   }
diff --git a/chromeos/ash/services/secure_channel/client_connection_parameters.cc b/chromeos/ash/services/secure_channel/client_connection_parameters.cc
index 9f3ed4c..69bba3f 100644
--- a/chromeos/ash/services/secure_channel/client_connection_parameters.cc
+++ b/chromeos/ash/services/secure_channel/client_connection_parameters.cc
@@ -52,7 +52,7 @@
 
 void ClientConnectionParameters::SetBleDiscoveryState(
     mojom::DiscoveryResult discovery_result,
-    absl::optional<mojom::DiscoveryErrorCode> potential_error_code) {
+    std::optional<mojom::DiscoveryErrorCode> potential_error_code) {
   UpdateBleDiscoveryState(discovery_result, potential_error_code);
 }
 
diff --git a/chromeos/ash/services/secure_channel/client_connection_parameters.h b/chromeos/ash/services/secure_channel/client_connection_parameters.h
index 0c7e59a..34adc51a 100644
--- a/chromeos/ash/services/secure_channel/client_connection_parameters.h
+++ b/chromeos/ash/services/secure_channel/client_connection_parameters.h
@@ -66,7 +66,7 @@
 
   void SetBleDiscoveryState(
       mojom::DiscoveryResult discovery_state,
-      absl::optional<mojom::DiscoveryErrorCode> potential_error_code);
+      std::optional<mojom::DiscoveryErrorCode> potential_error_code);
   void SetNearbyConnectionState(mojom::NearbyConnectionStep step,
                                 mojom::NearbyConnectionStepResult result);
   void SetSecureChannelAuthenticationState(
@@ -86,7 +86,7 @@
           nearby_connection_state_listener_receiver) = 0;
   virtual void UpdateBleDiscoveryState(
       mojom::DiscoveryResult discovery_result,
-      absl::optional<mojom::DiscoveryErrorCode> potential_error_code) = 0;
+      std::optional<mojom::DiscoveryErrorCode> potential_error_code) = 0;
   virtual void UpdateNearbyConnectionState(
       mojom::NearbyConnectionStep step,
       mojom::NearbyConnectionStepResult result) = 0;
diff --git a/chromeos/ash/services/secure_channel/client_connection_parameters_impl.cc b/chromeos/ash/services/secure_channel/client_connection_parameters_impl.cc
index 935fa86..def15c431 100644
--- a/chromeos/ash/services/secure_channel/client_connection_parameters_impl.cc
+++ b/chromeos/ash/services/secure_channel/client_connection_parameters_impl.cc
@@ -83,7 +83,7 @@
 
 void ClientConnectionParametersImpl::UpdateBleDiscoveryState(
     mojom::DiscoveryResult discovery_state,
-    absl::optional<mojom::DiscoveryErrorCode> potential_error_code) {
+    std::optional<mojom::DiscoveryErrorCode> potential_error_code) {
   secure_channel_structured_metrics_logger_remote_->LogDiscoveryAttempt(
       discovery_state, potential_error_code);
 }
diff --git a/chromeos/ash/services/secure_channel/client_connection_parameters_impl.h b/chromeos/ash/services/secure_channel/client_connection_parameters_impl.h
index 432ad361..6695619 100644
--- a/chromeos/ash/services/secure_channel/client_connection_parameters_impl.h
+++ b/chromeos/ash/services/secure_channel/client_connection_parameters_impl.h
@@ -68,7 +68,7 @@
           nearby_connection_state_listener_receiver) override;
   void UpdateBleDiscoveryState(
       mojom::DiscoveryResult discovery_state,
-      absl::optional<mojom::DiscoveryErrorCode> potential_error_code) override;
+      std::optional<mojom::DiscoveryErrorCode> potential_error_code) override;
   void UpdateNearbyConnectionState(
       mojom::NearbyConnectionStep step,
       mojom::NearbyConnectionStepResult result) override;
diff --git a/chromeos/ash/services/secure_channel/fake_client_connection_parameters.cc b/chromeos/ash/services/secure_channel/fake_client_connection_parameters.cc
index 9a41e53..006ac42e 100644
--- a/chromeos/ash/services/secure_channel/fake_client_connection_parameters.cc
+++ b/chromeos/ash/services/secure_channel/fake_client_connection_parameters.cc
@@ -60,7 +60,7 @@
 
 void FakeClientConnectionParameters::UpdateBleDiscoveryState(
     mojom::DiscoveryResult discovery_result,
-    absl::optional<mojom::DiscoveryErrorCode> potential_error_code) {
+    std::optional<mojom::DiscoveryErrorCode> potential_error_code) {
   ble_discovery_result_ = discovery_result;
   potential_ble_discovery_error_code_ = potential_error_code;
 }
diff --git a/chromeos/ash/services/secure_channel/fake_client_connection_parameters.h b/chromeos/ash/services/secure_channel/fake_client_connection_parameters.h
index 98b4fda..e1fb514d 100644
--- a/chromeos/ash/services/secure_channel/fake_client_connection_parameters.h
+++ b/chromeos/ash/services/secure_channel/fake_client_connection_parameters.h
@@ -73,7 +73,7 @@
 
   void UpdateBleDiscoveryState(
       mojom::DiscoveryResult discovery_result,
-      absl::optional<mojom::DiscoveryErrorCode> potential_error_code) override;
+      std::optional<mojom::DiscoveryErrorCode> potential_error_code) override;
   void UpdateNearbyConnectionState(
       mojom::NearbyConnectionStep nearby_connection_step,
       mojom::NearbyConnectionStepResult result) override;
@@ -96,7 +96,7 @@
   std::optional<mojom::ConnectionAttemptFailureReason> failure_reason_;
 
   mojom::DiscoveryResult ble_discovery_result_;
-  absl::optional<mojom::DiscoveryErrorCode> potential_ble_discovery_error_code_;
+  std::optional<mojom::DiscoveryErrorCode> potential_ble_discovery_error_code_;
   mojom::NearbyConnectionStep nearby_connection_step_;
   mojom::NearbyConnectionStepResult nearby_connection_step_result_;
   mojom::SecureChannelState secure_channel_state_;
diff --git a/chromeos/ash/services/secure_channel/nearby_connection_manager.cc b/chromeos/ash/services/secure_channel/nearby_connection_manager.cc
index f2c93ae..e79a72b 100644
--- a/chromeos/ash/services/secure_channel/nearby_connection_manager.cc
+++ b/chromeos/ash/services/secure_channel/nearby_connection_manager.cc
@@ -126,7 +126,7 @@
 void NearbyConnectionManager::NotifyBleDiscoveryStateChanged(
     const DeviceIdPair& device_id_pair,
     mojom::DiscoveryResult discovery_result,
-    absl::optional<mojom::DiscoveryErrorCode> potential_error_code) {
+    std::optional<mojom::DiscoveryErrorCode> potential_error_code) {
   if (id_pair_to_initiator_metadata_map_.contains(device_id_pair)) {
     GetInitiatorEntry(device_id_pair)
         .ble_discovery_state_change_callback.Run(discovery_result,
diff --git a/chromeos/ash/services/secure_channel/nearby_connection_manager.h b/chromeos/ash/services/secure_channel/nearby_connection_manager.h
index 9c7621e..335ff18 100644
--- a/chromeos/ash/services/secure_channel/nearby_connection_manager.h
+++ b/chromeos/ash/services/secure_channel/nearby_connection_manager.h
@@ -18,7 +18,6 @@
 #include "chromeos/ash/services/secure_channel/public/mojom/secure_channel.mojom-shared.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace ash::secure_channel {
 
@@ -38,7 +37,7 @@
 
   using BleDiscoveryStateChangeCallback =
       base::RepeatingCallback<void(mojom::DiscoveryResult,
-                                   absl::optional<mojom::DiscoveryErrorCode>)>;
+                                   std::optional<mojom::DiscoveryErrorCode>)>;
   using NearbyConnectionStateChangeCallback =
       base::RepeatingCallback<void(mojom::NearbyConnectionStep,
                                    mojom::NearbyConnectionStepResult)>;
@@ -89,7 +88,7 @@
   void NotifyBleDiscoveryStateChanged(
       const DeviceIdPair& device_id_pair,
       mojom::DiscoveryResult discovery_result,
-      absl::optional<mojom::DiscoveryErrorCode> potential_error_code);
+      std::optional<mojom::DiscoveryErrorCode> potential_error_code);
   void NotifyNearbyConnectionStateChanged(
       const DeviceIdPair& device_id_pair,
       mojom::NearbyConnectionStep step,
diff --git a/chromeos/ash/services/secure_channel/nearby_connection_manager_impl.cc b/chromeos/ash/services/secure_channel/nearby_connection_manager_impl.cc
index f254845..154ab082 100644
--- a/chromeos/ash/services/secure_channel/nearby_connection_manager_impl.cc
+++ b/chromeos/ash/services/secure_channel/nearby_connection_manager_impl.cc
@@ -4,6 +4,8 @@
 
 #include "chromeos/ash/services/secure_channel/nearby_connection_manager_impl.h"
 
+#include <optional>
+
 #include "base/containers/contains.h"
 #include "base/memory/ptr_util.h"
 #include "chromeos/ash/components/multidevice/logging/logging.h"
@@ -13,7 +15,6 @@
 #include "chromeos/ash/services/secure_channel/public/mojom/secure_channel.mojom-shared.h"
 #include "chromeos/ash/services/secure_channel/public/mojom/secure_channel.mojom.h"
 #include "chromeos/ash/services/secure_channel/secure_channel_disconnector.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace ash::secure_channel {
 
@@ -100,7 +101,7 @@
 
   NotifyBleDiscoveryStateChanged(
       ChooseChannelRecipient(remote_device.GetDeviceId()),
-      mojom::DiscoveryResult::kSuccess, absl::nullopt);
+      mojom::DiscoveryResult::kSuccess, std::nullopt);
   SetAuthenticatingChannel(
       remote_device.GetDeviceId(),
       SecureChannel::Factory::Create(std::move(connection)));
@@ -109,7 +110,7 @@
 void NearbyConnectionManagerImpl::OnDiscoveryFailed(
     const DeviceIdPair& device_id_pair,
     mojom::DiscoveryResult discovery_result,
-    absl::optional<mojom::DiscoveryErrorCode> potential_error_code) {
+    std::optional<mojom::DiscoveryErrorCode> potential_error_code) {
   NotifyBleDiscoveryStateChanged(device_id_pair, discovery_result,
                                  potential_error_code);
 }
diff --git a/chromeos/ash/services/secure_channel/nearby_connection_manager_impl_unittest.cc b/chromeos/ash/services/secure_channel/nearby_connection_manager_impl_unittest.cc
index 8465cc3..f02e214 100644
--- a/chromeos/ash/services/secure_channel/nearby_connection_manager_impl_unittest.cc
+++ b/chromeos/ash/services/secure_channel/nearby_connection_manager_impl_unittest.cc
@@ -5,6 +5,7 @@
 #include "chromeos/ash/services/secure_channel/nearby_connection_manager_impl.h"
 
 #include <memory>
+#include <optional>
 
 #include "base/functional/bind.h"
 #include "base/memory/raw_ptr.h"
@@ -22,7 +23,6 @@
 #include "chromeos/ash/services/secure_channel/public/mojom/secure_channel.mojom-shared.h"
 #include "chromeos/ash/services/secure_channel/secure_channel.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace ash::secure_channel {
 
@@ -367,7 +367,7 @@
   void OnBleDiscoveryStateChanged(
       const DeviceIdPair& device_id_pair,
       mojom::DiscoveryResult result,
-      absl::optional<mojom::DiscoveryErrorCode> error_code) {
+      std::optional<mojom::DiscoveryErrorCode> error_code) {
     device_discovery_results_[device_id_pair] = result;
   }
 
diff --git a/chromeos/ash/services/secure_channel/nearby_initiator_operation.cc b/chromeos/ash/services/secure_channel/nearby_initiator_operation.cc
index c87d4ef..fac1645 100644
--- a/chromeos/ash/services/secure_channel/nearby_initiator_operation.cc
+++ b/chromeos/ash/services/secure_channel/nearby_initiator_operation.cc
@@ -165,7 +165,7 @@
 
 void NearbyInitiatorOperation::OnBleDiscoveryStateChanged(
     mojom::DiscoveryResult discovery_result,
-    absl::optional<mojom::DiscoveryErrorCode> potential_error_code) {
+    std::optional<mojom::DiscoveryErrorCode> potential_error_code) {
   ble_discovery_state_changed_callback_.Run(discovery_result,
                                             potential_error_code);
 }
diff --git a/chromeos/ash/services/secure_channel/nearby_initiator_operation.h b/chromeos/ash/services/secure_channel/nearby_initiator_operation.h
index 36a77286..ec13ef3d 100644
--- a/chromeos/ash/services/secure_channel/nearby_initiator_operation.h
+++ b/chromeos/ash/services/secure_channel/nearby_initiator_operation.h
@@ -6,6 +6,7 @@
 #define CHROMEOS_ASH_SERVICES_SECURE_CHANNEL_NEARBY_INITIATOR_OPERATION_H_
 
 #include <memory>
+#include <optional>
 
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
@@ -17,7 +18,6 @@
 #include "chromeos/ash/services/secure_channel/public/cpp/shared/connection_priority.h"
 #include "chromeos/ash/services/secure_channel/public/mojom/nearby_connector.mojom-shared.h"
 #include "chromeos/ash/services/secure_channel/public/mojom/secure_channel.mojom-shared.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace ash::secure_channel {
 
@@ -106,7 +106,7 @@
 
   void OnBleDiscoveryStateChanged(
       mojom::DiscoveryResult discovery_result,
-      absl::optional<mojom::DiscoveryErrorCode> potential_error_code);
+      std::optional<mojom::DiscoveryErrorCode> potential_error_code);
   void OnNearbyConnectionStateChanged(mojom::NearbyConnectionStep step,
                                       mojom::NearbyConnectionStepResult result);
   void OnSecureChannelAuthenticationStateChanged(
diff --git a/chromeos/ash/services/secure_channel/nearby_initiator_operation_unittest.cc b/chromeos/ash/services/secure_channel/nearby_initiator_operation_unittest.cc
index eb8f237c..17f3f9c 100644
--- a/chromeos/ash/services/secure_channel/nearby_initiator_operation_unittest.cc
+++ b/chromeos/ash/services/secure_channel/nearby_initiator_operation_unittest.cc
@@ -93,7 +93,7 @@
 
   void OnBleDiscoveryStateChanged(
       mojom::DiscoveryResult result,
-      absl::optional<mojom::DiscoveryErrorCode> error_code) {
+      std::optional<mojom::DiscoveryErrorCode> error_code) {
     discovery_result_ = result;
     discovery_error_code_ = error_code;
   }
@@ -119,7 +119,7 @@
   std::optional<NearbyInitiatorFailureType> failure_type_from_callback_;
 
   mojom::DiscoveryResult discovery_result_;
-  absl::optional<mojom::DiscoveryErrorCode> discovery_error_code_;
+  std::optional<mojom::DiscoveryErrorCode> discovery_error_code_;
   mojom::NearbyConnectionStep nearby_connection_step_;
   mojom::NearbyConnectionStepResult nearby_connection_step_result_;
   mojom::SecureChannelState secure_channel_state_;
diff --git a/chromeos/ash/services/secure_channel/pending_connection_request.h b/chromeos/ash/services/secure_channel/pending_connection_request.h
index a883f7a..5f53f3e 100644
--- a/chromeos/ash/services/secure_channel/pending_connection_request.h
+++ b/chromeos/ash/services/secure_channel/pending_connection_request.h
@@ -15,7 +15,6 @@
 #include "chromeos/ash/services/secure_channel/public/cpp/shared/connection_priority.h"
 #include "chromeos/ash/services/secure_channel/public/mojom/nearby_connector.mojom-shared.h"
 #include "chromeos/ash/services/secure_channel/public/mojom/secure_channel.mojom-shared.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace ash::secure_channel {
 
@@ -52,7 +51,7 @@
 
   virtual void HandleBleDiscoveryStateChange(
       mojom::DiscoveryResult discovery_result,
-      absl::optional<mojom::DiscoveryErrorCode> potential_error_code) {}
+      std::optional<mojom::DiscoveryErrorCode> potential_error_code) {}
   virtual void HandleNearbyConnectionChange(
       mojom::NearbyConnectionStep step,
       mojom::NearbyConnectionStepResult result) {}
diff --git a/chromeos/ash/services/secure_channel/pending_connection_request_base.h b/chromeos/ash/services/secure_channel/pending_connection_request_base.h
index 095bca7..075ef9c 100644
--- a/chromeos/ash/services/secure_channel/pending_connection_request_base.h
+++ b/chromeos/ash/services/secure_channel/pending_connection_request_base.h
@@ -81,7 +81,7 @@
 
   void UpdateBleDiscoveryState(
       mojom::DiscoveryResult discovery_result,
-      absl::optional<mojom::DiscoveryErrorCode> potential_error_code) {
+      std::optional<mojom::DiscoveryErrorCode> potential_error_code) {
     client_connection_parameters_->SetBleDiscoveryState(discovery_result,
                                                         potential_error_code);
   }
diff --git a/chromeos/ash/services/secure_channel/pending_nearby_initiator_connection_request.cc b/chromeos/ash/services/secure_channel/pending_nearby_initiator_connection_request.cc
index c5af9383..635b952 100644
--- a/chromeos/ash/services/secure_channel/pending_nearby_initiator_connection_request.cc
+++ b/chromeos/ash/services/secure_channel/pending_nearby_initiator_connection_request.cc
@@ -72,7 +72,7 @@
 
 void PendingNearbyInitiatorConnectionRequest::HandleBleDiscoveryStateChange(
     mojom::DiscoveryResult discovery_state,
-    absl::optional<mojom::DiscoveryErrorCode> potential_error_code) {
+    std::optional<mojom::DiscoveryErrorCode> potential_error_code) {
   UpdateBleDiscoveryState(discovery_state, potential_error_code);
 }
 void PendingNearbyInitiatorConnectionRequest::HandleNearbyConnectionChange(
diff --git a/chromeos/ash/services/secure_channel/pending_nearby_initiator_connection_request.h b/chromeos/ash/services/secure_channel/pending_nearby_initiator_connection_request.h
index 7340ac91..d535142f 100644
--- a/chromeos/ash/services/secure_channel/pending_nearby_initiator_connection_request.h
+++ b/chromeos/ash/services/secure_channel/pending_nearby_initiator_connection_request.h
@@ -69,7 +69,7 @@
       NearbyInitiatorFailureType failure_detail) override;
   void HandleBleDiscoveryStateChange(
       mojom::DiscoveryResult discovery_state,
-      absl::optional<mojom::DiscoveryErrorCode> potential_error_code) override;
+      std::optional<mojom::DiscoveryErrorCode> potential_error_code) override;
   void HandleNearbyConnectionChange(
       mojom::NearbyConnectionStep step,
       mojom::NearbyConnectionStepResult result) override;
diff --git a/chromeos/components/kcer/helpers/kcer_chaps_util_unittest.cc b/chromeos/components/kcer/helpers/kcer_chaps_util_unittest.cc
index f152b412..54364df6 100644
--- a/chromeos/components/kcer/helpers/kcer_chaps_util_unittest.cc
+++ b/chromeos/components/kcer/helpers/kcer_chaps_util_unittest.cc
@@ -988,7 +988,7 @@
 // Successfully import EC key and single certificate from PKCS12 file to
 // Chaps software slot with is_software_backed = false.
 TEST_F(KcerChapsUtilImplTest, ImportPkcs12WithEcKeyHardwareBackedSuccess) {
-  using OPTIONAL_CK_BYTE_VECTOR = absl::optional<std::vector<CK_BYTE>>;
+  using OPTIONAL_CK_BYTE_VECTOR = std::optional<std::vector<CK_BYTE>>;
   std::map<CK_ATTRIBUTE_TYPE, OPTIONAL_CK_BYTE_VECTOR> expected_key_data;
   // Strings below have hardcoded fields from "client_with_ec_key.p12" which is
   // referenced by GetPkcs12Data(), they are Base64Encoded for the shorter
@@ -1033,7 +1033,7 @@
 // Successfully import EC key and single certificate from PKCS12 file to
 // Chaps software slot with is_software_backed = true.
 TEST_F(KcerChapsUtilImplTest, ImportPkcs12WithEcKeySoftwareBackedSuccess) {
-  using OPTIONAL_CK_BYTE_VECTOR = absl::optional<std::vector<CK_BYTE>>;
+  using OPTIONAL_CK_BYTE_VECTOR = std::optional<std::vector<CK_BYTE>>;
   std::map<CK_ATTRIBUTE_TYPE, OPTIONAL_CK_BYTE_VECTOR> expected_key_data;
   // Strings below have hardcoded fields from "client_with_ec_key.p12" which is
   // referenced by GetPkcs12Data(), they are Base64Encoded for the shorter
diff --git a/chromeos/components/kcer/kcer_token_impl.cc b/chromeos/components/kcer/kcer_token_impl.cc
index ce7a10a..d05a42e 100644
--- a/chromeos/components/kcer/kcer_token_impl.cc
+++ b/chromeos/components/kcer/kcer_token_impl.cc
@@ -104,7 +104,7 @@
 }
 
 bool GetOptionalString(const chaps::Attribute* attr,
-                       absl::optional<std::string>& result_string) {
+                       std::optional<std::string>& result_string) {
   if (!attr || !attr->has_value() || !attr->has_length()) {
     return false;
   }
diff --git a/chromeos/components/kcer/kcer_token_impl.h b/chromeos/components/kcer/kcer_token_impl.h
index 9523bd0..ec298ef 100644
--- a/chromeos/components/kcer/kcer_token_impl.h
+++ b/chromeos/components/kcer/kcer_token_impl.h
@@ -460,7 +460,7 @@
       SessionChapsClient::SlotId(0xFFFFFFFF);
   // Indicates whether PSS signatures are supported. This variable caches the
   // value from Chaps, if it's empty, it needs to be retrieved first.
-  absl::optional<bool> token_supports_pss_;
+  std::optional<bool> token_supports_pss_;
 
   // Queue for the tasks that were received while the tast queue was blocked.
   std::deque<base::OnceClosure> task_queue_;
diff --git a/components/bookmarks/browser/bookmark_storage_unittest.cc b/components/bookmarks/browser/bookmark_storage_unittest.cc
index fa79003..9774c04 100644
--- a/components/bookmarks/browser/bookmark_storage_unittest.cc
+++ b/components/bookmarks/browser/bookmark_storage_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "components/bookmarks/browser/bookmark_storage.h"
 
+#include <optional>
 #include <string>
 
 #include "base/files/file_path.h"
@@ -18,7 +19,6 @@
 #include "components/bookmarks/test/test_bookmark_client.h"
 #include "components/sync/base/features.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace bookmarks {
 
@@ -36,11 +36,11 @@
   return model;
 }
 
-absl::optional<base::Value::Dict> ReadFileToDict(
+std::optional<base::Value::Dict> ReadFileToDict(
     const base::FilePath& file_path) {
   std::string file_content;
   if (!base::ReadFileToString(file_path, &file_content)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return base::JSONReader::ReadDict(file_content);
 }
@@ -203,7 +203,7 @@
   EXPECT_TRUE(base::PathExists(bookmarks_file_path));
   EXPECT_FALSE(base::PathExists(backup_file_path));
 
-  absl::optional<base::Value::Dict> file_content =
+  std::optional<base::Value::Dict> file_content =
       ReadFileToDict(bookmarks_file_path);
   ASSERT_TRUE(file_content.has_value());
   EXPECT_FALSE(file_content->empty());
@@ -224,13 +224,13 @@
   BookmarkStorage storage(model.get(), BookmarkStorage::kSelectAccountNodes,
                           bookmarks_file_path);
 
-  ASSERT_EQ(ReadFileToDict(bookmarks_file_path), absl::nullopt);
+  ASSERT_EQ(ReadFileToDict(bookmarks_file_path), std::nullopt);
 
   storage.ScheduleSave();
   task_environment.FastForwardUntilNoTasksRemain();
 
   EXPECT_EQ(ReadFileToDict(bookmarks_file_path),
-            absl::make_optional<base::Value::Dict>());
+            std::make_optional<base::Value::Dict>());
 }
 
 }  // namespace bookmarks
diff --git a/components/history/core/browser/browsing_history_service.cc b/components/history/core/browser/browsing_history_service.cc
index 358158f..9c3b5830 100644
--- a/components/history/core/browser/browsing_history_service.cc
+++ b/components/history/core/browser/browsing_history_service.cc
@@ -734,7 +734,7 @@
               HistoryEntry::REMOTE_ENTRY, gurl, title, time, client_id,
               !state->search_text.empty(), std::u16string(),
               /* blocked_visit */ false, GURL(favicon_url), 0, 0,
-              /*app_id= */ absl::nullopt));
+              /*app_id= */ std::nullopt));
         }
       }
     }
diff --git a/components/history/core/browser/history_types.h b/components/history/core/browser/history_types.h
index c451fef..9c36b7d 100644
--- a/components/history/core/browser/history_types.h
+++ b/components/history/core/browser/history_types.h
@@ -70,7 +70,7 @@
 typedef std::map<VisitID, VisitSource> VisitSourceMap;
 
 // Constant used to represent that no app_id is used for matching.
-inline constexpr std::optional<std::string> kNoAppIdFilter = absl::nullopt;
+inline constexpr std::optional<std::string> kNoAppIdFilter = std::nullopt;
 
 // VisitRow -------------------------------------------------------------------
 
diff --git a/components/history/core/browser/url_row.h b/components/history/core/browser/url_row.h
index 17b25c5..a718b82 100644
--- a/components/history/core/browser/url_row.h
+++ b/components/history/core/browser/url_row.h
@@ -14,7 +14,6 @@
 #include "base/memory/raw_ref.h"
 #include "base/time/time.h"
 #include "components/query_parser/snippet.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace history {
diff --git a/components/page_load_metrics/browser/observers/core/largest_contentful_paint_handler.cc b/components/page_load_metrics/browser/observers/core/largest_contentful_paint_handler.cc
index dd9bd22..bded360 100644
--- a/components/page_load_metrics/browser/observers/core/largest_contentful_paint_handler.cc
+++ b/components/page_load_metrics/browser/observers/core/largest_contentful_paint_handler.cc
@@ -123,9 +123,9 @@
     const std::optional<net::RequestPriority>& image_request_priority,
     bool in_main_frame,
     const blink::LargestContentfulPaintType type,
-    const absl::optional<base::TimeDelta>& image_discovery_time,
-    const absl::optional<base::TimeDelta>& image_load_start,
-    const absl::optional<base::TimeDelta>& image_load_end)
+    const std::optional<base::TimeDelta>& image_discovery_time,
+    const std::optional<base::TimeDelta>& image_load_start,
+    const std::optional<base::TimeDelta>& image_load_end)
     : time_(time),
       size_(size),
       text_or_image_(text_or_image),
@@ -381,7 +381,7 @@
     const page_load_metrics::mojom::LargestContentfulPaintTiming&
         largest_contentful_paint,
     ContentfulPaint& subframe_contentful_paint,
-    const absl::optional<base::TimeDelta>&
+    const std::optional<base::TimeDelta>&
         first_input_or_scroll_notified_timestamp,
     const base::TimeDelta& navigation_start_offset,
     const bool is_cross_site) {
diff --git a/components/page_load_metrics/browser/observers/core/largest_contentful_paint_handler.h b/components/page_load_metrics/browser/observers/core/largest_contentful_paint_handler.h
index 2d9b32c..3ed49ce 100644
--- a/components/page_load_metrics/browser/observers/core/largest_contentful_paint_handler.h
+++ b/components/page_load_metrics/browser/observers/core/largest_contentful_paint_handler.h
@@ -44,9 +44,9 @@
       const std::optional<net::RequestPriority>& image_request_priority,
       bool in_main_frame,
       const blink::LargestContentfulPaintType type,
-      const absl::optional<base::TimeDelta>& image_discovery_time,
-      const absl::optional<base::TimeDelta>& image_load_start,
-      const absl::optional<base::TimeDelta>& image_load_end);
+      const std::optional<base::TimeDelta>& image_discovery_time,
+      const std::optional<base::TimeDelta>& image_load_start,
+      const std::optional<base::TimeDelta>& image_load_end);
   ContentfulPaintTimingInfo(const ContentfulPaintTimingInfo& other);
   void Reset(const std::optional<base::TimeDelta>& time,
              const uint64_t& size,
@@ -207,7 +207,7 @@
       const page_load_metrics::mojom::LargestContentfulPaintTiming&
           largest_contentful_paint,
       ContentfulPaint& subframe_contentful_paint,
-      const absl::optional<base::TimeDelta>&
+      const std::optional<base::TimeDelta>&
           first_input_or_scroll_notified_timestamp,
       const base::TimeDelta& navigation_start_offset,
       const bool is_cross_site);
diff --git a/components/permissions/permissions_client.h b/components/permissions/permissions_client.h
index 8b7c804..bdd0565 100644
--- a/components/permissions/permissions_client.h
+++ b/components/permissions/permissions_client.h
@@ -138,7 +138,7 @@
   // may be null. |callback| will be called with the result, and may be run
   // synchronously if the result is available immediately.
   using GetUkmSourceIdCallback =
-      base::OnceCallback<void(absl::optional<ukm::SourceId>)>;
+      base::OnceCallback<void(std::optional<ukm::SourceId>)>;
   virtual void GetUkmSourceId(ContentSettingsType permission_type,
                               content::BrowserContext* browser_context,
                               content::WebContents* web_contents,
diff --git a/components/qr_code_generator/qr_code_generator_unittest.cc b/components/qr_code_generator/qr_code_generator_unittest.cc
index 560a5a3..4eecafc2 100644
--- a/components/qr_code_generator/qr_code_generator_unittest.cc
+++ b/components/qr_code_generator/qr_code_generator_unittest.cc
@@ -10,7 +10,6 @@
 #include "base/containers/span.h"
 #include "base/test/scoped_feature_list.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace qr_code_generator {
 
diff --git a/components/remote_cocoa/app_shim/menu_controller_cocoa_delegate_impl.mm b/components/remote_cocoa/app_shim/menu_controller_cocoa_delegate_impl.mm
index 35cd9ab0..09a400e 100644
--- a/components/remote_cocoa/app_shim/menu_controller_cocoa_delegate_impl.mm
+++ b/components/remote_cocoa/app_shim/menu_controller_cocoa_delegate_impl.mm
@@ -178,7 +178,7 @@
 }
 
 - (void)controllerWillAddMenu:(NSMenu*)menu fromModel:(ui::MenuModel*)model {
-  absl::optional<size_t> alertedIndex;
+  std::optional<size_t> alertedIndex;
 
   // A map containing elements that need to be tracked, mapping from their
   // identifiers to their indexes in the menu.
diff --git a/components/viz/service/display/overlay_processor_ozone.cc b/components/viz/service/display/overlay_processor_ozone.cc
index 97bb53ba1..d50b8a5 100644
--- a/components/viz/service/display/overlay_processor_ozone.cc
+++ b/components/viz/service/display/overlay_processor_ozone.cc
@@ -86,7 +86,7 @@
   ozone_candidate->color_space = overlay_candidate.color_space;
   ozone_candidate->display_rect = overlay_candidate.display_rect;
   ozone_candidate->crop_rect = gfx::RectF(1.0, 1.0);
-  ozone_candidate->clip_rect = absl::nullopt;
+  ozone_candidate->clip_rect = std::nullopt;
   ozone_candidate->is_opaque = overlay_candidate.is_opaque;
   ozone_candidate->opacity = overlay_candidate.opacity;
   ozone_candidate->plane_z_order = overlay_candidate.plane_z_order;
diff --git a/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc b/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc
index a51b93a..8d27c77 100644
--- a/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc
+++ b/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc
@@ -3842,7 +3842,7 @@
     data_host_manager_.NotifyBackgroundRegistrationStarted(
         kBackgroundId, context_origin,
         /*is_within_fenced_frame=*/false, RegistrationEligibility::kTrigger,
-        kFrameId, kLastNavigationId, /*attribution_src_token=*/absl::nullopt,
+        kFrameId, kLastNavigationId, /*attribution_src_token=*/std::nullopt,
         kDevtoolsRequestId);
 
     auto headers = base::MakeRefCounted<net::HttpResponseHeaders>("");
diff --git a/content/browser/device_posture/device_posture_platform_provider_win.cc b/content/browser/device_posture/device_posture_platform_provider_win.cc
index d1c0d78..dca66d8 100644
--- a/content/browser/device_posture/device_posture_platform_provider_win.cc
+++ b/content/browser/device_posture/device_posture_platform_provider_win.cc
@@ -59,7 +59,7 @@
 }
 
 void DevicePosturePlatformProviderWin::StopListening() {
-  registry_key_ = absl::nullopt;
+  registry_key_ = std::nullopt;
 }
 
 std::optional<DevicePostureType> DevicePosturePlatformProviderWin::ParsePosture(
@@ -79,7 +79,7 @@
     return iter->second;
   }
   DVLOG(1) << "Could not parse the posture data: " << posture_state;
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void DevicePosturePlatformProviderWin::ComputeFoldableState(
@@ -142,14 +142,14 @@
 DevicePosturePlatformProviderWin::ParseViewportSegments(
     const base::Value::List& viewport_segments) {
   if (viewport_segments.empty()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Check if the list is correctly constructed. It should be a multiple of
   // |left side|fold|right side| or 1.
   if (viewport_segments.size() != 1 && viewport_segments.size() % 3 != 0) {
     DVLOG(1) << "Could not parse the viewport segments data.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   std::vector<gfx::Rect> segments;
@@ -157,7 +157,7 @@
     const std::string* segment_string = segment.GetIfString();
     if (!segment_string) {
       DVLOG(1) << "Could not parse the viewport segments data";
-      return absl::nullopt;
+      return std::nullopt;
     }
     auto rectangle_dimensions = base::SplitStringPiece(
         *segment_string, ",", base::WhitespaceHandling::TRIM_WHITESPACE,
@@ -165,7 +165,7 @@
     if (rectangle_dimensions.size() != 4) {
       DVLOG(1) << "Could not parse the viewport segments data: "
                << *segment_string;
-      return absl::nullopt;
+      return std::nullopt;
     }
     int x, y, width, height;
     if (!base::StringToInt(rectangle_dimensions[0], &x) ||
@@ -174,7 +174,7 @@
         !base::StringToInt(rectangle_dimensions[3], &height)) {
       DVLOG(1) << "Could not parse the viewport segments data: "
                << *segment_string;
-      return absl::nullopt;
+      return std::nullopt;
     }
     segments.emplace_back(x, y, width, height);
   }
diff --git a/content/browser/fenced_frame/fenced_frame_config.h b/content/browser/fenced_frame/fenced_frame_config.h
index d13d290c..f7b766e 100644
--- a/content/browser/fenced_frame/fenced_frame_config.h
+++ b/content/browser/fenced_frame/fenced_frame_config.h
@@ -480,7 +480,7 @@
   // FencedFrameProperties constructor rather than
   // OnFencedFrameURLMappingComplete.
   void AdjustPropertiesForUrnIframe() {
-    partition_nonce_ = absl::nullopt;
+    partition_nonce_ = std::nullopt;
     can_disable_untrusted_network_ = false;
   }
 
diff --git a/content/browser/indexed_db/indexed_db_unittest.cc b/content/browser/indexed_db/indexed_db_unittest.cc
index 8ab09a64..5ee14386 100644
--- a/content/browser/indexed_db/indexed_db_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_unittest.cc
@@ -443,7 +443,7 @@
   }
 
   IndexedDBBucketContextHandle CreateBucketHandle(
-      absl::optional<storage::BucketLocator> bucket_locator = absl::nullopt) {
+      std::optional<storage::BucketLocator> bucket_locator = std::nullopt) {
     if (!bucket_locator) {
       const blink::StorageKey storage_key =
           blink::StorageKey::CreateFromStringForTesting("http://localhost:81");
diff --git a/content/browser/interest_group/ad_auction_service_impl_unittest.cc b/content/browser/interest_group/ad_auction_service_impl_unittest.cc
index 78d69bf..b2ba0141 100644
--- a/content/browser/interest_group/ad_auction_service_impl_unittest.cc
+++ b/content/browser/interest_group/ad_auction_service_impl_unittest.cc
@@ -12652,7 +12652,7 @@
   manager_->JoinInterestGroup(
       blink::TestInterestGroupBuilder(test_origin, "cars")
           .SetAds(
-              {{{GURL("https://c.test/ad1.html"), /*metadata=*/absl::nullopt}}})
+              {{{GURL("https://c.test/ad1.html"), /*metadata=*/std::nullopt}}})
           .Build(),
       GURL("https://a.test/example.html"));
 
@@ -12699,7 +12699,7 @@
   manager_->JoinInterestGroup(
       blink::TestInterestGroupBuilder(test_origin, "cars")
           .SetAds(
-              {{{GURL("https://c.test/ad1.html"), /*metadata=*/absl::nullopt}}})
+              {{{GURL("https://c.test/ad1.html"), /*metadata=*/std::nullopt}}})
           .Build(),
       GURL("https://a.test/example.html"));
 
@@ -12719,7 +12719,7 @@
   manager_->JoinInterestGroup(
       blink::TestInterestGroupBuilder(test_origin, "cars")
           .SetAds(
-              {{{GURL("https://c.test/ad1.html"), /*metadata=*/absl::nullopt}}})
+              {{{GURL("https://c.test/ad1.html"), /*metadata=*/std::nullopt}}})
           .Build(),
       GURL("https://a.test/example.html"));
 
@@ -12763,13 +12763,13 @@
   manager_->JoinInterestGroup(
       blink::TestInterestGroupBuilder(test_origin, "cars")
           .SetAds(
-              {{{GURL("https://c.test/ad1.html"), /*metadata=*/absl::nullopt}}})
+              {{{GURL("https://c.test/ad1.html"), /*metadata=*/std::nullopt}}})
           .Build(),
       GURL("https://a.test/example.html"));
   manager_->JoinInterestGroup(
       blink::TestInterestGroupBuilder(test_origin, "boats")
           .SetAds(
-              {{{GURL("https://c.test/ad2.html"), /*metadata=*/absl::nullopt}}})
+              {{{GURL("https://c.test/ad2.html"), /*metadata=*/std::nullopt}}})
           .Build(),
       GURL("https://a.test/example.html"));
 
diff --git a/content/browser/interest_group/interest_group_browsertest.cc b/content/browser/interest_group/interest_group_browsertest.cc
index 79cdc821..347be95 100644
--- a/content/browser/interest_group/interest_group_browsertest.cc
+++ b/content/browser/interest_group/interest_group_browsertest.cc
@@ -7586,7 +7586,7 @@
       int bucket,
       int value,
       AggregatableReportSharedInfo::DebugMode debug_mode,
-      std::optional<uint64_t> debug_key = absl::nullopt) {
+      std::optional<uint64_t> debug_key = std::nullopt) {
     ASSERT_FALSE(run_loop_);
     run_loop_ = std::make_unique<base::RunLoop>();
 
@@ -12988,9 +12988,9 @@
       {"1", TestInterestGroupObserver::kLoaded, test_origin, "cars"},
       {"1", TestInterestGroupObserver::kBid, test_origin, "cars", 1.0},
       {"2", TestInterestGroupObserver::kTopLevelBid, test_origin, "cars", 1.0,
-       /*bid_currency=*/absl::nullopt, test_origin},
+       /*bid_currency=*/std::nullopt, test_origin},
       {"2", TestInterestGroupObserver::kWin, test_origin, "cars",
-       /*bid=*/absl::nullopt, /*bid_currency=*/absl::nullopt, test_origin},
+       /*bid=*/std::nullopt, /*bid_currency=*/std::nullopt, test_origin},
   });
 }
 
@@ -13780,7 +13780,7 @@
         {"2", TestInterestGroupObserver::kTopLevelBid, bidder_origin, "cars",
          42.0, "CAD", component_seller_origin},
         {"2", TestInterestGroupObserver::kWin, bidder_origin, "cars",
-         /*bid=*/absl::nullopt, /*bid_currency=*/absl::nullopt,
+         /*bid=*/std::nullopt, /*bid_currency=*/std::nullopt,
          component_seller_origin},
     });
   }
@@ -19345,10 +19345,10 @@
                                                 /*name=*/"cars")
                     .SetBiddingUrl(embedded_https_test_server().GetURL(
                         "a.test", "/interest_group/bidding_logic.js"))
-                    .SetAds({{{ad_url, /*metadata=*/absl::nullopt,
-                               /*size_group=*/absl::nullopt,
-                               /*buyer_reporting_id=*/absl::nullopt,
-                               /*buyer_and_seller_reporting_id=*/absl::nullopt,
+                    .SetAds({{{ad_url, /*metadata=*/std::nullopt,
+                               /*size_group=*/std::nullopt,
+                               /*buyer_reporting_id=*/std::nullopt,
+                               /*buyer_and_seller_reporting_id=*/std::nullopt,
                                /*ad_render_id=*/"buyCars"}}})
                     .Build()));
 
@@ -19387,8 +19387,7 @@
       ->GetDefaultStoragePartition()
       ->SetNetworkContextForTesting(std::move(pending_remote));
 
-  std::string result =
-      GetInterestGroupAdAuctionData(test_origin, absl::nullopt);
+  std::string result = GetInterestGroupAdAuctionData(test_origin, std::nullopt);
 
   static_cast<PreconnectCheckingNetworkContext*>(preconnect_check->impl())
       ->run_loop()
diff --git a/content/browser/interest_group/interest_group_manager_impl.cc b/content/browser/interest_group/interest_group_manager_impl.cc
index 75ee851..f76111a2 100644
--- a/content/browser/interest_group/interest_group_manager_impl.cc
+++ b/content/browser/interest_group/interest_group_manager_impl.cc
@@ -554,7 +554,7 @@
     // Since a single B&A blob can be associated with multiple auctions, we
     // can't link these loads to a specific one.
     GetInterestGroupsForOwner(
-        /*devtools_auction_id=*/absl::nullopt, next_owner,
+        /*devtools_auction_id=*/std::nullopt, next_owner,
         base::BindOnce(
             &InterestGroupManagerImpl::OnLoadedNextInterestGroupAdAuctionData,
             weak_factory_.GetWeakPtr(), std::move(state), std::move(owners),
diff --git a/content/browser/interest_group/interest_group_update_manager.cc b/content/browser/interest_group/interest_group_update_manager.cc
index 3a86acc..796c7e4 100644
--- a/content/browser/interest_group/interest_group_update_manager.cc
+++ b/content/browser/interest_group/interest_group_update_manager.cc
@@ -715,7 +715,7 @@
   }
   if (!TryToCopyMaxTrustedBiddingSignalsURLLength(*dict,
                                                   interest_group_update)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   if (!TryToCopyTrustedBiddingSignalsKeys(*dict, interest_group_update)) {
     return std::nullopt;
diff --git a/content/browser/loader/keep_alive_attribution_request_helper_unittest.cc b/content/browser/loader/keep_alive_attribution_request_helper_unittest.cc
index 38edd813..f733a73 100644
--- a/content/browser/loader/keep_alive_attribution_request_helper_unittest.cc
+++ b/content/browser/loader/keep_alive_attribution_request_helper_unittest.cc
@@ -121,7 +121,7 @@
       AttributionReportingEligibility eligibility =
           AttributionReportingEligibility::kEventSourceOrTrigger,
       const std::optional<base::UnguessableToken>& attribution_src_token =
-          absl::nullopt,
+          std::nullopt,
       const GURL& context_url = GURL("https://secure_source.com")) {
     test_web_contents()->NavigateAndCommit(context_url);
 
@@ -156,7 +156,7 @@
   const GURL reporting_url("https://report.test");
   auto helper = CreateValidHelper(
       reporting_url, AttributionReportingEligibility::kEventSourceOrTrigger,
-      /*attribution_src_token=*/absl::nullopt, source_url);
+      /*attribution_src_token=*/std::nullopt, source_url);
 
   EXPECT_CALL(
       *mock_attribution_manager(),
@@ -418,7 +418,7 @@
     ASSERT_TRUE(context.has_value());
     auto helper = KeepAliveAttributionRequestHelper::CreateIfNeeded(
         AttributionReportingEligibility::kEmpty, reporting_url,
-        /*attribution_src_token=*/absl::nullopt, "devtools-request-id",
+        /*attribution_src_token=*/std::nullopt, "devtools-request-id",
         network::AttributionReportingRuntimeFeatures(), context.value());
     EXPECT_EQ(helper, nullptr);
   }
@@ -435,7 +435,7 @@
     ASSERT_TRUE(context.has_value());
     auto helper = KeepAliveAttributionRequestHelper::CreateIfNeeded(
         AttributionReportingEligibility::kEventSourceOrTrigger, reporting_url,
-        /*attribution_src_token=*/absl::nullopt, "devtools-request-id",
+        /*attribution_src_token=*/std::nullopt, "devtools-request-id",
         network::AttributionReportingRuntimeFeatures(), context.value());
     EXPECT_EQ(helper, nullptr);
   }
diff --git a/content/browser/loader/keep_alive_url_loader_service_unittest.cc b/content/browser/loader/keep_alive_url_loader_service_unittest.cc
index 20ea527..0ecf0b429 100644
--- a/content/browser/loader/keep_alive_url_loader_service_unittest.cc
+++ b/content/browser/loader/keep_alive_url_loader_service_unittest.cc
@@ -646,7 +646,7 @@
   GetLastPendingRequest()->client->OnReceiveResponse(
       CreateResponseHead(
           {{kAttributionReportingRegisterSourceHeader, kRegisterSourceJson}}),
-      /*body=*/{}, /*cached_metadata=*/absl::nullopt);
+      /*body=*/{}, /*cached_metadata=*/std::nullopt);
 
   base::RunLoop().RunUntilIdle();
 }
diff --git a/content/browser/loader/navigation_early_hints_manager.cc b/content/browser/loader/navigation_early_hints_manager.cc
index ee25cb1..42aca32 100644
--- a/content/browser/loader/navigation_early_hints_manager.cc
+++ b/content/browser/loader/navigation_early_hints_manager.cc
@@ -536,7 +536,7 @@
           base::BindRepeating(&WebContents::FromFrameTreeNodeId,
                               frame_tree_node_id_),
           /*navigation_ui_data=*/nullptr, frame_tree_node_id_,
-          /*navigation_id=*/absl::nullopt);
+          /*navigation_id=*/std::nullopt);
 
   auto loader_client = std::make_unique<PreloadURLLoaderClient>(*this, request);
   auto loader = blink::ThrottlingURLLoader::CreateLoaderAndStart(
diff --git a/content/browser/loader/prefetch_url_loader_service_context.cc b/content/browser/loader/prefetch_url_loader_service_context.cc
index 0f31507..d15cb4a 100644
--- a/content/browser/loader/prefetch_url_loader_service_context.cc
+++ b/content/browser/loader/prefetch_url_loader_service_context.cc
@@ -281,7 +281,7 @@
       base::BindRepeating(&WebContents::FromFrameTreeNodeId,
                           frame_tree_node_id),
       nullptr /* navigation_ui_data */, frame_tree_node_id,
-      /*navigation_id=*/absl::nullopt);
+      /*navigation_id=*/std::nullopt);
 }
 
 }  // namespace content
diff --git a/content/browser/loader/url_loader_factory_utils.h b/content/browser/loader/url_loader_factory_utils.h
index 1034917..99f3629 100644
--- a/content/browser/loader/url_loader_factory_utils.h
+++ b/content/browser/loader/url_loader_factory_utils.h
@@ -43,7 +43,7 @@
                       const url::Origin& request_initiator,
                       ukm::SourceIdObj ukm_source_id,
                       bool* bypass_redirect_checks = nullptr,
-                      std::optional<int64_t> navigation_id = absl::nullopt,
+                      std::optional<int64_t> navigation_id = std::nullopt,
                       scoped_refptr<base::SequencedTaskRunner>
                           navigation_response_task_runner = nullptr);
 
diff --git a/content/browser/media/cdm_storage_database.cc b/content/browser/media/cdm_storage_database.cc
index 6d7b141..e3435478d 100644
--- a/content/browser/media/cdm_storage_database.cc
+++ b/content/browser/media/cdm_storage_database.cc
@@ -145,14 +145,14 @@
   return success;
 }
 
-absl::optional<uint64_t> CdmStorageDatabase::GetSizeForFile(
+std::optional<uint64_t> CdmStorageDatabase::GetSizeForFile(
     const blink::StorageKey& storage_key,
     const media::CdmType& cdm_type,
     const std::string& file_name) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (OpenDatabase() != CdmStorageOpenError::kOk) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // clang-format off
@@ -182,14 +182,14 @@
   return statement.ColumnInt64(0);
 }
 
-absl::optional<uint64_t> CdmStorageDatabase::GetSizeForStorageKey(
+std::optional<uint64_t> CdmStorageDatabase::GetSizeForStorageKey(
     const blink::StorageKey& storage_key,
     const base::Time begin,
     const base::Time end) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (OpenDatabase() != CdmStorageOpenError::kOk) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // clang-format off
@@ -221,13 +221,13 @@
   return statement.ColumnInt64(0);
 }
 
-absl::optional<uint64_t> CdmStorageDatabase::GetSizeForTimeFrame(
+std::optional<uint64_t> CdmStorageDatabase::GetSizeForTimeFrame(
     const base::Time begin,
     const base::Time end) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (OpenDatabase() != CdmStorageOpenError::kOk) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // clang-format off
diff --git a/content/browser/media/cdm_storage_database.h b/content/browser/media/cdm_storage_database.h
index 3965669..0a8ea5a 100644
--- a/content/browser/media/cdm_storage_database.h
+++ b/content/browser/media/cdm_storage_database.h
@@ -42,17 +42,17 @@
                  const std::string& file_name,
                  const std::vector<uint8_t>& data);
 
-  absl::optional<uint64_t> GetSizeForFile(const blink::StorageKey& storage_key,
-                                          const media::CdmType& cdm_type,
-                                          const std::string& file_name);
+  std::optional<uint64_t> GetSizeForFile(const blink::StorageKey& storage_key,
+                                         const media::CdmType& cdm_type,
+                                         const std::string& file_name);
 
-  absl::optional<uint64_t> GetSizeForStorageKey(
+  std::optional<uint64_t> GetSizeForStorageKey(
       const blink::StorageKey& storage_key,
       const base::Time begin,
       const base::Time end);
 
-  absl::optional<uint64_t> GetSizeForTimeFrame(const base::Time begin,
-                                               const base::Time end);
+  std::optional<uint64_t> GetSizeForTimeFrame(const base::Time begin,
+                                              const base::Time end);
 
   bool DeleteFile(const blink::StorageKey& storage_key,
                   const media::CdmType& cdm_type,
diff --git a/content/browser/media/cdm_storage_manager.cc b/content/browser/media/cdm_storage_manager.cc
index 3d044b7..2b1c5fd 100644
--- a/content/browser/media/cdm_storage_manager.cc
+++ b/content/browser/media/cdm_storage_manager.cc
@@ -265,7 +265,7 @@
 
 void CdmStorageManager::DidGetSize(base::OnceCallback<void(uint64_t)> callback,
                                    const std::string& operation,
-                                   absl::optional<uint64_t> size) {
+                                   std::optional<uint64_t> size) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   base::UmaHistogramBoolean(GetHistogramName(operation), !size.has_value());
diff --git a/content/browser/media/cdm_storage_manager.h b/content/browser/media/cdm_storage_manager.h
index 337a462..36096627 100644
--- a/content/browser/media/cdm_storage_manager.h
+++ b/content/browser/media/cdm_storage_manager.h
@@ -113,7 +113,7 @@
 
   void DidGetSize(base::OnceCallback<void(uint64_t)> callback,
                   const std::string& operation,
-                  absl::optional<uint64_t> size);
+                  std::optional<uint64_t> size);
 
   void DidDelete(base::OnceCallback<void(bool)> callback,
                  const std::string& operation,
diff --git a/content/browser/metrics/histogram_shared_memory_config_unittest.cc b/content/browser/metrics/histogram_shared_memory_config_unittest.cc
index eedd0fa..025c79a 100644
--- a/content/browser/metrics/histogram_shared_memory_config_unittest.cc
+++ b/content/browser/metrics/histogram_shared_memory_config_unittest.cc
@@ -19,8 +19,8 @@
   int process_type;
   std::optional<Config> expected;
 
-  ProcessTypeToOptionalConfig(int type, absl::nullopt_t)
-      : process_type(type), expected(absl::nullopt) {}
+  ProcessTypeToOptionalConfig(int type, std::nullopt_t)
+      : process_type(type), expected(std::nullopt) {}
 
   ProcessTypeToOptionalConfig(int type, std::string_view name, size_t size)
       : process_type(type), expected(Config{type, name, size}) {}
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index b303b8b..d5015db 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -5805,7 +5805,7 @@
     // TODO(https://crbug.com/1169736): Make this unreachable by blocking
     // cross-origin about:srcdoc navigations. Then enforce that the chosen
     // origin for srcdoc cases agrees with the parent frame's origin.
-    common_params_->initiator_base_url = absl::nullopt;
+    common_params_->initiator_base_url = std::nullopt;
   }
 
   // TODO(https://crbug.com/888079): The storage key's origin is ignored at the
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index a934cec..2d8673a 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -12799,7 +12799,7 @@
     SCOPED_CRASH_KEY_STRING32("ValidateDidCommit_empty_baseurl", "url",
                               params->url.possibly_invalid_spec());
     base::debug::DumpWithoutCrashing();
-    params->initiator_base_url = absl::nullopt;
+    params->initiator_base_url = std::nullopt;
   }
 
   // A cross-document navigation requires an embedding token. Navigations
diff --git a/content/browser/service_worker/service_worker_new_script_loader.cc b/content/browser/service_worker/service_worker_new_script_loader.cc
index f68ce1f..1e8d936 100644
--- a/content/browser/service_worker/service_worker_new_script_loader.cc
+++ b/content/browser/service_worker/service_worker_new_script_loader.cc
@@ -176,7 +176,7 @@
         resource_request, version_->context()->wrapper()->browser_context(),
         std::move(web_contents_getter),
         /*navigation_ui_data=*/nullptr, RenderFrameHost::kNoFrameTreeNodeId,
-        /*navigation_id=*/absl::nullopt);
+        /*navigation_id=*/std::nullopt);
   }
 
   network_loader_ = blink::ThrottlingURLLoader::CreateLoaderAndStart(
diff --git a/content/browser/service_worker/service_worker_single_script_update_checker.cc b/content/browser/service_worker/service_worker_single_script_update_checker.cc
index 89c8a8f5..e31e90e 100644
--- a/content/browser/service_worker/service_worker_single_script_update_checker.cc
+++ b/content/browser/service_worker/service_worker_single_script_update_checker.cc
@@ -194,7 +194,7 @@
       CreateContentBrowserURLLoaderThrottles(
           resource_request, browser_context, std::move(web_contents_getter),
           /*navigation_ui_data=*/nullptr, RenderFrameHost::kNoFrameTreeNodeId,
-          /*navigation_id=*/absl::nullopt);
+          /*navigation_id=*/std::nullopt);
 
   network_client_remote_.Bind(
       network_client_receiver_.BindNewPipeAndPassRemote());
diff --git a/content/browser/webid/digital_credentials/digital_identity_request_impl.cc b/content/browser/webid/digital_credentials/digital_identity_request_impl.cc
index f24c3b4..5610464 100644
--- a/content/browser/webid/digital_credentials/digital_identity_request_impl.cc
+++ b/content/browser/webid/digital_credentials/digital_identity_request_impl.cc
@@ -39,7 +39,7 @@
 void DigitalIdentityRequestImpl::CompleteRequest(const std::string& response) {
   if (!provider_) {
     std::move(callback_).Run(RequestDigitalIdentityStatus::kError,
-                             absl::nullopt);
+                             std::nullopt);
     return;
   }
 
@@ -47,7 +47,7 @@
     std::move(callback_).Run(RequestDigitalIdentityStatus::kSuccess, response);
   } else {
     std::move(callback_).Run(RequestDigitalIdentityStatus::kError,
-                             absl::nullopt);
+                             std::nullopt);
   }
 }
 
@@ -111,8 +111,7 @@
     blink::mojom::DigitalCredentialProviderPtr digital_credential_provider,
     RequestCallback callback) {
   if (!IsWebIdentityDigitalCredentialsEnabled()) {
-    std::move(callback).Run(RequestDigitalIdentityStatus::kError,
-                            absl::nullopt);
+    std::move(callback).Run(RequestDigitalIdentityStatus::kError, std::nullopt);
     return;
   }
 
@@ -126,7 +125,7 @@
   if (callback_) {
     // Only allow one in-flight wallet request.
     std::move(callback).Run(RequestDigitalIdentityStatus::kErrorTooManyRequests,
-                            absl::nullopt);
+                            std::nullopt);
     return;
   }
 
@@ -138,7 +137,7 @@
   }
   if (!provider_) {
     std::move(callback_).Run(RequestDigitalIdentityStatus::kError,
-                             absl::nullopt);
+                             std::nullopt);
     return;
   }
 
diff --git a/content/browser/webid/federated_auth_request_impl.cc b/content/browser/webid/federated_auth_request_impl.cc
index 08db2c1..cb5b52a 100644
--- a/content/browser/webid/federated_auth_request_impl.cc
+++ b/content/browser/webid/federated_auth_request_impl.cc
@@ -702,7 +702,7 @@
         break;
     };
     RecordLifecycleStateFailureReason(reason);
-    std::move(callback).Run(RequestTokenStatus::kError, absl::nullopt, "",
+    std::move(callback).Run(RequestTokenStatus::kError, std::nullopt, "",
                             /*error=*/nullptr,
                             /*is_auto_selected=*/false);
     return;
diff --git a/content/browser/worker_host/worker_script_fetcher.cc b/content/browser/worker_host/worker_script_fetcher.cc
index e2202f5..d7bf45d 100644
--- a/content/browser/worker_host/worker_script_fetcher.cc
+++ b/content/browser/worker_host/worker_script_fetcher.cc
@@ -467,7 +467,7 @@
       CreateContentBrowserURLLoaderThrottles(
           *resource_request, browser_context, wc_getter,
           nullptr /* navigation_ui_data */, RenderFrameHost::kNoFrameTreeNodeId,
-          /*navigation_id=*/absl::nullopt);
+          /*navigation_id=*/std::nullopt);
 
   // Create a BrowserContext getter using |service_worker_context|.
   // This context is aware of shutdown and safely returns a nullptr
diff --git a/content/services/auction_worklet/context_recycler_unittest.cc b/content/services/auction_worklet/context_recycler_unittest.cc
index eaccaaa..7bdbd90 100644
--- a/content/services/auction_worklet/context_recycler_unittest.cc
+++ b/content/services/auction_worklet/context_recycler_unittest.cc
@@ -177,11 +177,11 @@
       ig_params2->priority_vector.emplace();
       ig_params2->priority_vector->insert(
           std::pair<std::string, double>("a", 42.0));
-      ig_params2->ads = {{{GURL("https://ad.test/1"), absl::nullopt},
+      ig_params2->ads = {{{GURL("https://ad.test/1"), std::nullopt},
                           {GURL("https://ad.test/2"), {"\"metadata 1\""}}}};
       ig_params2->ad_components = {
           {{GURL("https://ad-component.test/1"), {"\"metadata 2\""}},
-           {GURL("https://ad-component.test/2"), absl::nullopt}}};
+           {GURL("https://ad-component.test/2"), std::nullopt}}};
 
       mojom::BiddingBrowserSignalsPtr bs_params2 =
           mojom::BiddingBrowserSignals::New();
@@ -1127,7 +1127,7 @@
   ig_params->enable_bidding_signals_prioritization = true;
   ig_params->ads = {{{GURL("https://ad2.test/"), {"\"metadata 3\""}}}};
   ig_params->ad_components = {
-      {{GURL("https://ad-component2.test/"), absl::nullopt}}};
+      {{GURL("https://ad-component2.test/"), std::nullopt}}};
 
   mojom::BiddingBrowserSignalsPtr bs_params =
       mojom::BiddingBrowserSignals::New();
diff --git a/extensions/browser/api/alarms/alarm_manager.h b/extensions/browser/api/alarms/alarm_manager.h
index 5ab6efb..5415084 100644
--- a/extensions/browser/api/alarms/alarm_manager.h
+++ b/extensions/browser/api/alarms/alarm_manager.h
@@ -7,6 +7,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -24,7 +25,6 @@
 #include "extensions/browser/extension_registry_observer.h"
 #include "extensions/common/api/alarms.h"
 #include "extensions/common/extension_id.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class Clock;
diff --git a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
index b40b67e..156bb23 100644
--- a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
+++ b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
@@ -322,7 +322,7 @@
       web_view_internal::CaptureVisibleRegion::Params::Create(args());
   EXTENSION_FUNCTION_VALIDATE(params);
 
-  absl::optional<ImageDetails> image_details;
+  std::optional<ImageDetails> image_details;
   if (args().size() > 1) {
     image_details = ImageDetails::FromValue(args()[1]);
   }
diff --git a/extensions/browser/api/sockets_udp/test_udp_echo_server.cc b/extensions/browser/api/sockets_udp/test_udp_echo_server.cc
index 1d7ede7..38feb4f 100644
--- a/extensions/browser/api/sockets_udp/test_udp_echo_server.cc
+++ b/extensions/browser/api/sockets_udp/test_udp_echo_server.cc
@@ -43,8 +43,8 @@
 
  private:
   void OnReceived(int32_t result,
-                  const absl::optional<net::IPEndPoint>& src_addr,
-                  absl::optional<base::span<const uint8_t>> data) override {
+                  const std::optional<net::IPEndPoint>& src_addr,
+                  std::optional<base::span<const uint8_t>> data) override {
     if (on_received_callback_) {
       std::move(on_received_callback_)
           .Run(result, src_addr.value(), data.value());
diff --git a/extensions/browser/api/storage/settings_observer.h b/extensions/browser/api/storage/settings_observer.h
index f98cc360..58e52e6 100644
--- a/extensions/browser/api/storage/settings_observer.h
+++ b/extensions/browser/api/storage/settings_observer.h
@@ -19,7 +19,7 @@
 using SettingsChangedCallback =
     base::RepeatingCallback<void(const std::string&,
                                  StorageAreaNamespace,
-                                 absl::optional<api::storage::AccessLevel>,
+                                 std::optional<api::storage::AccessLevel>,
                                  base::Value)>;
 
 using SequenceBoundSettingsChangedCallback =
diff --git a/extensions/browser/api/storage/storage_api.cc b/extensions/browser/api/storage/storage_api.cc
index ac8b07a..4579da64 100644
--- a/extensions/browser/api/storage/storage_api.cc
+++ b/extensions/browser/api/storage/storage_api.cc
@@ -227,7 +227,7 @@
 
   if (!result.changes().empty()) {
     observer_->Run(
-        extension_id(), storage_area_, /*session_access_level=*/absl::nullopt,
+        extension_id(), storage_area_, /*session_access_level=*/std::nullopt,
         value_store::ValueStoreChange::ToValue(result.PassChanges()));
   }
 
diff --git a/extensions/browser/api/storage/storage_frontend.cc b/extensions/browser/api/storage/storage_frontend.cc
index aff0eae6..0154469 100644
--- a/extensions/browser/api/storage/storage_frontend.cc
+++ b/extensions/browser/api/storage/storage_frontend.cc
@@ -177,7 +177,7 @@
 void StorageFrontend::OnSettingsChanged(
     const ExtensionId& extension_id,
     StorageAreaNamespace storage_area,
-    absl::optional<api::storage::AccessLevel> session_access_level,
+    std::optional<api::storage::AccessLevel> session_access_level,
     base::Value changes) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   TRACE_EVENT1("browser", "SettingsObserver:OnSettingsChanged", "extension_id",
@@ -205,7 +205,7 @@
 
   // Restrict event to blessed context if session access level is set only to
   // trusted contexts.
-  absl::optional<mojom::ContextType> restrict_to_context_type = absl::nullopt;
+  std::optional<mojom::ContextType> restrict_to_context_type = std::nullopt;
   if (storage_area == StorageAreaNamespace::kSession) {
     CHECK(session_access_level.has_value());
     if (session_access_level.value() ==
diff --git a/extensions/browser/api/storage/storage_frontend.h b/extensions/browser/api/storage/storage_frontend.h
index c15805d..9e3cf7b2 100644
--- a/extensions/browser/api/storage/storage_frontend.h
+++ b/extensions/browser/api/storage/storage_frontend.h
@@ -98,7 +98,7 @@
   void OnSettingsChanged(
       const ExtensionId& extension_id,
       StorageAreaNamespace storage_area,
-      absl::optional<api::storage::AccessLevel> session_access_level,
+      std::optional<api::storage::AccessLevel> session_access_level,
       base::Value changes);
 
   // The (non-incognito) browser context this Frontend belongs to.
diff --git a/extensions/browser/api/web_request/extension_web_request_event_router.cc b/extensions/browser/api/web_request/extension_web_request_event_router.cc
index 7447673..8092008 100644
--- a/extensions/browser/api/web_request/extension_web_request_event_router.cc
+++ b/extensions/browser/api/web_request/extension_web_request_event_router.cc
@@ -276,7 +276,7 @@
 
   auto event = std::make_unique<Event>(
       histogram_value, event_name, std::move(event_args), browser_context,
-      /*restrict_to_context_type=*/absl::nullopt, GURL(),
+      /*restrict_to_context_type=*/std::nullopt, GURL(),
       EventRouter::USER_GESTURE_UNKNOWN, std::move(event_filtering_info));
   event_router->DispatchEventToExtension(extension_id, std::move(event));
 }
diff --git a/extensions/browser/event_listener_map_unittest.cc b/extensions/browser/event_listener_map_unittest.cc
index f44d1984..781d216 100644
--- a/extensions/browser/event_listener_map_unittest.cc
+++ b/extensions/browser/event_listener_map_unittest.cc
@@ -95,7 +95,7 @@
     info->url = url;
     return std::make_unique<Event>(
         events::FOR_TEST, event_name, base::Value::List(), nullptr,
-        /*restrict_to_context_type=*/absl::nullopt, GURL(),
+        /*restrict_to_context_type=*/std::nullopt, GURL(),
         EventRouter::USER_GESTURE_UNKNOWN, std::move(info));
   }
 
diff --git a/extensions/browser/event_router.cc b/extensions/browser/event_router.cc
index 4149955d..a862a9b 100644
--- a/extensions/browser/event_router.cc
+++ b/extensions/browser/event_router.cc
@@ -1580,7 +1580,7 @@
              std::string_view event_name,
              base::Value::List event_args,
              content::BrowserContext* restrict_to_browser_context,
-             absl::optional<mojom::ContextType> restrict_to_context_type)
+             std::optional<mojom::ContextType> restrict_to_context_type)
     : Event(histogram_value,
             event_name,
             std::move(event_args),
@@ -1594,7 +1594,7 @@
              std::string_view event_name,
              base::Value::List event_args,
              content::BrowserContext* restrict_to_browser_context,
-             absl::optional<mojom::ContextType> restrict_to_context_type,
+             std::optional<mojom::ContextType> restrict_to_context_type,
              const GURL& event_url,
              EventRouter::UserGestureState user_gesture,
              mojom::EventFilteringInfoPtr info,
diff --git a/extensions/browser/event_router.h b/extensions/browser/event_router.h
index 89e50f9..ff0ea92 100644
--- a/extensions/browser/event_router.h
+++ b/extensions/browser/event_router.h
@@ -601,7 +601,7 @@
   const raw_ptr<content::BrowserContext> restrict_to_browser_context;
 
   // If present, then the event will only be sent to this context type.
-  const absl::optional<mojom::ContextType> restrict_to_context_type;
+  const std::optional<mojom::ContextType> restrict_to_context_type;
 
   // If not empty, the event is only sent to extensions with host permissions
   // for this url.
@@ -656,14 +656,14 @@
         std::string_view event_name,
         base::Value::List event_args,
         content::BrowserContext* restrict_to_browser_context,
-        absl::optional<mojom::ContextType> restrict_to_context_type =
-            absl::nullopt);
+        std::optional<mojom::ContextType> restrict_to_context_type =
+            std::nullopt);
 
   Event(events::HistogramValue histogram_value,
         std::string_view event_name,
         base::Value::List event_args,
         content::BrowserContext* restrict_to_browser_context,
-        absl::optional<mojom::ContextType> restrict_to_context_type,
+        std::optional<mojom::ContextType> restrict_to_context_type,
         const GURL& event_url,
         EventRouter::UserGestureState user_gesture,
         mojom::EventFilteringInfoPtr info,
diff --git a/extensions/browser/extensions_browser_client.h b/extensions/browser/extensions_browser_client.h
index 1be758c..7e5c291 100644
--- a/extensions/browser/extensions_browser_client.h
+++ b/extensions/browser/extensions_browser_client.h
@@ -9,6 +9,7 @@
 #include <optional>
 #include <string>
 #include <vector>
+
 #include "base/functional/callback_forward.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/ref_counted_memory.h"
@@ -29,7 +30,6 @@
 #include "services/network/public/mojom/fetch_api.mojom.h"
 #include "services/network/public/mojom/url_loader.mojom-forward.h"
 #include "services/network/public/mojom/url_loader_factory.mojom-forward.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/page_transition_types.h"
 #include "url/gurl.h"
 
diff --git a/extensions/common/api/scripts_internal/script_serialization_fuzzer.cc b/extensions/common/api/scripts_internal/script_serialization_fuzzer.cc
index 29bf70e..07a5acc 100644
--- a/extensions/common/api/scripts_internal/script_serialization_fuzzer.cc
+++ b/extensions/common/api/scripts_internal/script_serialization_fuzzer.cc
@@ -2,12 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "extensions/common/api/scripts_internal/script_serialization.h"
+
+#include <fuzzer/FuzzedDataProvider.h>
 #include <stddef.h>
 #include <stdint.h>
 
-#include <fuzzer/FuzzedDataProvider.h>
-
 #include <memory>
+#include <optional>
 #include <string>
 #include <tuple>
 #include <utility>
@@ -17,11 +19,9 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/values.h"
 #include "extensions/common/api/scripts_internal.h"
-#include "extensions/common/api/scripts_internal/script_serialization.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_builder.h"
 #include "extensions/common/user_script.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using extensions::api::scripts_internal::SerializedUserScript;
 
@@ -32,12 +32,12 @@
   FuzzedDataProvider provider(data, size);
 
   // Generate input parameters for the call.
-  absl::optional<base::Value> serialized_script_value =
+  std::optional<base::Value> serialized_script_value =
       base::JSONReader::Read(provider.ConsumeRandomLengthString());
   if (!serialized_script_value.has_value()) {
     return 0;
   }
-  absl::optional<SerializedUserScript> serialized_script =
+  std::optional<SerializedUserScript> serialized_script =
       SerializedUserScript::FromValue(std::move(*serialized_script_value));
   if (!serialized_script.has_value()) {
     return 0;
diff --git a/fuchsia_web/webengine/browser/web_engine_content_browser_client.cc b/fuchsia_web/webengine/browser/web_engine_content_browser_client.cc
index b1ca06b4..5522a055 100644
--- a/fuchsia_web/webengine/browser/web_engine_content_browser_client.cc
+++ b/fuchsia_web/webengine/browser/web_engine_content_browser_client.cc
@@ -339,7 +339,7 @@
     const base::RepeatingCallback<content::WebContents*()>& wc_getter,
     content::NavigationUIData* navigation_ui_data,
     int frame_tree_node_id,
-    absl::optional<int64_t> navigation_id) {
+    std::optional<int64_t> navigation_id) {
   if (frame_tree_node_id == content::RenderFrameHost::kNoFrameTreeNodeId) {
     // TODO(crbug.com/1378791): Add support for Shared and Service Workers.
     return {};
diff --git a/fuchsia_web/webengine/browser/web_engine_content_browser_client.h b/fuchsia_web/webengine/browser/web_engine_content_browser_client.h
index 4449c57..d28dcf5a 100644
--- a/fuchsia_web/webengine/browser/web_engine_content_browser_client.h
+++ b/fuchsia_web/webengine/browser/web_engine_content_browser_client.h
@@ -67,7 +67,7 @@
       const base::RepeatingCallback<content::WebContents*()>& wc_getter,
       content::NavigationUIData* navigation_ui_data,
       int frame_tree_node_id,
-      absl::optional<int64_t> navigation_id) override;
+      std::optional<int64_t> navigation_id) override;
   void ConfigureNetworkContextParams(
       content::BrowserContext* context,
       bool in_memory,
diff --git a/gpu/command_buffer/service/image_reader_gl_owner.cc b/gpu/command_buffer/service/image_reader_gl_owner.cc
index 9f7a5ea..c42f1a5 100644
--- a/gpu/command_buffer/service/image_reader_gl_owner.cc
+++ b/gpu/command_buffer/service/image_reader_gl_owner.cc
@@ -77,12 +77,12 @@
   return features::LimitAImageReaderMaxSizeToOne() ? 1 : 2;
 }
 
-absl::optional<gfx::Size> GetImageSize(AImage* image) {
+std::optional<gfx::Size> GetImageSize(AImage* image) {
   int32_t width = 0, height = 0;
   if (AImage_getWidth(image, &width) != AMEDIA_OK ||
       AImage_getHeight(image, &height) != AMEDIA_OK || width <= 0 ||
       height <= 0) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return gfx::Size(width, height);
diff --git a/gpu/command_buffer/service/surface_texture_gl_owner.h b/gpu/command_buffer/service/surface_texture_gl_owner.h
index 8fee0c47..b3086a9 100644
--- a/gpu/command_buffer/service/surface_texture_gl_owner.h
+++ b/gpu/command_buffer/service/surface_texture_gl_owner.h
@@ -75,7 +75,7 @@
   bool is_frame_available_callback_set_ = false;
 
   // This is not precise, but good estimation for memory dumps.
-  absl::optional<gfx::Size> last_coded_size_for_memory_dumps_;
+  std::optional<gfx::Size> last_coded_size_for_memory_dumps_;
 
   THREAD_CHECKER(thread_checker_);
 };
diff --git a/ios/chrome/browser/plus_addresses/coordinator/plus_address_bottom_sheet_mediator.mm b/ios/chrome/browser/plus_addresses/coordinator/plus_address_bottom_sheet_mediator.mm
index 16937b3d..bbcbdc3 100644
--- a/ios/chrome/browser/plus_addresses/coordinator/plus_address_bottom_sheet_mediator.mm
+++ b/ios/chrome/browser/plus_addresses/coordinator/plus_address_bottom_sheet_mediator.mm
@@ -95,7 +95,7 @@
 }
 
 - (NSString*)primaryEmailAddress {
-  absl::optional<std::string> primaryAddress =
+  std::optional<std::string> primaryAddress =
       _plusAddressService->GetPrimaryEmail();
   // TODO(crbug.com/1467623): determine the appropriate behavior in cases
   // without a primary email (or just switch the signature away from optional).
diff --git a/ios/chrome/browser/plus_addresses/coordinator/plus_address_bottom_sheet_mediator_unittest.mm b/ios/chrome/browser/plus_addresses/coordinator/plus_address_bottom_sheet_mediator_unittest.mm
index 3b417bf..65d8bc6 100644
--- a/ios/chrome/browser/plus_addresses/coordinator/plus_address_bottom_sheet_mediator_unittest.mm
+++ b/ios/chrome/browser/plus_addresses/coordinator/plus_address_bottom_sheet_mediator_unittest.mm
@@ -68,7 +68,7 @@
                           .is_confirmed = false}));
   }
 
-  absl::optional<std::string> GetPrimaryEmail() override {
+  std::optional<std::string> GetPrimaryEmail() override {
     // Ensure the value is present without requiring identity setup.
     return "[email protected]";
   }
diff --git a/ios/chrome/browser/promos_manager/model/promos_manager_feature_engagement_unittest.mm b/ios/chrome/browser/promos_manager/model/promos_manager_feature_engagement_unittest.mm
index 3368a1c..b672f474 100644
--- a/ios/chrome/browser/promos_manager/model/promos_manager_feature_engagement_unittest.mm
+++ b/ios/chrome/browser/promos_manager/model/promos_manager_feature_engagement_unittest.mm
@@ -35,7 +35,7 @@
 // than once in 30 days is added to all active standard promos.
 TEST_F(PromosManagerFeatureEngagementTest, TestPerPromoLimit) {
   for (const base::Feature* feature : ActiveStandardPromos()) {
-    absl::optional<feature_engagement::FeatureConfig> optional_config =
+    std::optional<feature_engagement::FeatureConfig> optional_config =
         feature_engagement::GetClientSideiOSPromoFeatureConfig(feature);
 
     ASSERT_TRUE(optional_config.has_value());
@@ -57,7 +57,7 @@
 // active standard promos.
 TEST_F(PromosManagerFeatureEngagementTest, TestGlobalLimit) {
   for (const base::Feature* feature : ActiveStandardPromos()) {
-    absl::optional<feature_engagement::FeatureConfig> optional_config =
+    std::optional<feature_engagement::FeatureConfig> optional_config =
         feature_engagement::GetClientSideiOSPromoFeatureConfig(feature);
 
     ASSERT_TRUE(optional_config.has_value());
diff --git a/ios/chrome/browser/segmentation_platform/model/segmentation_platform_service_factory_unittest.mm b/ios/chrome/browser/segmentation_platform/model/segmentation_platform_service_factory_unittest.mm
index 9893ec68..ca1a85e9 100644
--- a/ios/chrome/browser/segmentation_platform/model/segmentation_platform_service_factory_unittest.mm
+++ b/ios/chrome/browser/segmentation_platform/model/segmentation_platform_service_factory_unittest.mm
@@ -191,7 +191,7 @@
       const PredictionOptions& prediction_options,
       scoped_refptr<InputContext> input_context,
       PredictionStatus expected_status,
-      absl::optional<std::vector<std::string>> expected_labels) {
+      std::optional<std::vector<std::string>> expected_labels) {
     base::RunLoop loop;
     profile_->service->GetClassificationResult(
         segmentation_key, prediction_options, input_context,
@@ -205,7 +205,7 @@
   void OnGetClassificationResult(
       base::RepeatingClosure closure,
       PredictionStatus expected_status,
-      absl::optional<std::vector<std::string>> expected_labels,
+      std::optional<std::vector<std::string>> expected_labels,
       const ClassificationResult& actual_result) {
     EXPECT_EQ(actual_result.status, expected_status);
     if (expected_labels.has_value()) {
diff --git a/ios/chrome/browser/segmentation_platform/model/ukm_data_manager_test_utils.mm b/ios/chrome/browser/segmentation_platform/model/ukm_data_manager_test_utils.mm
index 458b15a..567c0a4 100644
--- a/ios/chrome/browser/segmentation_platform/model/ukm_data_manager_test_utils.mm
+++ b/ios/chrome/browser/segmentation_platform/model/ukm_data_manager_test_utils.mm
@@ -43,18 +43,17 @@
 
 // Runs the given query and returns the result as float value. See
 // RunReadonlyQueries() for more info.
-absl::optional<float> RunQueryAndGetResult(
-    UkmDatabase* database,
-    UkmDatabase::CustomSqlQuery&& query) {
-  absl::optional<float> output;
+std::optional<float> RunQueryAndGetResult(UkmDatabase* database,
+                                          UkmDatabase::CustomSqlQuery&& query) {
+  std::optional<float> output;
   UkmDatabase::QueryList queries;
   queries.emplace(0, std::move(query));
   base::RunLoop wait_for_query;
   database->RunReadonlyQueries(
       std::move(queries),
       base::BindOnce(
-          [](base::OnceClosure quit, absl::optional<float>* output,
-             bool success, processing::IndexedTensors tensor) {
+          [](base::OnceClosure quit, std::optional<float>* output, bool success,
+             processing::IndexedTensors tensor) {
             if (success) {
               EXPECT_EQ(1u, tensor.size());
               EXPECT_EQ(1u, tensor.at(0).size());
@@ -178,7 +177,7 @@
 bool UkmDataManagerTestUtils::IsUrlInDatabase(const GURL& url) {
   UkmDatabase::CustomSqlQuery query("SELECT 1 FROM urls WHERE url=?",
                                     {processing::ProcessedValue(url.spec())});
-  absl::optional<float> result = RunQueryAndGetResult(
+  std::optional<float> result = RunQueryAndGetResult(
       ukm_database_client_->GetUkmDataManager()->GetUkmDatabase(),
       std::move(query));
   return !!result;
diff --git a/ios/chrome/browser/sync/model/prefs/ios_chrome_syncable_prefs_database_unittest.cc b/ios/chrome/browser/sync/model/prefs/ios_chrome_syncable_prefs_database_unittest.cc
index 710cb713..2cdc21a 100644
--- a/ios/chrome/browser/sync/model/prefs/ios_chrome_syncable_prefs_database_unittest.cc
+++ b/ios/chrome/browser/sync/model/prefs/ios_chrome_syncable_prefs_database_unittest.cc
@@ -10,7 +10,7 @@
 namespace {
 
 TEST(IOSChromeSyncablePrefsDatabaseTest, CheckMetricsEnum) {
-  absl::optional<base::HistogramEnumEntryMap> syncable_pref_enums =
+  std::optional<base::HistogramEnumEntryMap> syncable_pref_enums =
       base::ReadEnumFromEnumsXml("SyncablePref", "sync");
 
   ASSERT_TRUE(syncable_pref_enums.has_value())
diff --git a/ios/chrome/browser/ui/policy/idle/idle_timeout_policy_utils.h b/ios/chrome/browser/ui/policy/idle/idle_timeout_policy_utils.h
index a3dd0a9..7afb451 100644
--- a/ios/chrome/browser/ui/policy/idle/idle_timeout_policy_utils.h
+++ b/ios/chrome/browser/ui/policy/idle/idle_timeout_policy_utils.h
@@ -5,9 +5,10 @@
 #ifndef IOS_CHROME_BROWSER_UI_POLICY_IDLE_IDLE_TIMEOUT_POLICY_UTILS_H_
 #define IOS_CHROME_BROWSER_UI_POLICY_IDLE_IDLE_TIMEOUT_POLICY_UTILS_H_
 
+#import <optional>
+
 #import "base/containers/flat_set.h"
 #import "ios/chrome/browser/enterprise/model/idle/idle_timeout_policy_utils.h"
-#import "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace enterprise_idle {
 
diff --git a/ios/chrome/browser/ui/policy/idle/idle_timeout_policy_utils.mm b/ios/chrome/browser/ui/policy/idle/idle_timeout_policy_utils.mm
index 1ec5737..eb44289 100644
--- a/ios/chrome/browser/ui/policy/idle/idle_timeout_policy_utils.mm
+++ b/ios/chrome/browser/ui/policy/idle/idle_timeout_policy_utils.mm
@@ -11,7 +11,7 @@
 
 namespace enterprise_idle {
 
-absl::optional<int> GetIdleTimeoutActionsTitleId(ActionSet actions) {
+std::optional<int> GetIdleTimeoutActionsTitleId(ActionSet actions) {
   if (actions.clear && actions.close && actions.signout) {
     return IDS_IOS_IDLE_TIMEOUT_ALL_ACTIONS_TITLE;
   }
@@ -42,7 +42,7 @@
                        : IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITHOUT_CLEAR_DATA;
 }
 
-absl::optional<int> GetIdleTimeoutActionsSnackbarMessageId(ActionSet actions) {
+std::optional<int> GetIdleTimeoutActionsSnackbarMessageId(ActionSet actions) {
   if (actions.clear && actions.close && actions.signout) {
     return IDS_IOS_IDLE_TIMEOUT_ALL_ACTIONS_SNACKBAR_MESSAGE;
   }
diff --git a/media/gpu/windows/d3d11_video_decoder_wrapper.cc b/media/gpu/windows/d3d11_video_decoder_wrapper.cc
index ef03598..96f03b97 100644
--- a/media/gpu/windows/d3d11_video_decoder_wrapper.cc
+++ b/media/gpu/windows/d3d11_video_decoder_wrapper.cc
@@ -53,14 +53,14 @@
     }
   }
 
-  absl::optional<bool> UseSingleTexture() const override {
+  std::optional<bool> UseSingleTexture() const override {
     D3D11_VIDEO_DECODER_DESC desc;
     D3D11_VIDEO_DECODER_CONFIG config;
     HRESULT hr = video_decoder_->GetCreationParameters(&desc, &config);
     if (FAILED(hr)) {
       RecordFailure("D3D11VideoDecoder GetCreationParameters failed",
                     D3D11StatusCode::kDecoderGetCreationParametersFailed, hr);
-      return absl::nullopt;
+      return std::nullopt;
     }
     // Prefer whatever the config tells us about whether to use one Texture2D
     // with multiple array slices, or multiple Texture2Ds with one slice each.
diff --git a/media/gpu/windows/d3d12_video_decoder_wrapper.cc b/media/gpu/windows/d3d12_video_decoder_wrapper.cc
index 6ea9dc6..d1d8cfe2 100644
--- a/media/gpu/windows/d3d12_video_decoder_wrapper.cc
+++ b/media/gpu/windows/d3d12_video_decoder_wrapper.cc
@@ -68,7 +68,7 @@
 
   ~D3D12VideoDecoderWrapperImpl() override = default;
 
-  absl::optional<bool> UseSingleTexture() const override { return true; }
+  std::optional<bool> UseSingleTexture() const override { return true; }
 
   void Reset() override {
     picture_parameters_buffer_.clear();
diff --git a/media/gpu/windows/d3d_video_decoder_wrapper.h b/media/gpu/windows/d3d_video_decoder_wrapper.h
index 5fc4eb1..66b93b65 100644
--- a/media/gpu/windows/d3d_video_decoder_wrapper.h
+++ b/media/gpu/windows/d3d_video_decoder_wrapper.h
@@ -36,7 +36,7 @@
 
   // Get whether single video decoder texture is recommended by the driver.
   // Returns whether this operation succeeds.
-  virtual absl::optional<bool> UseSingleTexture() const = 0;
+  virtual std::optional<bool> UseSingleTexture() const = 0;
 
   // Clear all internal states.
   virtual void Reset() = 0;
diff --git a/media/muxers/mp4_muxer_delegate.h b/media/muxers/mp4_muxer_delegate.h
index 37725f2..06e71aa 100644
--- a/media/muxers/mp4_muxer_delegate.h
+++ b/media/muxers/mp4_muxer_delegate.h
@@ -135,9 +135,9 @@
   int audio_sample_rate_ = 0;
 
   // Flush for startup is only called once.
-  absl::optional<size_t> written_file_type_box_size_;
+  std::optional<size_t> written_file_type_box_size_;
 
-  absl::optional<size_t> written_mov_box_size_;
+  std::optional<size_t> written_mov_box_size_;
 
   uint32_t sequence_number_ = 1;
 
diff --git a/media/video/software_video_encoder_test.cc b/media/video/software_video_encoder_test.cc
index 2fefe15..f1689812 100644
--- a/media/video/software_video_encoder_test.cc
+++ b/media/video/software_video_encoder_test.cc
@@ -600,7 +600,7 @@
 
   VideoEncoder::OutputCB encoder_output_cb = base::BindLambdaForTesting(
       [&, this](VideoEncoderOutput output,
-                absl::optional<VideoEncoder::CodecDescription> desc) {
+                std::optional<VideoEncoder::CodecDescription> desc) {
         if (output.size == 0) {
           dropped_frames_count++;
           dropped_frame_timestamps.push_back(output.timestamp);
diff --git a/net/http/http_stream_factory_job.cc b/net/http/http_stream_factory_job.cc
index f3956d5..9b265e8d 100644
--- a/net/http/http_stream_factory_job.cc
+++ b/net/http/http_stream_factory_job.cc
@@ -917,11 +917,11 @@
   // supported, but when it is we can remove this CHECK.
   CHECK(proxy_info_.proxy_chain().is_direct());
 
-  absl::optional<NetworkTrafficAnnotationTag> traffic_annotation =
+  std::optional<NetworkTrafficAnnotationTag> traffic_annotation =
       proxy_info_.traffic_annotation().is_valid()
-          ? absl::make_optional<NetworkTrafficAnnotationTag>(
+          ? std::make_optional<NetworkTrafficAnnotationTag>(
                 proxy_info_.traffic_annotation())
-          : absl::nullopt;
+          : std::nullopt;
   int rv = quic_request_.Request(
       destination_, quic_version_, proxy_info_.proxy_chain(),
       std::move(traffic_annotation), SessionUsage::kDestination,
diff --git a/remoting/codec/webrtc_video_encoder_gpu.cc b/remoting/codec/webrtc_video_encoder_gpu.cc
index 4f1b9874..5226d347 100644
--- a/remoting/codec/webrtc_video_encoder_gpu.cc
+++ b/remoting/codec/webrtc_video_encoder_gpu.cc
@@ -275,8 +275,7 @@
     uint32_t bitrate_bps =
         checked_bitrate.ValueOrDefault(std::numeric_limits<uint32_t>::max());
     video_encode_accelerator_->RequestEncodingParametersChange(
-        media::Bitrate::ConstantBitrate(bitrate_bps), params.fps,
-        absl::nullopt);
+        media::Bitrate::ConstantBitrate(bitrate_bps), params.fps, std::nullopt);
   }
   video_encode_accelerator_->Encode(video_frame, params.key_frame);
 }
diff --git a/remoting/host/chromeos/remote_support_host_ash.cc b/remoting/host/chromeos/remote_support_host_ash.cc
index 7e61755..41ede01d 100644
--- a/remoting/host/chromeos/remote_support_host_ash.cc
+++ b/remoting/host/chromeos/remote_support_host_ash.cc
@@ -192,7 +192,7 @@
     SessionId session_id,
     const std::string& access_token,
     StartSessionCallback callback,
-    absl::optional<base::Value::Dict> session) {
+    std::optional<base::Value::Dict> session) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (!session.has_value()) {
diff --git a/remoting/host/chromeos/remote_support_host_ash.h b/remoting/host/chromeos/remote_support_host_ash.h
index 28fbe7e..8337261 100644
--- a/remoting/host/chromeos/remote_support_host_ash.h
+++ b/remoting/host/chromeos/remote_support_host_ash.h
@@ -81,7 +81,7 @@
   void OnSessionRetrieved(SessionId session_id,
                           const std::string& access_token,
                           StartSessionCallback callback,
-                          absl::optional<base::Value::Dict> session);
+                          std::optional<base::Value::Dict> session);
 
   SEQUENCE_CHECKER(sequence_checker_);
 
diff --git a/remoting/host/chromeos/remote_support_host_ash_unittest.cc b/remoting/host/chromeos/remote_support_host_ash_unittest.cc
index 10e9f80..e04f0680 100644
--- a/remoting/host/chromeos/remote_support_host_ash_unittest.cc
+++ b/remoting/host/chromeos/remote_support_host_ash_unittest.cc
@@ -71,7 +71,7 @@
   }
   void Disconnect() override {}
 
-  absl::optional<ReconnectParams> CreateReconnectParams() const override {
+  std::optional<ReconnectParams> CreateReconnectParams() const override {
     if (is_enterprise_session() && enterprise_params().allow_reconnections) {
       ReconnectParams reconnect_params;
       reconnect_params.support_id = "1234567";
@@ -83,7 +83,7 @@
           "/chromoting_ftl_11111111-2222-3333-4444-555555555555";
       return reconnect_params;
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   bool WaitForConnectCall() {
diff --git a/remoting/host/it2me/it2me_host.cc b/remoting/host/it2me/it2me_host.cc
index 5897f744..ffba0885 100644
--- a/remoting/host/it2me/it2me_host.cc
+++ b/remoting/host/it2me/it2me_host.cc
@@ -125,8 +125,8 @@
 #endif
 }
 
-absl::optional<ReconnectParams> It2MeHost::CreateReconnectParams() const {
-  absl::optional<ReconnectParams> reconnect_params;
+std::optional<ReconnectParams> It2MeHost::CreateReconnectParams() const {
+  std::optional<ReconnectParams> reconnect_params;
 #if BUILDFLAG(IS_CHROMEOS_ASH) || !defined(NDEBUG)
   if (!SessionSupportsReconnections()) {
     return reconnect_params;
diff --git a/remoting/host/it2me/it2me_host.h b/remoting/host/it2me/it2me_host.h
index 3439d9d..2e9e8446 100644
--- a/remoting/host/it2me/it2me_host.h
+++ b/remoting/host/it2me/it2me_host.h
@@ -118,7 +118,7 @@
 
   // Creates a new ReconnectParams struct if reconnections are allowed and the
   // remote client has connected, otherwise an empty optional is returned.
-  virtual absl::optional<ReconnectParams> CreateReconnectParams() const;
+  virtual std::optional<ReconnectParams> CreateReconnectParams() const;
 
   // Creates It2Me host structures and starts the host.
   virtual void Connect(
@@ -226,7 +226,7 @@
 
   It2MeHostState state_ = It2MeHostState::kDisconnected;
 
-  absl::optional<ReconnectParams> reconnect_params_;
+  std::optional<ReconnectParams> reconnect_params_;
 
   std::string support_id_;
   std::string host_secret_;
diff --git a/remoting/host/it2me/it2me_native_messaging_host.cc b/remoting/host/it2me/it2me_native_messaging_host.cc
index 5a52541a..13c0f6c 100644
--- a/remoting/host/it2me/it2me_native_messaging_host.cc
+++ b/remoting/host/it2me/it2me_native_messaging_host.cc
@@ -329,7 +329,7 @@
     }
   }
 
-  absl::optional<ReconnectParams> reconnect_params;
+  std::optional<ReconnectParams> reconnect_params;
 #if BUILDFLAG(IS_CHROMEOS_ASH) || !defined(NDEBUG)
   bool is_enterprise_admin_user =
       message.FindBool(kIsEnterpriseAdminUser).value_or(false);
diff --git a/remoting/host/passthrough_register_support_host_request.cc b/remoting/host/passthrough_register_support_host_request.cc
index 039fd3c..be6706d7 100644
--- a/remoting/host/passthrough_register_support_host_request.cc
+++ b/remoting/host/passthrough_register_support_host_request.cc
@@ -24,7 +24,7 @@
     SignalStrategy* signal_strategy,
     scoped_refptr<RsaKeyPair> key_pair,
     const std::string& authorized_helper,
-    absl::optional<ChromeOsEnterpriseParams> params,
+    std::optional<ChromeOsEnterpriseParams> params,
     RegisterCallback callback) {
   signal_strategy_ = signal_strategy;
   callback_ = std::move(callback);
diff --git a/remoting/host/passthrough_register_support_host_request.h b/remoting/host/passthrough_register_support_host_request.h
index 2ee2679..2fe716a 100644
--- a/remoting/host/passthrough_register_support_host_request.h
+++ b/remoting/host/passthrough_register_support_host_request.h
@@ -5,6 +5,8 @@
 #ifndef REMOTING_HOST_PASSTHROUGH_REGISTER_SUPPORT_HOST_REQUEST_H_
 #define REMOTING_HOST_PASSTHROUGH_REGISTER_SUPPORT_HOST_REQUEST_H_
 
+#include <optional>
+
 #include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
@@ -12,7 +14,6 @@
 #include "remoting/host/register_support_host_request.h"
 #include "remoting/protocol/errors.h"
 #include "remoting/signaling/signal_strategy.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -40,7 +41,7 @@
   void StartRequest(SignalStrategy* signal_strategy,
                     scoped_refptr<RsaKeyPair> key_pair,
                     const std::string& authorized_helper,
-                    absl::optional<ChromeOsEnterpriseParams> params,
+                    std::optional<ChromeOsEnterpriseParams> params,
                     RegisterCallback callback) override;
 
  private:
diff --git a/services/device/compute_pressure/cpu_probe_manager_unittest.cc b/services/device/compute_pressure/cpu_probe_manager_unittest.cc
index d6e0dc95..be734d4 100644
--- a/services/device/compute_pressure/cpu_probe_manager_unittest.cc
+++ b/services/device/compute_pressure/cpu_probe_manager_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <cstddef>
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "base/check_op.h"
@@ -20,7 +21,6 @@
 #include "components/system_cpu/pressure_test_support.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace device {
 
@@ -100,7 +100,7 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   static_cast<FakeCpuProbe*>(cpu_probe_manager_->GetCpuProbeForTesting())
-      ->SetLastSample(absl::make_optional(CpuSample{0.9}));
+      ->SetLastSample(std::make_optional(CpuSample{0.9}));
   cpu_probe_manager_->EnsureStarted();
   WaitForUpdate();
 
diff --git a/services/network/ip_protection/ip_protection_config_cache_impl_unittest.cc b/services/network/ip_protection/ip_protection_config_cache_impl_unittest.cc
index 2c7fedd..117742f 100644
--- a/services/network/ip_protection/ip_protection_config_cache_impl_unittest.cc
+++ b/services/network/ip_protection/ip_protection_config_cache_impl_unittest.cc
@@ -167,7 +167,7 @@
   std::string proxy = "a-proxy";
   auto ip_protection_proxy_chain =
       net::ProxyChain::ForIpProtection({net::ProxyServer::FromSchemeHostAndPort(
-          net::ProxyServer::SCHEME_HTTPS, proxy, absl::nullopt)});
+          net::ProxyServer::SCHEME_HTTPS, proxy, std::nullopt)});
   const std::vector<net::ProxyChain> proxy_chain_list = {
       std::move(ip_protection_proxy_chain)};
   auto ipp_proxy_list_manager_ =
diff --git a/services/network/ip_protection/ip_protection_proxy_delegate.cc b/services/network/ip_protection/ip_protection_proxy_delegate.cc
index 889dbad9..d7885ed 100644
--- a/services/network/ip_protection/ip_protection_proxy_delegate.cc
+++ b/services/network/ip_protection/ip_protection_proxy_delegate.cc
@@ -162,7 +162,7 @@
     const GURL& url,
     const net::NetworkAnonymizationKey& network_anonymization_key) const {
   auto dvlog = [&](std::string message) {
-    absl::optional<net::SchemefulSite> top_frame_site =
+    std::optional<net::SchemefulSite> top_frame_site =
         network_anonymization_key.GetTopFrameSite();
     DVLOG(3) << "IPPD::CheckEligibility(" << url << ", "
              << (top_frame_site.has_value() ? top_frame_site.value()
@@ -186,7 +186,7 @@
     const GURL& url,
     const net::NetworkAnonymizationKey& network_anonymization_key) const {
   auto dvlog = [&](std::string message) {
-    absl::optional<net::SchemefulSite> top_frame_site =
+    std::optional<net::SchemefulSite> top_frame_site =
         network_anonymization_key.GetTopFrameSite();
     DVLOG(3) << "IPPD::CheckAvailability(" << url << ", "
              << (top_frame_site.has_value() ? top_frame_site.value()
diff --git a/services/network/p2p/socket.cc b/services/network/p2p/socket.cc
index 018afd0..7641e3d 100644
--- a/services/network/p2p/socket.cc
+++ b/services/network/p2p/socket.cc
@@ -137,7 +137,7 @@
     net::NetLog* net_log,
     ProxyResolvingClientSocketFactory* proxy_resolving_socket_factory,
     P2PMessageThrottler* throttler,
-    absl::optional<base::UnguessableToken> devtools_token) {
+    std::optional<base::UnguessableToken> devtools_token) {
   switch (type) {
     case P2P_SOCKET_UDP:
       return std::make_unique<P2PSocketUdp>(
diff --git a/services/network/p2p/socket.h b/services/network/p2p/socket.h
index b10e1f3c..c3e2f8c 100644
--- a/services/network/p2p/socket.h
+++ b/services/network/p2p/socket.h
@@ -70,7 +70,7 @@
       net::NetLog* net_log,
       ProxyResolvingClientSocketFactory* proxy_resolving_socket_factory,
       P2PMessageThrottler* throttler,
-      absl::optional<base::UnguessableToken> devtools_token);
+      std::optional<base::UnguessableToken> devtools_token);
 
   P2PSocket(const P2PSocket&) = delete;
   P2PSocket& operator=(const P2PSocket&) = delete;
diff --git a/services/network/p2p/socket_manager.cc b/services/network/p2p/socket_manager.cc
index f187044..bea2318 100644
--- a/services/network/p2p/socket_manager.cc
+++ b/services/network/p2p/socket_manager.cc
@@ -423,7 +423,7 @@
     const P2PPortRange& port_range,
     const P2PHostAndIPEndPoint& remote_address,
     const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
-    const absl::optional<base::UnguessableToken>& devtools_token,
+    const std::optional<base::UnguessableToken>& devtools_token,
     mojo::PendingRemote<mojom::P2PSocketClient> client,
     mojo::PendingReceiver<mojom::P2PSocket> receiver) {
   if (port_range.min_port > port_range.max_port ||
diff --git a/services/network/p2p/socket_manager.h b/services/network/p2p/socket_manager.h
index 080db58..cd3e15b 100644
--- a/services/network/p2p/socket_manager.h
+++ b/services/network/p2p/socket_manager.h
@@ -139,7 +139,7 @@
       const P2PPortRange& port_range,
       const P2PHostAndIPEndPoint& remote_address,
       const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
-      const absl::optional<base::UnguessableToken>& devtools_token,
+      const std::optional<base::UnguessableToken>& devtools_token,
       mojo::PendingRemote<mojom::P2PSocketClient> client,
       mojo::PendingReceiver<mojom::P2PSocket> receiver) override;
 
diff --git a/services/network/p2p/socket_udp.cc b/services/network/p2p/socket_udp.cc
index 584b268..a4c09ed 100644
--- a/services/network/p2p/socket_udp.cc
+++ b/services/network/p2p/socket_udp.cc
@@ -111,7 +111,7 @@
     const net::NetworkTrafficAnnotationTag& traffic_annotation,
     net::NetLog* net_log,
     const DatagramServerSocketFactory& socket_factory,
-    absl::optional<base::UnguessableToken> devtools_token)
+    std::optional<base::UnguessableToken> devtools_token)
     : P2PSocket(Delegate, std::move(client), std::move(socket), P2PSocket::UDP),
       throttler_(throttler),
       traffic_annotation_(traffic_annotation),
@@ -135,7 +135,7 @@
     P2PMessageThrottler* throttler,
     const net::NetworkTrafficAnnotationTag& traffic_annotation,
     net::NetLog* net_log,
-    absl::optional<base::UnguessableToken> devtools_token)
+    std::optional<base::UnguessableToken> devtools_token)
     : P2PSocketUdp(Delegate,
                    std::move(client),
                    std::move(socket),
diff --git a/services/network/p2p/socket_udp.h b/services/network/p2p/socket_udp.h
index d08f980..52d63dec 100644
--- a/services/network/p2p/socket_udp.h
+++ b/services/network/p2p/socket_udp.h
@@ -71,14 +71,14 @@
                const net::NetworkTrafficAnnotationTag& traffic_annotation,
                net::NetLog* net_log,
                const DatagramServerSocketFactory& socket_factory,
-               absl::optional<base::UnguessableToken> devtools_token);
+               std::optional<base::UnguessableToken> devtools_token);
   P2PSocketUdp(Delegate* delegate,
                mojo::PendingRemote<mojom::P2PSocketClient> client,
                mojo::PendingReceiver<mojom::P2PSocket> socket,
                P2PMessageThrottler* throttler,
                const net::NetworkTrafficAnnotationTag& traffic_annotation,
                net::NetLog* net_log,
-               absl::optional<base::UnguessableToken> devtools_token);
+               std::optional<base::UnguessableToken> devtools_token);
 
   P2PSocketUdp(const P2PSocketUdp&) = delete;
   P2PSocketUdp& operator=(const P2PSocketUdp&) = delete;
diff --git a/services/network/shared_dictionary/shared_dictionary_network_transaction.cc b/services/network/shared_dictionary/shared_dictionary_network_transaction.cc
index 66f31e68a..a07f403 100644
--- a/services/network/shared_dictionary/shared_dictionary_network_transaction.cc
+++ b/services/network/shared_dictionary/shared_dictionary_network_transaction.cc
@@ -274,7 +274,7 @@
   }
 
   if (!shared_dictionary_->id().empty()) {
-    absl::optional<std::string> serialized_id =
+    std::optional<std::string> serialized_id =
         net::structured_headers::SerializeItem(shared_dictionary_->id());
     if (serialized_id) {
       request_headers->SetHeader("Dictionary-ID", *serialized_id);
diff --git a/services/network/shared_dictionary/simple_url_pattern_matcher_unittest.cc b/services/network/shared_dictionary/simple_url_pattern_matcher_unittest.cc
index 6542d4c..5174f73c 100644
--- a/services/network/shared_dictionary/simple_url_pattern_matcher_unittest.cc
+++ b/services/network/shared_dictionary/simple_url_pattern_matcher_unittest.cc
@@ -151,10 +151,9 @@
   struct {
     std::string_view constructor_string;
     std::string_view base_url;
-    absl::optional<
-        testing::Matcher<const SimpleUrlPatternMatcher::PatternInit&>>
+    std::optional<testing::Matcher<const SimpleUrlPatternMatcher::PatternInit&>>
         expected_pattern;
-    absl::optional<std::string_view> expected_error;
+    std::optional<std::string_view> expected_error;
     std::vector<std::string_view> match_urls;
     std::vector<std::string_view> non_match_urls;
   } test_cases[] = {
@@ -165,11 +164,11 @@
       {.constructor_string = "/foo",
        .base_url = "https://example.com/foo/bar.html",
        .expected_pattern = ExpectPatternInit(
-           /*protocol=*/"https", /*username=*/absl::nullopt,
-           /*password=*/absl::nullopt, /*hostname=*/"example.com",
+           /*protocol=*/"https", /*username=*/std::nullopt,
+           /*password=*/std::nullopt, /*hostname=*/"example.com",
            /*port=*/"", /*pathname=*/"/foo",
-           /*search=*/absl::nullopt,
-           /*hash=*/absl::nullopt),
+           /*search=*/std::nullopt,
+           /*hash=*/std::nullopt),
        .match_urls = {"https://example.com/foo", "https://example.com/foo?bar"},
        .non_match_urls = {"https://example.com/bar", "https://example.com/foo/",
                           "https://example.com/foo/baz"}},
@@ -178,11 +177,11 @@
       {.constructor_string = "/foo/",
        .base_url = "https://example.com/foo/bar.html",
        .expected_pattern = ExpectPatternInit(
-           /*protocol=*/"https", /*username=*/absl::nullopt,
-           /*password=*/absl::nullopt, /*hostname=*/"example.com",
+           /*protocol=*/"https", /*username=*/std::nullopt,
+           /*password=*/std::nullopt, /*hostname=*/"example.com",
            /*port=*/"", /*pathname=*/"/foo/",
-           /*search=*/absl::nullopt,
-           /*hash=*/absl::nullopt),
+           /*search=*/std::nullopt,
+           /*hash=*/std::nullopt),
        .match_urls = {"https://example.com/foo/",
                       "https://example.com/foo/?bar"},
        .non_match_urls = {"https://example.com/foo",
@@ -193,11 +192,11 @@
       {.constructor_string = "hoge",
        .base_url = "https://example.com/foo/bar.html",
        .expected_pattern = ExpectPatternInit(
-           /*protocol=*/"https", /*username=*/absl::nullopt,
-           /*password=*/absl::nullopt, /*hostname=*/"example.com",
+           /*protocol=*/"https", /*username=*/std::nullopt,
+           /*password=*/std::nullopt, /*hostname=*/"example.com",
            /*port=*/"", /*pathname=*/"/foo/hoge",
-           /*search=*/absl::nullopt,
-           /*hash=*/absl::nullopt),
+           /*search=*/std::nullopt,
+           /*hash=*/std::nullopt),
        .match_urls = {"https://example.com/foo/hoge",
                       "https://example.com/foo/hoge?bar"},
        .non_match_urls = {"https://example.com/hoge",
@@ -207,11 +206,11 @@
       {.constructor_string = "hoge/",
        .base_url = "https://example.com/foo/bar.html",
        .expected_pattern = ExpectPatternInit(
-           /*protocol=*/"https", /*username=*/absl::nullopt,
-           /*password=*/absl::nullopt, /*hostname=*/"example.com",
+           /*protocol=*/"https", /*username=*/std::nullopt,
+           /*password=*/std::nullopt, /*hostname=*/"example.com",
            /*port=*/"", /*pathname=*/"/foo/hoge/",
-           /*search=*/absl::nullopt,
-           /*hash=*/absl::nullopt),
+           /*search=*/std::nullopt,
+           /*hash=*/std::nullopt),
        .match_urls = {"https://example.com/foo/hoge/",
                       "https://example.com/foo/hoge/?bar"},
        .non_match_urls = {"https://example.com/hoge",
@@ -221,11 +220,11 @@
       {.constructor_string = "https://example.com/piyo/fuga",
        .base_url = "https://example.com/foo/bar.html",
        .expected_pattern = ExpectPatternInit(
-           /*protocol=*/"https", /*username=*/absl::nullopt,
-           /*password=*/absl::nullopt, /*hostname=*/"example.com",
+           /*protocol=*/"https", /*username=*/std::nullopt,
+           /*password=*/std::nullopt, /*hostname=*/"example.com",
            /*port=*/"", /*pathname=*/"/piyo/fuga",
-           /*search=*/absl::nullopt,
-           /*hash=*/absl::nullopt),
+           /*search=*/std::nullopt,
+           /*hash=*/std::nullopt),
        .match_urls = {"https://example.com/piyo/fuga",
                       "https://example.com/piyo/fuga?bar"},
        .non_match_urls = {"https://example.com/foo/",
@@ -236,11 +235,11 @@
       {.constructor_string = "https://example.net/piyo/fuga",
        .base_url = "https://example.com/foo/bar.html",
        .expected_pattern = ExpectPatternInit(
-           /*protocol=*/"https", /*username=*/absl::nullopt,
-           /*password=*/absl::nullopt, /*hostname=*/"example.net",
+           /*protocol=*/"https", /*username=*/std::nullopt,
+           /*password=*/std::nullopt, /*hostname=*/"example.net",
            /*port=*/"", /*pathname=*/"/piyo/fuga",
-           /*search=*/absl::nullopt,
-           /*hash=*/absl::nullopt),
+           /*search=*/std::nullopt,
+           /*hash=*/std::nullopt),
        .match_urls = {"https://example.net/piyo/fuga",
                       "https://example.net/piyo/fuga?bar"},
        .non_match_urls = {"https://example.com/foo/",
@@ -250,11 +249,11 @@
       {.constructor_string = "https://example.com:443/piyo/fuga",
        .base_url = "https://example.com/foo/bar.html",
        .expected_pattern = ExpectPatternInit(
-           /*protocol=*/"https", /*username=*/absl::nullopt,
-           /*password=*/absl::nullopt, /*hostname=*/"example.com",
+           /*protocol=*/"https", /*username=*/std::nullopt,
+           /*password=*/std::nullopt, /*hostname=*/"example.com",
            /*port=*/"", /*pathname=*/"/piyo/fuga",
-           /*search=*/absl::nullopt,
-           /*hash=*/absl::nullopt),
+           /*search=*/std::nullopt,
+           /*hash=*/std::nullopt),
        .match_urls = {"https://example.com/piyo/fuga",
                       "https://example.com:443/piyo/fuga"},
        .non_match_urls = {"https://example.com:444/piyo/fuga/",
@@ -264,11 +263,11 @@
       {.constructor_string = "https://example.com:444/piyo/fuga",
        .base_url = "https://example.com/foo/bar.html",
        .expected_pattern = ExpectPatternInit(
-           /*protocol=*/"https", /*username=*/absl::nullopt,
-           /*password=*/absl::nullopt, /*hostname=*/"example.com",
+           /*protocol=*/"https", /*username=*/std::nullopt,
+           /*password=*/std::nullopt, /*hostname=*/"example.com",
            /*port=*/"444", /*pathname=*/"/piyo/fuga",
-           /*search=*/absl::nullopt,
-           /*hash=*/absl::nullopt),
+           /*search=*/std::nullopt,
+           /*hash=*/std::nullopt),
        .match_urls = {"https://example.com:444/piyo/fuga"},
        .non_match_urls = {"https://example.com/piyo/fuga/",
                           "https://example.com:443/piyo/fuga",
@@ -278,11 +277,11 @@
       {.constructor_string = "https://example.com",
        .base_url = "https://example.com/foo/bar.html",
        .expected_pattern = ExpectPatternInit(
-           /*protocol=*/"https", /*username=*/absl::nullopt,
-           /*password=*/absl::nullopt, /*hostname=*/"example.com",
-           /*port=*/"", /*pathname=*/absl::nullopt,
-           /*search=*/absl::nullopt,
-           /*hash=*/absl::nullopt),
+           /*protocol=*/"https", /*username=*/std::nullopt,
+           /*password=*/std::nullopt, /*hostname=*/"example.com",
+           /*port=*/"", /*pathname=*/std::nullopt,
+           /*search=*/std::nullopt,
+           /*hash=*/std::nullopt),
        .match_urls = {"https://example.com", "https://example.com/piyo/"},
        .non_match_urls = {"https://example.net/"}},
 
@@ -290,11 +289,11 @@
       {.constructor_string = "https://example.com/",
        .base_url = "https://example.com/foo/bar.html",
        .expected_pattern = ExpectPatternInit(
-           /*protocol=*/"https", /*username=*/absl::nullopt,
-           /*password=*/absl::nullopt, /*hostname=*/"example.com",
+           /*protocol=*/"https", /*username=*/std::nullopt,
+           /*password=*/std::nullopt, /*hostname=*/"example.com",
            /*port=*/"", /*pathname=*/"/",
-           /*search=*/absl::nullopt,
-           /*hash=*/absl::nullopt),
+           /*search=*/std::nullopt,
+           /*hash=*/std::nullopt),
        .match_urls = {"https://example.com"},
        .non_match_urls = {"https://example.net/", "https://example.com/piyo/"}},
 
@@ -302,11 +301,11 @@
       {.constructor_string = "hoge?*",
        .base_url = "https://example.com/foo/bar.html",
        .expected_pattern = ExpectPatternInit(
-           /*protocol=*/"https", /*username=*/absl::nullopt,
-           /*password=*/absl::nullopt, /*hostname=*/"example.com",
+           /*protocol=*/"https", /*username=*/std::nullopt,
+           /*password=*/std::nullopt, /*hostname=*/"example.com",
            /*port=*/"", /*pathname=*/"/foo/hoge",
            /*search=*/"*",
-           /*hash=*/absl::nullopt),
+           /*hash=*/std::nullopt),
        .match_urls = {"https://example.com/foo/hoge",
                       "https://example.com/foo/hoge?bar"},
        .non_match_urls = {"https://example.com/hoge",
@@ -316,11 +315,11 @@
       {.constructor_string = "hoge?*",
        .base_url = "non-standard:example.com/foo/bar.html",
        .expected_pattern = ExpectPatternInit(
-           /*protocol=*/"non-standard", /*username=*/absl::nullopt,
-           /*password=*/absl::nullopt, /*hostname=*/"",
+           /*protocol=*/"non-standard", /*username=*/std::nullopt,
+           /*password=*/std::nullopt, /*hostname=*/"",
            /*port=*/"", /*pathname=*/"hoge",
            /*search=*/"*",
-           /*hash=*/absl::nullopt),
+           /*hash=*/std::nullopt),
        .match_urls = {"non-standard:hoge", "non-standard:hoge?bar"},
        .non_match_urls = {"non-standard:example.com/foo/hoge",
                           "non-standard:example.com/foo/hoge?bar"}},
@@ -329,11 +328,11 @@
       {.constructor_string = "https://{:subdomain.}?example.com/piyo/fuga",
        .base_url = "https://example.com/foo/bar.html",
        .expected_pattern = ExpectPatternInit(
-           /*protocol=*/"https", /*username=*/absl::nullopt,
-           /*password=*/absl::nullopt, /*hostname=*/"{:subdomain.}?example.com",
+           /*protocol=*/"https", /*username=*/std::nullopt,
+           /*password=*/std::nullopt, /*hostname=*/"{:subdomain.}?example.com",
            /*port=*/"", /*pathname=*/"/piyo/fuga",
-           /*search=*/absl::nullopt,
-           /*hash=*/absl::nullopt),
+           /*search=*/std::nullopt,
+           /*hash=*/std::nullopt),
        .match_urls = {"https://example.com/piyo/fuga",
                       "https://a.example.com/piyo/fuga"},
        .non_match_urls = {"https://example.net/piyo/fuga"}},
@@ -342,11 +341,11 @@
       {.constructor_string = "\\/piyo\\/fuga",
        .base_url = "https://example.com/foo/bar.html",
        .expected_pattern = ExpectPatternInit(
-           /*protocol=*/"https", /*username=*/absl::nullopt,
-           /*password=*/absl::nullopt, /*hostname=*/"example.com",
+           /*protocol=*/"https", /*username=*/std::nullopt,
+           /*password=*/std::nullopt, /*hostname=*/"example.com",
            /*port=*/"", /*pathname=*/"\\/piyo\\/fuga",
-           /*search=*/absl::nullopt,
-           /*hash=*/absl::nullopt),
+           /*search=*/std::nullopt,
+           /*hash=*/std::nullopt),
        .match_urls = {"https://example.com/piyo/fuga",
                       "https://example.com/piyo/fuga?bar"},
        .non_match_urls = {"https://example.com\\/piyo/fuga"}},
@@ -355,11 +354,11 @@
       {.constructor_string = "hoge/piyo",
        .base_url = "non-standard:",
        .expected_pattern = ExpectPatternInit(
-           /*protocol=*/"non-standard", /*username=*/absl::nullopt,
-           /*password=*/absl::nullopt, /*hostname=*/"",
+           /*protocol=*/"non-standard", /*username=*/std::nullopt,
+           /*password=*/std::nullopt, /*hostname=*/"",
            /*port=*/"", /*pathname=*/"hoge/piyo",
-           /*search=*/absl::nullopt,
-           /*hash=*/absl::nullopt),
+           /*search=*/std::nullopt,
+           /*hash=*/std::nullopt),
        .match_urls = {"non-standard:hoge/piyo", "non-standard:hoge/piyo"},
        .non_match_urls = {"https://hoge/piyo"}},
 
@@ -367,11 +366,11 @@
       {.constructor_string = "",
        .base_url = "https://example.com/foo/bar.html",
        .expected_pattern = ExpectPatternInit(
-           /*protocol=*/"https", /*username=*/absl::nullopt,
-           /*password=*/absl::nullopt, /*hostname=*/"example.com",
+           /*protocol=*/"https", /*username=*/std::nullopt,
+           /*password=*/std::nullopt, /*hostname=*/"example.com",
            /*port=*/"", /*pathname=*/"/foo/",
-           /*search=*/absl::nullopt,
-           /*hash=*/absl::nullopt),
+           /*search=*/std::nullopt,
+           /*hash=*/std::nullopt),
        .match_urls = {"https://example.com/foo/",
                       "https://example.com/foo/?bar"},
        .non_match_urls = {"https://example.com/foo",
diff --git a/services/network/url_loader_unittest.cc b/services/network/url_loader_unittest.cc
index 8945c6d..7c41ff2 100644
--- a/services/network/url_loader_unittest.cc
+++ b/services/network/url_loader_unittest.cc
@@ -4846,7 +4846,7 @@
 
   GURL cookie_url = test_server()->GetURL("/");
   auto cc = net::CanonicalCookie::Create(
-      cookie_url, "a=b", base::Time::Now(), absl::nullopt /* server_time */,
+      cookie_url, "a=b", base::Time::Now(), std::nullopt /* server_time */,
       net::CookiePartitionKey::FromURLForTesting(
           GURL("https://toplevelsite.com")));
   ResourceRequest request = CreateResourceRequest("GET", first_party_url);
@@ -4874,7 +4874,7 @@
 
   GURL cookie_url = test_server()->GetURL("/");
   auto cc = net::CanonicalCookie::Create(
-      cookie_url, "a=b", base::Time::Now(), absl::nullopt /* server_time */,
+      cookie_url, "a=b", base::Time::Now(), std::nullopt /* server_time */,
       net::CookiePartitionKey::FromURLForTesting(
           GURL("https://toplevelsite.com")));
   ResourceRequest request = CreateResourceRequest("GET", first_party_url);
@@ -4902,7 +4902,7 @@
 
   GURL cookie_url = test_server()->GetURL("/");
   auto cc = net::CanonicalCookie::Create(
-      cookie_url, "a=b", base::Time::Now(), absl::nullopt /* server_time */,
+      cookie_url, "a=b", base::Time::Now(), std::nullopt /* server_time */,
       net::CookiePartitionKey::FromURLForTesting(
           GURL("https://toplevelsite.com")));
   ResourceRequest request = CreateResourceRequest("GET", first_party_url);
diff --git a/services/webnn/coreml/graph_impl.h b/services/webnn/coreml/graph_impl.h
index 555e97f..48a4d2f 100644
--- a/services/webnn/coreml/graph_impl.h
+++ b/services/webnn/coreml/graph_impl.h
@@ -51,7 +51,7 @@
   static MLFeatureValue* CreateFeatureValue(
       GraphImpl::CoreMLFeatureInfo* feature_info,
       mojo_base::BigBuffer data);
-  static absl::optional<CoreMLFeatureInfo> GetCoreMLFeatureInfo(
+  static std::optional<CoreMLFeatureInfo> GetCoreMLFeatureInfo(
       const GraphBuilder::OperandInfo* operand_info);
   using CoreMLFeatureInfoMap = base::flat_map<std::string, CoreMLFeatureInfo>;
   GraphImpl(
diff --git a/services/webnn/coreml/graph_impl.mm b/services/webnn/coreml/graph_impl.mm
index dfcd5cb..1c644a08 100644
--- a/services/webnn/coreml/graph_impl.mm
+++ b/services/webnn/coreml/graph_impl.mm
@@ -236,7 +236,7 @@
 }
 
 // static
-absl::optional<GraphImpl::CoreMLFeatureInfo> GraphImpl::GetCoreMLFeatureInfo(
+std::optional<GraphImpl::CoreMLFeatureInfo> GraphImpl::GetCoreMLFeatureInfo(
     const GraphBuilder::OperandInfo* operand_info) {
   CHECK(operand_info);
   enum MLMultiArrayDataType data_type;
@@ -256,7 +256,7 @@
     case webnn::mojom::Operand_DataType::kInt8:
     case webnn::mojom::Operand_DataType::kUint8:
       // Unsupported data types in coreml.
-      return absl::nullopt;
+      return std::nullopt;
   }
   NSMutableArray* shape =
       [[NSMutableArray alloc] initWithCapacity:operand_info->dimensions.size()];
@@ -269,7 +269,7 @@
   if (!expected_size.IsValid()) {
     DLOG(ERROR)
         << "WebNN::CoreML Error GetCoreMLFeatureInfo expected size overflow";
-    return absl::nullopt;
+    return std::nullopt;
   }
   uint32_t current_stride = expected_size.ValueOrDie();
   for (uint32_t dimension : operand_info->dimensions) {
diff --git a/services/webnn/dml/command_recorder_test.cc b/services/webnn/dml/command_recorder_test.cc
index 4c6fa63..dde59e8 100644
--- a/services/webnn/dml/command_recorder_test.cc
+++ b/services/webnn/dml/command_recorder_test.cc
@@ -400,7 +400,7 @@
   // Relu operator initializer deson't need to bind any input and persistent
   // resources.
   EXPECT_HRESULT_SUCCEEDED(command_recorder->InitializeOperator(
-      compiled_operator.Get(), absl::nullopt, absl::nullopt));
+      compiled_operator.Get(), std::nullopt, std::nullopt));
   EXPECT_HRESULT_SUCCEEDED(command_recorder->CloseAndExecute());
   EXPECT_HRESULT_SUCCEEDED(
       command_recorder->GetCommandQueue()->WaitSyncForTesting());
@@ -444,7 +444,7 @@
   // Execute the operator with input and output bindings.
   EXPECT_HRESULT_SUCCEEDED(command_recorder->ExecuteOperator(
       std::move(compiled_operator), descriptor_heap, input_bindings,
-      output_bindings, absl::nullopt, absl::nullopt));
+      output_bindings, std::nullopt, std::nullopt));
 
   // Close, execute and wait for completion.
   ASSERT_HRESULT_SUCCEEDED(command_recorder->CloseAndExecute());
@@ -1121,7 +1121,7 @@
   // Execute the operator with persistent, input and output bindings.
   EXPECT_HRESULT_SUCCEEDED(command_recorder->ExecuteOperator(
       std::move(compiled_operator), descriptor_heap, input_bindings,
-      output_bindings, persistent_buffer_binding_desc, absl::nullopt));
+      output_bindings, persistent_buffer_binding_desc, std::nullopt));
 
   // Close, execute and wait for completion.
   ASSERT_HRESULT_SUCCEEDED(command_recorder->CloseAndExecute());
diff --git a/skia/public/mojom/skcolorspace_mojom_traits.h b/skia/public/mojom/skcolorspace_mojom_traits.h
index ad2a63dd..1a57a65 100644
--- a/skia/public/mojom/skcolorspace_mojom_traits.h
+++ b/skia/public/mojom/skcolorspace_mojom_traits.h
@@ -65,10 +65,10 @@
 
 template <>
 struct StructTraits<skia::mojom::SkColorSpaceDataView, ::sk_sp<SkColorSpace>> {
-  static absl::optional<skcms_TransferFunction> to_linear(
+  static std::optional<skcms_TransferFunction> to_linear(
       const ::sk_sp<SkColorSpace>& in) {
     if (!in) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     skcms_TransferFunction trfn = {
         1.f, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f,
@@ -76,10 +76,10 @@
     in->transferFn(&trfn);
     return trfn;
   }
-  static absl::optional<skcms_Matrix3x3> to_xyzd50(
+  static std::optional<skcms_Matrix3x3> to_xyzd50(
       const ::sk_sp<SkColorSpace>& in) {
     if (!in) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     skcms_Matrix3x3 m = {{{1.f, 0.f, 0.f}, {0.f, 1.f, 0.f}, {0.f, 0.f, 1.f}}};
     // The function toXYZD50 returns a boolean for historical reasons. It will
@@ -91,11 +91,11 @@
 
   static bool Read(skia::mojom::SkColorSpaceDataView data,
                    ::sk_sp<SkColorSpace>* out) {
-    absl::optional<skcms_TransferFunction> to_linear;
+    std::optional<skcms_TransferFunction> to_linear;
     if (!data.ReadToLinear(&to_linear)) {
       return false;
     }
-    absl::optional<skcms_Matrix3x3> to_xyzd50;
+    std::optional<skcms_Matrix3x3> to_xyzd50;
     if (!data.ReadToXyzd50(&to_xyzd50)) {
       return false;
     }
diff --git a/third_party/blink/renderer/core/probe/core_probes.pidl b/third_party/blink/renderer/core/probe/core_probes.pidl
index adbfc98..8eb6291a 100644
--- a/third_party/blink/renderer/core/probe/core_probes.pidl
+++ b/third_party/blink/renderer/core/probe/core_probes.pidl
@@ -95,7 +95,7 @@
   void ApplyAcceptLanguageOverride(CoreProbeSink*, String* accept_language);
   void ApplyHardwareConcurrencyOverride(CoreProbeSink*, unsigned int& hardware_concurrency);
   void ApplyUserAgentOverride(CoreProbeSink*, String* user_agent);
-  void ApplyUserAgentMetadataOverride(CoreProbeSink*, absl::optional<blink::UserAgentMetadata>* ua_metadata_override);
+  void ApplyUserAgentMetadataOverride(CoreProbeSink*, std::optional<blink::UserAgentMetadata>* ua_metadata_override);
   void DidBlockRequest(CoreProbeSink*, const ResourceRequest&, DocumentLoader*, const KURL& fetch_context_url, const ResourceLoaderOptions&, ResourceRequestBlockedReason, ResourceType);
   void DidChangeResourcePriority(LocalFrame*, DocumentLoader*, uint64_t identifier, ResourceLoadPriority load_priority);
   void PrepareRequest(CoreProbeSink*, DocumentLoader*, ResourceRequest&, ResourceLoaderOptions&, ResourceType);
@@ -119,7 +119,7 @@
   void DidReceiveScriptResponse(ExecutionContext*, uint64_t identifier);
   void DomContentLoadedEventFired([Keep] LocalFrame*);
   void LoadEventFired([Keep] LocalFrame*);
-  void FrameAttachedToParent([Keep] LocalFrame*, const absl::optional<AdScriptIdentifier>& ad_script_on_stack);
+  void FrameAttachedToParent([Keep] LocalFrame*, const std::optional<AdScriptIdentifier>& ad_script_on_stack);
   void FrameDetachedFromParent([Keep] LocalFrame*, FrameDetachType);
   void DidStartProvisionalLoad([Keep] LocalFrame*);
   void DidFailProvisionalLoad([Keep] LocalFrame*);
@@ -136,7 +136,7 @@
   void FrameRequestedNavigation(LocalFrame*, Frame* target_frame, const KURL& url, ClientNavigationReason reason, NavigationPolicy policy);
   void FrameScheduledNavigation([Keep] LocalFrame*, const KURL& url, base::TimeDelta delay, ClientNavigationReason reason);
   void FrameClearedScheduledNavigation([Keep] LocalFrame*);
-  void WillCreateWebSocket([Keep] ExecutionContext*, uint64_t identifier, const KURL& request_url, const String& protocol, absl::optional<base::UnguessableToken>* devtools_token);
+  void WillCreateWebSocket([Keep] ExecutionContext*, uint64_t identifier, const KURL& request_url, const String& protocol, std::optional<base::UnguessableToken>* devtools_token);
   void WillSendWebSocketHandshakeRequest([Keep] ExecutionContext*, uint64_t identifier, network::mojom::blink::WebSocketHandshakeRequest* request);
   void DidReceiveWebSocketHandshakeResponse([Keep] ExecutionContext*, uint64_t identifier, network::mojom::blink::WebSocketHandshakeRequest* request, network::mojom::blink::WebSocketHandshakeResponse* response);
   void DidCloseWebSocket([Keep] ExecutionContext*, uint64_t identifier);
@@ -146,7 +146,7 @@
   void WebTransportCreated([Keep] ExecutionContext*, uint64_t transport_id, const KURL& request_url);
   void WebTransportConnectionEstablished(ExecutionContext*, uint64_t transport_id);
   void WebTransportClosed(ExecutionContext*, uint64_t transport_id);
-  void WillCreateP2PSocketUdp(ExecutionContext*, absl::optional<base::UnguessableToken>* devtools_token);
+  void WillCreateP2PSocketUdp(ExecutionContext*, std::optional<base::UnguessableToken>* devtools_token);
   /* This is for pre-BlinkGenPropertyTrees. TODO(wangxianzhu): Remove this function for BlinkGenPropertyTrees. */
   void LayerTreeDidChange(LocalFrame*);
   void LayerTreePainted(LocalFrame*);
diff --git a/third_party/blink/renderer/core/timing/window_performance.cc b/third_party/blink/renderer/core/timing/window_performance.cc
index 8cd4bf2f..cca9b26 100644
--- a/third_party/blink/renderer/core/timing/window_performance.cc
+++ b/third_party/blink/renderer/core/timing/window_performance.cc
@@ -521,7 +521,7 @@
   std::optional<int> key_code = event_data->GetKeyCode();
   std::optional<PointerId> pointer_id = event_data->GetPointerId();
 
-  absl::optional<base::TimeTicks> fallback_time =
+  std::optional<base::TimeTicks> fallback_time =
       GetFallbackTime(entry, event_timestamp, presentation_timestamp);
 
   base::TimeTicks entry_end_timetick =
@@ -621,7 +621,7 @@
   }
 }
 
-absl::optional<base::TimeTicks> WindowPerformance::GetFallbackTime(
+std::optional<base::TimeTicks> WindowPerformance::GetFallbackTime(
     PerformanceEventTiming* entry,
     base::TimeTicks event_timestamp,
     base::TimeTicks presentation_timestamp) {
@@ -682,7 +682,7 @@
   } else if (fallback_end_time_to_processing_end) {
     return processing_end_timetick;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool WindowPerformance::SetInteractionIdAndRecordLatency(
diff --git a/third_party/blink/renderer/core/timing/window_performance.h b/third_party/blink/renderer/core/timing/window_performance.h
index 7c4703c..7399a8f 100644
--- a/third_party/blink/renderer/core/timing/window_performance.h
+++ b/third_party/blink/renderer/core/timing/window_performance.h
@@ -230,7 +230,7 @@
 
   // Return a valid fallback time in event timing if there's one; otherwise
   // return nullopt.
-  absl::optional<base::TimeTicks> GetFallbackTime(
+  std::optional<base::TimeTicks> GetFallbackTime(
       PerformanceEventTiming* entry,
       base::TimeTicks event_timestamp,
       base::TimeTicks presentation_timestamp);
diff --git a/ui/gfx/geometry/transform_unittest.cc b/ui/gfx/geometry/transform_unittest.cc
index e5fe7a7a..68a32aa 100644
--- a/ui/gfx/geometry/transform_unittest.cc
+++ b/ui/gfx/geometry/transform_unittest.cc
@@ -15,7 +15,6 @@
 #include "base/numerics/angle_conversions.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/axis_transform2d.h"
 #include "ui/gfx/geometry/box_f.h"
 #include "ui/gfx/geometry/decomposed_transform.h"
diff --git a/ui/views/controls/menu/menu_runner_impl_mac.h b/ui/views/controls/menu/menu_runner_impl_mac.h
index 799e03fd..db81eab0 100644
--- a/ui/views/controls/menu/menu_runner_impl_mac.h
+++ b/ui/views/controls/menu/menu_runner_impl_mac.h
@@ -40,8 +40,8 @@
       MenuAnchorPosition anchor,
       int32_t run_types,
       gfx::NativeView native_view_for_gestures,
-      absl::optional<gfx::RoundedCornersF> corners,
-      absl::optional<std::string> show_menu_host_duration_histogram) override;
+      std::optional<gfx::RoundedCornersF> corners,
+      std::optional<std::string> show_menu_host_duration_histogram) override;
   void Cancel() override;
   base::TimeTicks GetClosingEventTime() const override;
 
diff --git a/ui/views/controls/menu/menu_runner_impl_mac.mm b/ui/views/controls/menu/menu_runner_impl_mac.mm
index 0fb98f5..27f83d5 100644
--- a/ui/views/controls/menu/menu_runner_impl_mac.mm
+++ b/ui/views/controls/menu/menu_runner_impl_mac.mm
@@ -47,8 +47,8 @@
     MenuAnchorPosition anchor,
     int32_t run_types,
     gfx::NativeView native_view_for_gestures,
-    absl::optional<gfx::RoundedCornersF> corners,
-    absl::optional<std::string> show_menu_host_duration_histogram) {
+    std::optional<gfx::RoundedCornersF> corners,
+    std::optional<std::string> show_menu_host_duration_histogram) {
   if (!implementation_) {
     if (remote_cocoa::IsWindowRemote(parent->GetNativeWindow())) {
       implementation_ =
diff --git a/ui/views/controls/menu/menu_runner_impl_remote_cocoa.h b/ui/views/controls/menu/menu_runner_impl_remote_cocoa.h
index fe26b107..7aaf6d82e 100644
--- a/ui/views/controls/menu/menu_runner_impl_remote_cocoa.h
+++ b/ui/views/controls/menu/menu_runner_impl_remote_cocoa.h
@@ -58,8 +58,8 @@
       MenuAnchorPosition anchor,
       int32_t run_types,
       gfx::NativeView native_view_for_gestures,
-      absl::optional<gfx::RoundedCornersF> corners,
-      absl::optional<std::string> show_menu_host_duration_histogram) override;
+      std::optional<gfx::RoundedCornersF> corners,
+      std::optional<std::string> show_menu_host_duration_histogram) override;
   void Cancel() override;
   base::TimeTicks GetClosingEventTime() const override;
 
diff --git a/ui/views/controls/menu/menu_runner_impl_remote_cocoa.mm b/ui/views/controls/menu/menu_runner_impl_remote_cocoa.mm
index 92e105c..e171461e 100644
--- a/ui/views/controls/menu/menu_runner_impl_remote_cocoa.mm
+++ b/ui/views/controls/menu/menu_runner_impl_remote_cocoa.mm
@@ -70,8 +70,8 @@
     MenuAnchorPosition anchor,
     int32_t run_types,
     gfx::NativeView native_view_for_gestures,
-    absl::optional<gfx::RoundedCornersF> corners,
-    absl::optional<std::string> show_menu_host_duration_histogram) {
+    std::optional<gfx::RoundedCornersF> corners,
+    std::optional<std::string> show_menu_host_duration_histogram) {
   RunMenu(parent, bounds.CenterPoint());
 }