diff --git a/fixtures/flight/src/App.js b/fixtures/flight/src/App.js
index 833c655cbffc7..2f29de7abaffe 100644
--- a/fixtures/flight/src/App.js
+++ b/fixtures/flight/src/App.js
@@ -37,8 +37,19 @@ async function delay(text, ms) {
   return new Promise(resolve => setTimeout(() => resolve(text), ms));
 }
 
+async function delayTwice() {
+  await delay('', 20);
+  await delay('', 10);
+}
+
+async function delayTrice() {
+  const p = delayTwice();
+  await delay('', 40);
+  return p;
+}
+
 async function Bar({children}) {
-  await delay('deferred text', 10);
+  await delayTrice();
   return 
{children}
;
 }
 
diff --git a/packages/react-client/src/ReactFlightClient.js b/packages/react-client/src/ReactFlightClient.js
index a69ede9efdf9d..1171f933d2712 100644
--- a/packages/react-client/src/ReactFlightClient.js
+++ b/packages/react-client/src/ReactFlightClient.js
@@ -2902,6 +2902,46 @@ function resolveTypedArray(
   resolveBuffer(response, id, view);
 }
 
+function logComponentInfo(
+  response: Response,
+  root: SomeChunk,
+  componentInfo: ReactComponentInfo,
+  trackIdx: number,
+  startTime: number,
+  componentEndTime: number,
+  childrenEndTime: number,
+  isLastComponent: boolean,
+): void {
+  // $FlowFixMe: Refined.
+  if (
+    isLastComponent &&
+    root.status === ERRORED &&
+    root.reason !== response._closedReason
+  ) {
+    // If this is the last component to render before this chunk rejected, then conceptually
+    // this component errored. If this was a cancellation then it wasn't this component that
+    // errored.
+    logComponentErrored(
+      componentInfo,
+      trackIdx,
+      startTime,
+      componentEndTime,
+      childrenEndTime,
+      response._rootEnvironmentName,
+      root.reason,
+    );
+  } else {
+    logComponentRender(
+      componentInfo,
+      trackIdx,
+      startTime,
+      componentEndTime,
+      childrenEndTime,
+      response._rootEnvironmentName,
+    );
+  }
+}
+
 function flushComponentPerformance(
   response: Response,
   root: SomeChunk,
@@ -2957,21 +2997,20 @@ function flushComponentPerformance(
   // in parallel with the previous.
   const debugInfo = __DEV__ && root._debugInfo;
   if (debugInfo) {
-    for (let i = 1; i < debugInfo.length; i++) {
+    let startTime = 0;
+    for (let i = 0; i < debugInfo.length; i++) {
       const info = debugInfo[i];
+      if (typeof info.time === 'number') {
+        startTime = info.time;
+      }
       if (typeof info.name === 'string') {
-        // $FlowFixMe: Refined.
-        const startTimeInfo = debugInfo[i - 1];
-        if (typeof startTimeInfo.time === 'number') {
-          const startTime = startTimeInfo.time;
-          if (startTime < trackTime) {
-            // The start time of this component is before the end time of the previous
-            // component on this track so we need to bump the next one to a parallel track.
-            trackIdx++;
-          }
-          trackTime = startTime;
-          break;
+        if (startTime < trackTime) {
+          // The start time of this component is before the end time of the previous
+          // component on this track so we need to bump the next one to a parallel track.
+          trackIdx++;
         }
+        trackTime = startTime;
+        break;
       }
     }
     for (let i = debugInfo.length - 1; i >= 0; i--) {
@@ -2979,6 +3018,7 @@ function flushComponentPerformance(
       if (typeof info.time === 'number') {
         if (info.time > parentEndTime) {
           parentEndTime = info.time;
+          break; // We assume the highest number is at the end.
         }
       }
     }
@@ -3006,85 +3046,72 @@ function flushComponentPerformance(
     }
     childTrackIdx = childResult.track;
     const childEndTime = childResult.endTime;
-    childTrackTime = childEndTime;
+    if (childEndTime > childTrackTime) {
+      childTrackTime = childEndTime;
+    }
     if (childEndTime > childrenEndTime) {
       childrenEndTime = childEndTime;
     }
   }
 
   if (debugInfo) {
-    let endTime = 0;
+    // Write debug info in reverse order (just like stack traces).
+    let componentEndTime = 0;
     let isLastComponent = true;
+    let endTime = -1;
+    let endTimeIdx = -1;
     for (let i = debugInfo.length - 1; i >= 0; i--) {
       const info = debugInfo[i];
-      if (typeof info.time === 'number') {
-        if (info.time > childrenEndTime) {
-          childrenEndTime = info.time;
-        }
-        if (endTime === 0) {
-          // Last timestamp is the end of the last component.
-          endTime = info.time;
-        }
+      if (typeof info.time !== 'number') {
+        continue;
       }
-      if (typeof info.name === 'string' && i > 0) {
-        // $FlowFixMe: Refined.
-        const componentInfo: ReactComponentInfo = info;
-        const startTimeInfo = debugInfo[i - 1];
-        if (typeof startTimeInfo.time === 'number') {
-          const startTime = startTimeInfo.time;
-          if (
-            isLastComponent &&
-            root.status === ERRORED &&
-            root.reason !== response._closedReason
-          ) {
-            // If this is the last component to render before this chunk rejected, then conceptually
-            // this component errored. If this was a cancellation then it wasn't this component that
-            // errored.
-            logComponentErrored(
+      if (componentEndTime === 0) {
+        // Last timestamp is the end of the last component.
+        componentEndTime = info.time;
+      }
+      const time = info.time;
+      if (endTimeIdx > -1) {
+        // Now that we know the start and end time, we can emit the entries between.
+        for (let j = endTimeIdx - 1; j > i; j--) {
+          const candidateInfo = debugInfo[j];
+          if (typeof candidateInfo.name === 'string') {
+            if (componentEndTime > childrenEndTime) {
+              childrenEndTime = componentEndTime;
+            }
+            // $FlowFixMe: Refined.
+            const componentInfo: ReactComponentInfo = candidateInfo;
+            logComponentInfo(
+              response,
+              root,
               componentInfo,
               trackIdx,
-              startTime,
-              endTime,
+              time,
+              componentEndTime,
               childrenEndTime,
-              response._rootEnvironmentName,
-              root.reason,
+              isLastComponent,
             );
-          } else {
-            logComponentRender(
-              componentInfo,
+            componentEndTime = time; // The end time of previous component is the start time of the next.
+            // Track the root most component of the result for deduping logging.
+            result.component = componentInfo;
+            isLastComponent = false;
+          } else if (candidateInfo.awaited) {
+            if (endTime > childrenEndTime) {
+              childrenEndTime = endTime;
+            }
+            // $FlowFixMe: Refined.
+            const asyncInfo: ReactAsyncInfo = candidateInfo;
+            logComponentAwait(
+              asyncInfo,
               trackIdx,
-              startTime,
+              time,
               endTime,
-              childrenEndTime,
               response._rootEnvironmentName,
             );
           }
-          // Track the root most component of the result for deduping logging.
-          result.component = componentInfo;
-          // Set the end time of the previous component to the start of the previous.
-          endTime = startTime;
-        }
-        isLastComponent = false;
-      } else if (info.awaited && i > 0 && i < debugInfo.length - 2) {
-        // $FlowFixMe: Refined.
-        const asyncInfo: ReactAsyncInfo = info;
-        const startTimeInfo = debugInfo[i - 1];
-        const endTimeInfo = debugInfo[i + 1];
-        if (
-          typeof startTimeInfo.time === 'number' &&
-          typeof endTimeInfo.time === 'number'
-        ) {
-          const awaitStartTime = startTimeInfo.time;
-          const awaitEndTime = endTimeInfo.time;
-          logComponentAwait(
-            asyncInfo,
-            trackIdx,
-            awaitStartTime,
-            awaitEndTime,
-            response._rootEnvironmentName,
-          );
         }
       }
+      endTime = time; // The end time of the next entry is this time.
+      endTimeIdx = i;
     }
   }
   result.endTime = childrenEndTime;
diff --git a/packages/react-server/src/ReactFlightAsyncSequence.js b/packages/react-server/src/ReactFlightAsyncSequence.js
index 215af7f7953b3..5785ba072c626 100644
--- a/packages/react-server/src/ReactFlightAsyncSequence.js
+++ b/packages/react-server/src/ReactFlightAsyncSequence.js
@@ -38,7 +38,7 @@ export type PromiseNode = {
   start: number, // start time when the Promise was created
   end: number, // end time when the Promise was resolved.
   awaited: null | AsyncSequence, // the thing that ended up resolving this promise
-  previous: null, // where we created the promise is not interesting since creating it doesn't mean waiting.
+  previous: null | AsyncSequence, // represents what the last return of an async function depended on before returning
 };
 
 export type AwaitNode = {
diff --git a/packages/react-server/src/ReactFlightServer.js b/packages/react-server/src/ReactFlightServer.js
index 5a9d0082ad4fc..3a56148f7101d 100644
--- a/packages/react-server/src/ReactFlightServer.js
+++ b/packages/react-server/src/ReactFlightServer.js
@@ -777,6 +777,10 @@ function serializeThenable(
         }
       }
       if (newTask.status === PENDING) {
+        if (enableProfilerTimer && enableComponentPerformanceTrack) {
+          // If this is async we need to time when this task finishes.
+          newTask.timed = true;
+        }
         // We expect that the only status it might be otherwise is ABORTED.
         // When we abort we emit chunks in each pending task slot and don't need
         // to do so again here.
@@ -786,11 +790,6 @@ function serializeThenable(
     },
   );
 
-  if (enableProfilerTimer && enableComponentPerformanceTrack) {
-    // If this is async we need to time when this task finishes.
-    newTask.timed = true;
-  }
-
   return newTask.id;
 }
 
@@ -1341,12 +1340,7 @@ function renderFunctionComponent(
 
       // Track when we started rendering this component.
       if (enableProfilerTimer && enableComponentPerformanceTrack) {
-        task.timed = true;
-        emitTimingChunk(
-          request,
-          componentDebugID,
-          (task.time = performance.now()),
-        );
+        advanceTaskTime(request, task, performance.now());
       }
 
       emitDebugChunk(request, componentDebugID, componentDebugInfo);
@@ -1890,8 +1884,8 @@ function visitAsyncNode(
   request: Request,
   task: Task,
   node: AsyncSequence,
-  cutOff: number,
   visited: Set,
+  cutOff: number,
 ): null | PromiseNode | IONode {
   if (visited.has(node)) {
     // It's possible to visit them same node twice when it's part of both an "awaited" path
@@ -1900,11 +1894,11 @@ function visitAsyncNode(
   }
   visited.add(node);
   // First visit anything that blocked this sequence to start in the first place.
-  if (node.previous !== null) {
+  if (node.previous !== null && node.end > request.timeOrigin) {
     // We ignore the return value here because if it wasn't awaited in user space, then we don't log it.
     // It also means that it can just have been part of a previous component's render.
     // TODO: This means that some I/O can get lost that was still blocking the sequence.
-    visitAsyncNode(request, task, node.previous, cutOff, visited);
+    visitAsyncNode(request, task, node.previous, visited, cutOff);
   }
   switch (node.tag) {
     case IO_NODE: {
@@ -1923,24 +1917,23 @@ function visitAsyncNode(
       const awaited = node.awaited;
       let match = null;
       if (awaited !== null) {
-        const ioNode = visitAsyncNode(request, task, awaited, cutOff, visited);
+        const ioNode = visitAsyncNode(request, task, awaited, visited, cutOff);
         if (ioNode !== null) {
           // This Promise was blocked on I/O. That's a signal that this Promise is interesting to log.
           // We don't log it yet though. We return it to be logged by the point where it's awaited.
           // The ioNode might be another PromiseNode in the case where none of the AwaitNode had
           // unfiltered stacks.
-          if (
+          if (ioNode.tag === PROMISE_NODE) {
+            // If the ioNode was a Promise, then that means we found one in user space since otherwise
+            // we would've returned an IO node. We assume this has the best stack.
+            match = ioNode;
+          } else if (
             filterStackTrace(request, parseStackTrace(node.stack, 1)).length ===
             0
           ) {
-            // Typically we assume that the outer most Promise that was awaited in user space has the
-            // most actionable stack trace for the start of the operation. However, if this Promise
-            // was created inside only third party code, then try to use the inner node instead.
-            // This could happen if you pass a first party Promise into a third party to be awaited there.
-            if (ioNode.end < 0) {
-              // If we haven't defined an end time, use the resolve of the outer Promise.
-              ioNode.end = node.end;
-            }
+            // If this Promise was created inside only third party code, then try to use
+            // the inner I/O node instead. This could happen if third party calls into first
+            // party to perform some I/O.
             match = ioNode;
           } else {
             match = node;
@@ -1955,30 +1948,17 @@ function visitAsyncNode(
       }
       return match;
     }
-    case UNRESOLVED_AWAIT_NODE:
-    // We could be inside the .then() which is about to resolve this node.
-    // TODO: We could call emitAsyncSequence in a microtask to avoid this issue.
-    // Fallthrough to the resolved path.
+    case UNRESOLVED_AWAIT_NODE: {
+      return null;
+    }
     case AWAIT_NODE: {
       const awaited = node.awaited;
       let match = null;
       if (awaited !== null) {
-        const ioNode = visitAsyncNode(request, task, awaited, cutOff, visited);
+        const ioNode = visitAsyncNode(request, task, awaited, visited, cutOff);
         if (ioNode !== null) {
           const startTime: number = node.start;
-          let endTime: number;
-          if (node.tag === UNRESOLVED_AWAIT_NODE) {
-            // If we haven't defined an end time, use the resolve of the inner Promise.
-            // This can happen because the ping gets invoked before the await gets resolved.
-            if (ioNode.end < node.start) {
-              // If we're awaiting a resolved Promise it could have finished before we started.
-              endTime = node.start;
-            } else {
-              endTime = ioNode.end;
-            }
-          } else {
-            endTime = node.end;
-          }
+          const endTime: number = node.end;
           if (endTime <= request.timeOrigin) {
             // This was already resolved when we started this render. It must have been either something
             // that's part of a start up sequence or externally cached data. We exclude that information.
@@ -2002,14 +1982,12 @@ function visitAsyncNode(
               match = ioNode;
             } else {
               // Outline the IO node.
-              if (ioNode.end < 0) {
-                ioNode.end = endTime;
-              }
               serializeIONode(request, ioNode);
+
               // We log the environment at the time when the last promise pigned ping which may
               // be later than what the environment was when we actually started awaiting.
               const env = (0, request.environmentName)();
-              emitTimingChunk(request, task.id, startTime);
+              advanceTaskTime(request, task, startTime);
               // Then emit a reference to us awaiting it in the current task.
               request.pendingChunks++;
               emitDebugChunk(request, task.id, {
@@ -2018,23 +1996,14 @@ function visitAsyncNode(
                 owner: node.owner,
                 stack: stack,
               });
-              emitTimingChunk(request, task.id, endTime);
+              markOperationEndTime(request, task, endTime);
             }
           }
         }
       }
       // We need to forward after we visit awaited nodes because what ever I/O we requested that's
       // the thing that generated this node and its virtual children.
-      let debugInfo: null | ReactDebugInfo;
-      if (node.tag === UNRESOLVED_AWAIT_NODE) {
-        const promise = node.debugInfo.deref();
-        debugInfo =
-          promise === undefined || promise._debugInfo === undefined
-            ? null
-            : promise._debugInfo;
-      } else {
-        debugInfo = node.debugInfo;
-      }
+      const debugInfo: null | ReactDebugInfo = node.debugInfo;
       if (debugInfo !== null) {
         forwardDebugInfo(request, task, debugInfo);
       }
@@ -2051,37 +2020,23 @@ function emitAsyncSequence(
   request: Request,
   task: Task,
   node: AsyncSequence,
-  cutOff: number,
 ): void {
   const visited: Set = new Set();
-  const awaitedNode = visitAsyncNode(request, task, node, cutOff, visited);
+  const awaitedNode = visitAsyncNode(request, task, node, visited, task.time);
   if (awaitedNode !== null) {
     // Nothing in user space (unfiltered stack) awaited this.
-    if (awaitedNode.end < 0) {
-      // If this was I/O directly without a Promise, then it means that some custom Thenable
-      // called our ping directly and not from a native .then(). We use the current ping time
-      // as the end time and treat it as an await with no stack.
-      // TODO: If this I/O is recurring then we really should have different entries for
-      // each occurrence. Right now we'll only track the first time it is invoked.
-      awaitedNode.end = performance.now();
-    }
     serializeIONode(request, awaitedNode);
     request.pendingChunks++;
     // We log the environment at the time when we ping which may be later than what the
     // environment was when we actually started awaiting.
     const env = (0, request.environmentName)();
     // If we don't have any thing awaited, the time we started awaiting was internal
-    // when we yielded after rendering. The cutOff time is basically that.
-    const awaitStartTime = cutOff;
-    // If the end time finished before we started, it could've been a cached thing so
-    // we clamp it to the cutOff time. Effectively leading to a zero-time await.
-    const awaitEndTime = awaitedNode.end < cutOff ? cutOff : awaitedNode.end;
-    emitTimingChunk(request, task.id, awaitStartTime);
+    // when we yielded after rendering. The current task time is basically that.
     emitDebugChunk(request, task.id, {
       awaited: ((awaitedNode: any): ReactIOInfo), // This is deduped by this reference.
       env: env,
     });
-    emitTimingChunk(request, task.id, awaitEndTime);
+    markOperationEndTime(request, task, awaitedNode.end);
   }
 }
 
@@ -2092,7 +2047,7 @@ function pingTask(request: Request, task: Task): void {
     if (enableAsyncDebugInfo) {
       const sequence = getCurrentAsyncSequence();
       if (sequence !== null) {
-        emitAsyncSequence(request, task, sequence, task.time);
+        emitAsyncSequence(request, task, sequence);
       }
     }
   }
@@ -4295,19 +4250,13 @@ function forwardDebugInfo(
   debugInfo: ReactDebugInfo,
 ) {
   const id = task.id;
-  const minimumTime =
-    enableProfilerTimer && enableComponentPerformanceTrack ? task.time : 0;
   for (let i = 0; i < debugInfo.length; i++) {
     const info = debugInfo[i];
     if (typeof info.time === 'number') {
       // When forwarding time we need to ensure to convert it to the time space of the payload.
       // We clamp the time to the starting render of the current component. It's as if it took
       // no time to render and await if we reuse cached content.
-      emitTimingChunk(
-        request,
-        id,
-        info.time < minimumTime ? minimumTime : info.time,
-      );
+      markOperationEndTime(request, task, info.time);
     } else {
       if (typeof info.name === 'string') {
         // We outline this model eagerly so that we can refer to by reference as an owner.
@@ -4384,6 +4333,40 @@ function emitTimingChunk(
   request.completedRegularChunks.push(processedChunk);
 }
 
+function advanceTaskTime(
+  request: Request,
+  task: Task,
+  timestamp: number,
+): void {
+  if (!enableProfilerTimer || !enableComponentPerformanceTrack) {
+    return;
+  }
+  // Emits a timing chunk, if the new timestamp is higher than the previous timestamp of this task.
+  if (timestamp > task.time) {
+    emitTimingChunk(request, task.id, timestamp);
+    task.time = timestamp;
+  } else if (!task.timed) {
+    // If it wasn't timed before, e.g. an outlined object, we need to emit the first timestamp and
+    // it is now timed.
+    emitTimingChunk(request, task.id, task.time);
+  }
+  task.timed = true;
+}
+
+function markOperationEndTime(request: Request, task: Task, timestamp: number) {
+  if (!enableProfilerTimer || !enableComponentPerformanceTrack) {
+    return;
+  }
+  // This is like advanceTaskTime() but always emits a timing chunk even if it doesn't advance.
+  // This ensures that the end time of the previous entry isn't implied to be the start of the next one.
+  if (timestamp > task.time) {
+    emitTimingChunk(request, task.id, timestamp);
+    task.time = timestamp;
+  } else {
+    emitTimingChunk(request, task.id, task.time);
+  }
+}
+
 function emitChunk(
   request: Request,
   task: Task,
@@ -4475,7 +4458,7 @@ function emitChunk(
 function erroredTask(request: Request, task: Task, error: mixed): void {
   if (enableProfilerTimer && enableComponentPerformanceTrack) {
     if (task.timed) {
-      emitTimingChunk(request, task.id, (task.time = performance.now()));
+      markOperationEndTime(request, task, performance.now());
     }
   }
   task.status = ERRORED;
@@ -4558,7 +4541,7 @@ function retryTask(request: Request, task: Task): void {
     // We've finished rendering. Log the end time.
     if (enableProfilerTimer && enableComponentPerformanceTrack) {
       if (task.timed) {
-        emitTimingChunk(request, task.id, (task.time = performance.now()));
+        markOperationEndTime(request, task, performance.now());
       }
     }
 
@@ -4685,7 +4668,7 @@ function abortTask(task: Task, request: Request, errorId: number): void {
   // Track when we aborted this task as its end time.
   if (enableProfilerTimer && enableComponentPerformanceTrack) {
     if (task.timed) {
-      emitTimingChunk(request, task.id, (task.time = performance.now()));
+      markOperationEndTime(request, task, performance.now());
     }
   }
   // Instead of emitting an error per task.id, we emit a model that only
diff --git a/packages/react-server/src/ReactFlightServerConfigDebugNode.js b/packages/react-server/src/ReactFlightServerConfigDebugNode.js
index 3bf84962bbed0..ddcf256525b6d 100644
--- a/packages/react-server/src/ReactFlightServerConfigDebugNode.js
+++ b/packages/react-server/src/ReactFlightServerConfigDebugNode.js
@@ -30,6 +30,27 @@ import {enableAsyncDebugInfo} from 'shared/ReactFeatureFlags';
 const pendingOperations: Map =
   __DEV__ && enableAsyncDebugInfo ? new Map() : (null: any);
 
+// Keep the last resolved await as a workaround for async functions missing data.
+let lastRanAwait: null | AwaitNode = null;
+
+function resolvePromiseOrAwaitNode(
+  unresolvedNode: UnresolvedAwaitNode | UnresolvedPromiseNode,
+  endTime: number,
+): AwaitNode | PromiseNode {
+  const resolvedNode: AwaitNode | PromiseNode = (unresolvedNode: any);
+  resolvedNode.tag = ((unresolvedNode.tag === UNRESOLVED_PROMISE_NODE
+    ? PROMISE_NODE
+    : AWAIT_NODE): any);
+  // The Promise can be garbage collected after this so we should extract debugInfo first.
+  const promise = unresolvedNode.debugInfo.deref();
+  resolvedNode.debugInfo =
+    promise === undefined || promise._debugInfo === undefined
+      ? null
+      : promise._debugInfo;
+  resolvedNode.end = endTime;
+  return resolvedNode;
+}
+
 // Initialize the tracing of async operations.
 // We do this globally since the async work can potentially eagerly
 // start before the first request and once requests start they can interleave.
@@ -129,42 +150,76 @@ export function initAsyncDebugInfo(): void {
         }
         pendingOperations.set(asyncId, node);
       },
-      promiseResolve(asyncId: number): void {
+      before(asyncId: number): void {
         const node = pendingOperations.get(asyncId);
         if (node !== undefined) {
-          let resolvedNode: AwaitNode | PromiseNode;
           switch (node.tag) {
+            case IO_NODE: {
+              lastRanAwait = null;
+              // Log the end time when we resolved the I/O. This can happen
+              // more than once if it's a recurring resource like a connection.
+              const ioNode: IONode = (node: any);
+              ioNode.end = performance.now();
+              break;
+            }
             case UNRESOLVED_AWAIT_NODE: {
-              const awaitNode: AwaitNode = (node: any);
-              awaitNode.tag = AWAIT_NODE;
-              resolvedNode = awaitNode;
+              // If we begin before we resolve, that means that this is actually already resolved but
+              // the promiseResolve hook is called at the end of the execution. So we track the time
+              // in the before call instead.
+              // $FlowFixMe
+              lastRanAwait = resolvePromiseOrAwaitNode(node, performance.now());
               break;
             }
-            case UNRESOLVED_PROMISE_NODE: {
-              const promiseNode: PromiseNode = (node: any);
-              promiseNode.tag = PROMISE_NODE;
-              resolvedNode = promiseNode;
+            case AWAIT_NODE: {
+              lastRanAwait = node;
               break;
             }
-            case IO_NODE:
-              // eslint-disable-next-line react-internal/prod-error-codes
-              throw new Error(
-                'A Promise should never be an IO_NODE. This is a bug in React.',
+            case UNRESOLVED_PROMISE_NODE: {
+              // We typically don't expected Promises to have an execution scope since only the awaits
+              // have a then() callback. However, this can happen for native async functions. The last
+              // piece of code that executes the return after the last await has the execution context
+              // of the Promise.
+              const resolvedNode = resolvePromiseOrAwaitNode(
+                node,
+                performance.now(),
               );
+              // We are missing information about what this was unblocked by but we can guess that it
+              // was whatever await we ran last since this will continue in a microtask after that.
+              // This is not perfect because there could potentially be other microtasks getting in
+              // between.
+              resolvedNode.previous = lastRanAwait;
+              lastRanAwait = null;
+              break;
+            }
+            default: {
+              lastRanAwait = null;
+            }
+          }
+        }
+      },
+
+      promiseResolve(asyncId: number): void {
+        const node = pendingOperations.get(asyncId);
+        if (node !== undefined) {
+          let resolvedNode: AwaitNode | PromiseNode;
+          switch (node.tag) {
+            case UNRESOLVED_AWAIT_NODE:
+            case UNRESOLVED_PROMISE_NODE: {
+              resolvedNode = resolvePromiseOrAwaitNode(node, performance.now());
+              break;
+            }
+            case AWAIT_NODE:
+            case PROMISE_NODE: {
+              // We already resolved this in the before hook.
+              resolvedNode = node;
+              break;
+            }
             default:
               // eslint-disable-next-line react-internal/prod-error-codes
               throw new Error(
-                'A Promise should never be resolved twice. This is a bug in React or Node.js.',
+                'A Promise should never be an IO_NODE. This is a bug in React.',
               );
           }
-          // Log the end time when we resolved the promise.
-          resolvedNode.end = performance.now();
-          // The Promise can be garbage collected after this so we should extract debugInfo first.
-          const promise = node.debugInfo.deref();
-          resolvedNode.debugInfo =
-            promise === undefined || promise._debugInfo === undefined
-              ? null
-              : promise._debugInfo;
           const currentAsyncId = executionAsyncId();
           if (asyncId !== currentAsyncId) {
             // If the promise was not resolved by itself, then that means that
diff --git a/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js b/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js
index 989dbdf19cbff..05f31ff7def9d 100644
--- a/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js
+++ b/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js
@@ -419,7 +419,7 @@ describe('ReactFlightAsyncDebugInfo', () => {
             "awaited": {
               "end": 0,
               "env": "Server",
-              "name": "getData",
+              "name": "delay",
               "owner": {
                 "env": "Server",
                 "key": null,
@@ -438,19 +438,19 @@ describe('ReactFlightAsyncDebugInfo', () => {
               },
               "stack": [
                 [
-                  "getData",
+                  "delay",
                   "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                  156,
-                  27,
-                  156,
-                  5,
+                  133,
+                  12,
+                  132,
+                  3,
                 ],
                 [
-                  "Component",
+                  "getData",
                   "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                  165,
-                  22,
-                  163,
+                  158,
+                  21,
+                  156,
                   5,
                 ],
               ],
@@ -547,9 +547,6 @@ describe('ReactFlightAsyncDebugInfo', () => {
               ],
             ],
           },
-          {
-            "time": 0,
-          },
           {
             "awaited": {
               "end": 0,
@@ -637,9 +634,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
               [
                 "Object.",
                 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                608,
+                605,
                 109,
-                599,
+                596,
                 94,
               ],
             ],
@@ -708,9 +705,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
               [
                 "Object.",
                 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                679,
+                676,
                 109,
-                655,
+                652,
                 50,
               ],
             ],
@@ -790,9 +787,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
               [
                 "Object.",
                 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                761,
+                758,
                 109,
-                744,
+                741,
                 63,
               ],
             ],
@@ -817,9 +814,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
               [
                 "Component",
                 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                757,
+                754,
                 24,
-                756,
+                753,
                 5,
               ],
             ],
@@ -849,9 +846,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
                   [
                     "Component",
                     "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                    757,
+                    754,
                     24,
-                    756,
+                    753,
                     5,
                   ],
                 ],
@@ -868,17 +865,17 @@ describe('ReactFlightAsyncDebugInfo', () => {
                 [
                   "getData",
                   "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                  746,
+                  743,
                   13,
-                  745,
+                  742,
                   5,
                 ],
                 [
                   "ThirdPartyComponent",
                   "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                  752,
+                  749,
                   24,
-                  751,
+                  748,
                   5,
                 ],
               ],
@@ -902,9 +899,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
                 [
                   "Component",
                   "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                  757,
+                  754,
                   24,
-                  756,
+                  753,
                   5,
                 ],
               ],
@@ -913,17 +910,17 @@ describe('ReactFlightAsyncDebugInfo', () => {
               [
                 "getData",
                 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                746,
+                743,
                 13,
-                745,
+                742,
                 5,
               ],
               [
                 "ThirdPartyComponent",
                 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                752,
+                749,
                 24,
-                751,
+                748,
                 5,
               ],
             ],
@@ -956,9 +953,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
                   [
                     "Component",
                     "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                    757,
+                    754,
                     24,
-                    756,
+                    753,
                     5,
                   ],
                 ],
@@ -975,17 +972,17 @@ describe('ReactFlightAsyncDebugInfo', () => {
                 [
                   "getData",
                   "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                  747,
+                  744,
                   13,
-                  745,
+                  742,
                   5,
                 ],
                 [
                   "ThirdPartyComponent",
                   "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                  752,
+                  749,
                   18,
-                  751,
+                  748,
                   5,
                 ],
               ],
@@ -1009,9 +1006,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
                 [
                   "Component",
                   "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                  757,
+                  754,
                   24,
-                  756,
+                  753,
                   5,
                 ],
               ],
@@ -1020,17 +1017,17 @@ describe('ReactFlightAsyncDebugInfo', () => {
               [
                 "getData",
                 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                747,
+                744,
                 13,
-                745,
+                742,
                 5,
               ],
               [
                 "ThirdPartyComponent",
                 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                752,
+                749,
                 18,
-                751,
+                748,
                 5,
               ],
             ],
@@ -1108,9 +1105,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
               [
                 "Object.",
                 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                1074,
+                1071,
                 40,
-                1052,
+                1049,
                 62,
               ],
             ],
@@ -1132,9 +1129,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
                   [
                     "Object.",
                     "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                    1074,
+                    1071,
                     40,
-                    1052,
+                    1049,
                     62,
                   ],
                 ],
@@ -1151,17 +1148,17 @@ describe('ReactFlightAsyncDebugInfo', () => {
                 [
                   "getData",
                   "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                  1059,
+                  1056,
                   13,
-                  1055,
+                  1052,
                   25,
                 ],
                 [
                   "Component",
                   "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                  1069,
+                  1066,
                   13,
-                  1068,
+                  1065,
                   5,
                 ],
               ],
@@ -1177,9 +1174,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
                 [
                   "Object.",
                   "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                  1074,
+                  1071,
                   40,
-                  1052,
+                  1049,
                   62,
                 ],
               ],
@@ -1188,17 +1185,17 @@ describe('ReactFlightAsyncDebugInfo', () => {
               [
                 "getData",
                 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                1059,
+                1056,
                 13,
-                1055,
+                1052,
                 25,
               ],
               [
                 "Component",
                 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                1069,
+                1066,
                 13,
-                1068,
+                1065,
                 5,
               ],
             ],
@@ -1218,9 +1215,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
               [
                 "Component",
                 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                1070,
+                1067,
                 60,
-                1068,
+                1065,
                 5,
               ],
             ],
@@ -1232,7 +1229,7 @@ describe('ReactFlightAsyncDebugInfo', () => {
             "awaited": {
               "end": 0,
               "env": "Server",
-              "name": "getData",
+              "name": "delay",
               "owner": {
                 "env": "Server",
                 "key": null,
@@ -1242,28 +1239,36 @@ describe('ReactFlightAsyncDebugInfo', () => {
                   [
                     "Object.",
                     "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                    1074,
+                    1071,
                     40,
-                    1052,
+                    1049,
                     62,
                   ],
                 ],
               },
               "stack": [
+                [
+                  "delay",
+                  "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                  133,
+                  12,
+                  132,
+                  3,
+                ],
                 [
                   "getData",
                   "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                  1055,
-                  47,
-                  1055,
+                  1056,
+                  13,
+                  1052,
                   25,
                 ],
                 [
                   "Component",
                   "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                  1069,
+                  1066,
                   13,
-                  1068,
+                  1065,
                   5,
                 ],
               ],
@@ -1279,9 +1284,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
                 [
                   "Component",
                   "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                  1070,
+                  1067,
                   60,
-                  1068,
+                  1065,
                   5,
                 ],
               ],
@@ -1290,9 +1295,346 @@ describe('ReactFlightAsyncDebugInfo', () => {
               [
                 "Child",
                 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
-                1064,
+                1061,
                 28,
-                1063,
+                1060,
+                5,
+              ],
+            ],
+          },
+          {
+            "time": 0,
+          },
+          {
+            "time": 0,
+          },
+        ]
+      `);
+    }
+  });
+
+  it('can track implicit returned promises that are blocked by previous data', async () => {
+    async function delayTwice() {
+      await delay('', 20);
+      await delay('', 10);
+    }
+
+    async function delayTrice() {
+      const p = delayTwice();
+      await delay('', 40);
+      return p;
+    }
+
+    async function Bar({children}) {
+      await delayTrice();
+      return 'hi';
+    }
+
+    const stream = ReactServerDOMServer.renderToPipeableStream(
+      ,
+      {},
+      {
+        filterStackFrame,
+      },
+    );
+
+    const readable = new Stream.PassThrough(streamOptions);
+
+    const result = ReactServerDOMClient.createFromNodeStream(readable, {
+      moduleMap: {},
+      moduleLoading: {},
+    });
+    stream.pipe(readable);
+
+    expect(await result).toBe('hi');
+    if (
+      __DEV__ &&
+      gate(
+        flags =>
+          flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo,
+      )
+    ) {
+      expect(getDebugInfo(result)).toMatchInlineSnapshot(`
+        [
+          {
+            "time": 0,
+          },
+          {
+            "env": "Server",
+            "key": null,
+            "name": "Bar",
+            "props": {},
+            "stack": [
+              [
+                "Object.",
+                "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                1334,
+                40,
+                1316,
+                80,
+              ],
+            ],
+          },
+          {
+            "time": 0,
+          },
+          {
+            "awaited": {
+              "end": 0,
+              "env": "Server",
+              "name": "delay",
+              "owner": {
+                "env": "Server",
+                "key": null,
+                "name": "Bar",
+                "props": {},
+                "stack": [
+                  [
+                    "Object.",
+                    "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                    1334,
+                    40,
+                    1316,
+                    80,
+                  ],
+                ],
+              },
+              "stack": [
+                [
+                  "delay",
+                  "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                  133,
+                  12,
+                  132,
+                  3,
+                ],
+                [
+                  "delayTrice",
+                  "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                  1324,
+                  13,
+                  1322,
+                  5,
+                ],
+                [
+                  "Bar",
+                  "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                  1329,
+                  13,
+                  1328,
+                  5,
+                ],
+              ],
+              "start": 0,
+            },
+            "env": "Server",
+            "owner": {
+              "env": "Server",
+              "key": null,
+              "name": "Bar",
+              "props": {},
+              "stack": [
+                [
+                  "Object.",
+                  "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                  1334,
+                  40,
+                  1316,
+                  80,
+                ],
+              ],
+            },
+            "stack": [
+              [
+                "delayTrice",
+                "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                1324,
+                13,
+                1322,
+                5,
+              ],
+              [
+                "Bar",
+                "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                1329,
+                13,
+                1328,
+                5,
+              ],
+            ],
+          },
+          {
+            "time": 0,
+          },
+          {
+            "awaited": {
+              "end": 0,
+              "env": "Server",
+              "name": "delay",
+              "owner": {
+                "env": "Server",
+                "key": null,
+                "name": "Bar",
+                "props": {},
+                "stack": [
+                  [
+                    "Object.",
+                    "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                    1334,
+                    40,
+                    1316,
+                    80,
+                  ],
+                ],
+              },
+              "stack": [
+                [
+                  "delay",
+                  "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                  133,
+                  12,
+                  132,
+                  3,
+                ],
+                [
+                  "delayTwice",
+                  "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                  1318,
+                  13,
+                  1317,
+                  5,
+                ],
+                [
+                  "delayTrice",
+                  "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                  1323,
+                  15,
+                  1322,
+                  5,
+                ],
+                [
+                  "Bar",
+                  "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                  1329,
+                  13,
+                  1328,
+                  5,
+                ],
+              ],
+              "start": 0,
+            },
+            "env": "Server",
+            "owner": {
+              "env": "Server",
+              "key": null,
+              "name": "Bar",
+              "props": {},
+              "stack": [
+                [
+                  "Object.",
+                  "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                  1334,
+                  40,
+                  1316,
+                  80,
+                ],
+              ],
+            },
+            "stack": [
+              [
+                "delayTwice",
+                "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                1318,
+                13,
+                1317,
+                5,
+              ],
+              [
+                "delayTrice",
+                "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                1323,
+                15,
+                1322,
+                5,
+              ],
+              [
+                "Bar",
+                "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                1329,
+                13,
+                1328,
+                5,
+              ],
+            ],
+          },
+          {
+            "time": 0,
+          },
+          {
+            "awaited": {
+              "end": 0,
+              "env": "Server",
+              "name": "delay",
+              "owner": {
+                "env": "Server",
+                "key": null,
+                "name": "Bar",
+                "props": {},
+                "stack": [
+                  [
+                    "Object.",
+                    "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                    1334,
+                    40,
+                    1316,
+                    80,
+                  ],
+                ],
+              },
+              "stack": [
+                [
+                  "delay",
+                  "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                  133,
+                  12,
+                  132,
+                  3,
+                ],
+                [
+                  "delayTwice",
+                  "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                  1319,
+                  13,
+                  1317,
+                  5,
+                ],
+              ],
+              "start": 0,
+            },
+            "env": "Server",
+            "owner": {
+              "env": "Server",
+              "key": null,
+              "name": "Bar",
+              "props": {},
+              "stack": [
+                [
+                  "Object.",
+                  "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                  1334,
+                  40,
+                  1316,
+                  80,
+                ],
+              ],
+            },
+            "stack": [
+              [
+                "delayTwice",
+                "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
+                1319,
+                13,
+                1317,
                 5,
               ],
             ],