diff --git a/lib/shared/dm-ops/create-thread-spec.js b/lib/shared/dm-ops/create-thread-spec.js
--- a/lib/shared/dm-ops/create-thread-spec.js
+++ b/lib/shared/dm-ops/create-thread-spec.js
@@ -29,6 +29,7 @@
 import { updateTypes } from '../../types/update-types-enum.js';
 import { generatePendingThreadColor } from '../color-utils.js';
 import { rawMessageInfoFromMessageData } from '../message-utils.js';
+import { createThreadTimestamps } from '../thread-utils.js';
 
 function createRoleAndPermissionForThickThreads(
   threadType: ThickThreadType,
@@ -78,11 +79,8 @@
     pinnedCount,
   } = input;
 
-  const threadColor =
-    color ??
-    generatePendingThreadColor(
-      allMemberIDsWithSubscriptions.map(({ id }) => id),
-    );
+  const memberIDs = allMemberIDsWithSubscriptions.map(({ id }) => id);
+  const threadColor = color ?? generatePendingThreadColor(memberIDs);
 
   const { membershipPermissions, role } =
     createRoleAndPermissionForThickThreads(threadType, threadID, roleID);
@@ -119,6 +117,7 @@
     avatar,
     description,
     containingThreadID,
+    timestamps: createThreadTimestamps(creationTime, memberIDs),
   };
   if (sourceMessageID) {
     newThread.sourceMessageID = sourceMessageID;
diff --git a/lib/shared/thread-utils.js b/lib/shared/thread-utils.js
--- a/lib/shared/thread-utils.js
+++ b/lib/shared/thread-utils.js
@@ -86,6 +86,7 @@
   UserProfileThreadInfo,
   MixedRawThreadInfos,
   LegacyThinRawThreadInfo,
+  ThreadTimestamps,
 } from '../types/thread-types.js';
 import { updateTypes } from '../types/update-types-enum.js';
 import { type ClientUpdateInfo } from '../types/update-types.js';
@@ -535,6 +536,7 @@
       repliesCount: 0,
       sourceMessageID,
       pinnedCount: 0,
+      timestamps: createThreadTimestamps(now, memberIDs),
     };
   } else {
     const thinThreadType = assertThinThreadType(threadType);
@@ -1699,6 +1701,27 @@
   return editableVisibleThreadInfos;
 }
 
+function createThreadTimestamps(
+  timestamp: number,
+  memberIDs: $ReadOnlyArray<string>,
+): ThreadTimestamps {
+  return {
+    name: timestamp,
+    avatar: timestamp,
+    description: timestamp,
+    color: timestamp,
+    members: Object.fromEntries(
+      memberIDs.map(id => [
+        id,
+        { isMember: timestamp, subscription: timestamp },
+      ]),
+    ),
+    currentUser: {
+      unread: timestamp,
+    },
+  };
+}
+
 export {
   threadHasPermission,
   useCommunityRootMembersToRole,
@@ -1764,4 +1787,5 @@
   useOnScreenEntryEditableThreadInfos,
   extractMentionedMembers,
   isMemberActive,
+  createThreadTimestamps,
 };
diff --git a/lib/types/thread-types.js b/lib/types/thread-types.js
--- a/lib/types/thread-types.js
+++ b/lib/types/thread-types.js
@@ -119,6 +119,40 @@
   +isSender: boolean,
 };
 
+export type ThreadTimestamps = {
+  +name: number,
+  +avatar: number,
+  +description: number,
+  +color: number,
+  +members: {
+    +[id: string]: {
+      +isMember: number,
+      +subscription: number,
+    },
+  },
+  +currentUser: {
+    +unread: number,
+  },
+};
+
+export const threadTimestampsValidator: TInterface<ThreadTimestamps> =
+  tShape<ThreadTimestamps>({
+    name: t.Number,
+    avatar: t.Number,
+    description: t.Number,
+    color: t.Number,
+    members: t.dict(
+      tUserID,
+      tShape({
+        isMember: t.Number,
+        subscription: t.Number,
+      }),
+    ),
+    currentUser: tShape({
+      unread: t.Number,
+    }),
+  });
+
 export type LegacyThickRawThreadInfo = {
   +thick: true,
   +id: string,
@@ -136,6 +170,7 @@
   +sourceMessageID?: string,
   +repliesCount: number,
   +pinnedCount?: number,
+  +timestamps: ThreadTimestamps,
 };
 
 export type LegacyRawThreadInfo =
diff --git a/lib/utils/thread-ops-utils.js b/lib/utils/thread-ops-utils.js
--- a/lib/utils/thread-ops-utils.js
+++ b/lib/utils/thread-ops-utils.js
@@ -2,6 +2,7 @@
 
 import invariant from 'invariant';
 
+import { assertWithValidator } from './validation-utils.js';
 import {
   memberInfoWithPermissionsValidator,
   persistedRoleInfoValidator,
@@ -31,6 +32,7 @@
   type LegacyRawThreadInfo,
   clientLegacyRoleInfoValidator,
   legacyThreadCurrentUserInfoValidator,
+  threadTimestampsValidator,
 } from '../types/thread-types.js';
 
 function convertRawThreadInfoToClientDBThreadInfo(
@@ -45,6 +47,9 @@
     currentUser: JSON.stringify(rawThreadInfo.currentUser),
     avatar: rawThreadInfo.avatar ? JSON.stringify(rawThreadInfo.avatar) : null,
     community: rawThreadInfo.community,
+    timestamps: rawThreadInfo.timestamps
+      ? JSON.stringify(rawThreadInfo.timestamps)
+      : null,
   };
 }
 
@@ -98,6 +103,14 @@
   const threadType = assertThreadType(clientDBThreadInfo.type);
   if (threadTypeIsThick(threadType)) {
     const thickThreadType = assertThickThreadType(threadType);
+    invariant(
+      clientDBThreadInfo.timestamps,
+      'Thick thread info must contain the timestamps',
+    );
+    const threadTimestamps = assertWithValidator(
+      JSON.parse(clientDBThreadInfo.timestamps),
+      threadTimestampsValidator,
+    );
     rawThreadInfo = {
       minimallyEncoded: true,
       thick: true,
@@ -114,6 +127,7 @@
       currentUser: minimallyEncodedCurrentUser,
       repliesCount: clientDBThreadInfo.repliesCount,
       pinnedCount: clientDBThreadInfo.pinnedCount,
+      timestamps: threadTimestamps,
     };
   } else {
     const thinThreadType = assertThinThreadType(threadType);
diff --git a/lib/utils/thread-ops-utils.test.js b/lib/utils/thread-ops-utils.test.js
--- a/lib/utils/thread-ops-utils.test.js
+++ b/lib/utils/thread-ops-utils.test.js
@@ -385,6 +385,7 @@
   community: '1',
   avatar: null,
   pinnedCount: 0,
+  timestamps: null,
 };
 
 describe('convertRawThreadInfoToClientDBThreadInfo', () => {