diff --git a/functions/src/create-notification.ts b/functions/src/create-notification.ts
index a0134634..204105ac 100644
--- a/functions/src/create-notification.ts
+++ b/functions/src/create-notification.ts
@@ -10,6 +10,7 @@ import {
   MANIFOLD_AVATAR_URL,
   MANIFOLD_USER_NAME,
   MANIFOLD_USER_USERNAME,
+  PrivateUser,
   User,
 } from '../../common/user'
 import { Contract } from '../../common/contract'
@@ -42,21 +43,19 @@ type recipients_to_reason_texts = {
   [userId: string]: { reason: notification_reason_types }
 }
 
-export const createNotification = async (
+export const createFollowOrMarketSubsidizedNotification = async (
   sourceId: string,
-  sourceType: 'contract' | 'liquidity' | 'follow',
-  sourceUpdateType: 'closed' | 'created',
+  sourceType: 'liquidity' | 'follow',
+  sourceUpdateType: 'created',
   sourceUser: User,
   idempotencyKey: string,
   sourceText: string,
   miscData?: {
     contract?: Contract
     recipients?: string[]
-    slug?: string
-    title?: string
   }
 ) => {
-  const { contract: sourceContract, recipients, slug, title } = miscData ?? {}
+  const { contract: sourceContract, recipients } = miscData ?? {}
 
   const shouldReceiveNotification = (
     userId: string,
@@ -100,23 +99,15 @@ export const createNotification = async (
           sourceContractCreatorUsername: sourceContract?.creatorUsername,
           sourceContractTitle: sourceContract?.question,
           sourceContractSlug: sourceContract?.slug,
-          sourceSlug: slug ? slug : sourceContract?.slug,
-          sourceTitle: title ? title : sourceContract?.question,
+          sourceSlug: sourceContract?.slug,
+          sourceTitle: sourceContract?.question,
         }
         await notificationRef.set(removeUndefinedProps(notification))
       }
 
       if (!sendToEmail) continue
 
-      if (reason === 'your_contract_closed' && privateUser && sourceContract) {
-        // TODO: include number and names of bettors waiting for creator to resolve their market
-        await sendMarketCloseEmail(
-          reason,
-          sourceUser,
-          privateUser,
-          sourceContract
-        )
-      } else if (reason === 'subsidized_your_market') {
+      if (reason === 'subsidized_your_market') {
         // TODO: send email to creator of market that was subsidized
       } else if (reason === 'on_new_follow') {
         // TODO: send email to user who was followed
@@ -133,20 +124,7 @@ export const createNotification = async (
         reason: 'on_new_follow',
       }
     return await sendNotificationsIfSettingsPermit(userToReasonTexts)
-  } else if (
-    sourceType === 'contract' &&
-    sourceUpdateType === 'closed' &&
-    sourceContract
-  ) {
-    userToReasonTexts[sourceContract.creatorId] = {
-      reason: 'your_contract_closed',
-    }
-    return await sendNotificationsIfSettingsPermit(userToReasonTexts)
-  } else if (
-    sourceType === 'liquidity' &&
-    sourceUpdateType === 'created' &&
-    sourceContract
-  ) {
+  } else if (sourceType === 'liquidity' && sourceContract) {
     if (shouldReceiveNotification(sourceContract.creatorId, userToReasonTexts))
       userToReasonTexts[sourceContract.creatorId] = {
         reason: 'subsidized_your_market',
@@ -1133,3 +1111,41 @@ export const createBadgeAwardedNotification = async (
 
   // TODO send email notification
 }
+
+export const createMarketClosedNotification = async (
+  contract: Contract,
+  creator: User,
+  privateUser: PrivateUser,
+  idempotencyKey: string
+) => {
+  const notificationRef = firestore
+    .collection(`/users/${creator.id}/notifications`)
+    .doc(idempotencyKey)
+  const notification: Notification = {
+    id: idempotencyKey,
+    userId: creator.id,
+    reason: 'your_contract_closed',
+    createdTime: Date.now(),
+    isSeen: false,
+    sourceId: contract.id,
+    sourceType: 'contract',
+    sourceUpdateType: 'closed',
+    sourceContractId: contract?.id,
+    sourceUserName: creator.name,
+    sourceUserUsername: creator.username,
+    sourceUserAvatarUrl: creator.avatarUrl,
+    sourceText: contract.closeTime?.toString() ?? new Date().toString(),
+    sourceContractCreatorUsername: creator.username,
+    sourceContractTitle: contract.question,
+    sourceContractSlug: contract.slug,
+    sourceSlug: contract.slug,
+    sourceTitle: contract.question,
+  }
+  await notificationRef.set(removeUndefinedProps(notification))
+  await sendMarketCloseEmail(
+    'your_contract_closed',
+    creator,
+    privateUser,
+    contract
+  )
+}
diff --git a/functions/src/emails.ts b/functions/src/emails.ts
index 31129b71..1b111a9b 100644
--- a/functions/src/emails.ts
+++ b/functions/src/emails.ts
@@ -301,12 +301,7 @@ export const sendMarketCloseEmail = async (
   privateUser: PrivateUser,
   contract: Contract
 ) => {
-  const { sendToEmail, unsubscribeUrl } = getNotificationDestinationsForUser(
-    privateUser,
-    reason
-  )
-
-  if (!privateUser.email || !sendToEmail) return
+  if (!privateUser.email) return
 
   const { username, name, id: userId } = user
   const firstName = name.split(' ')[0]
@@ -315,6 +310,7 @@ export const sendMarketCloseEmail = async (
 
   const url = `https://${DOMAIN}/${username}/${slug}`
 
+  // We ignore if they were able to unsubscribe from market close emails, this is a necessary email
   return await sendTemplateEmail(
     privateUser.email,
     'Your market has closed',
@@ -322,7 +318,7 @@ export const sendMarketCloseEmail = async (
     {
       question,
       url,
-      unsubscribeUrl,
+      unsubscribeUrl: '',
       userId,
       name: firstName,
       volume: formatMoney(volume),
diff --git a/functions/src/market-close-notifications.ts b/functions/src/market-close-notifications.ts
index 21b52fbc..4e25b493 100644
--- a/functions/src/market-close-notifications.ts
+++ b/functions/src/market-close-notifications.ts
@@ -3,8 +3,10 @@ import * as admin from 'firebase-admin'
 
 import { Contract } from '../../common/contract'
 import { getPrivateUser, getUserByUsername } from './utils'
-import { createNotification } from './create-notification'
+import { createMarketClosedNotification } from './create-notification'
+import { DAY_MS } from '../../common/util/time'
 
+const SEND_NOTIFICATIONS_EVERY_DAYS = 5
 export const marketCloseNotifications = functions
   .runWith({ secrets: ['MAILGUN_KEY'] })
   .pubsub.schedule('every 1 hours')
@@ -14,31 +16,31 @@ export const marketCloseNotifications = functions
 
 const firestore = admin.firestore()
 
-async function sendMarketCloseEmails() {
+export async function sendMarketCloseEmails() {
   const contracts = await firestore.runTransaction(async (transaction) => {
     const snap = await transaction.get(
       firestore.collection('contracts').where('isResolved', '!=', true)
     )
+    const contracts = snap.docs.map((doc) => doc.data() as Contract)
+    const now = Date.now()
+    const closeContracts = contracts.filter(
+      (contract) =>
+        contract.closeTime &&
+        contract.closeTime < now &&
+        shouldSendFirstOrFollowUpCloseNotification(contract)
+    )
 
-    return snap.docs
-      .map((doc) => {
-        const contract = doc.data() as Contract
-
-        if (
-          contract.resolution ||
-          (contract.closeEmailsSent ?? 0) >= 1 ||
-          contract.closeTime === undefined ||
-          (contract.closeTime ?? 0) > Date.now()
+    await Promise.all(
+      closeContracts.map(async (contract) => {
+        await transaction.update(
+          firestore.collection('contracts').doc(contract.id),
+          {
+            closeEmailsSent: admin.firestore.FieldValue.increment(1),
+          }
         )
-          return undefined
-
-        transaction.update(doc.ref, {
-          closeEmailsSent: (contract.closeEmailsSent ?? 0) + 1,
-        })
-
-        return contract
       })
-      .filter((x) => !!x) as Contract[]
+    )
+    return closeContracts
   })
 
   for (const contract of contracts) {
@@ -55,14 +57,38 @@ async function sendMarketCloseEmails() {
     const privateUser = await getPrivateUser(user.id)
     if (!privateUser) continue
 
-    await createNotification(
-      contract.id,
-      'contract',
-      'closed',
+    await createMarketClosedNotification(
+      contract,
       user,
-      contract.id + '-closed-at-' + contract.closeTime,
-      contract.closeTime?.toString() ?? new Date().toString(),
-      { contract }
+      privateUser,
+      contract.id + '-closed-at-' + contract.closeTime
     )
   }
 }
+function shouldSendFirstOrFollowUpCloseNotification(contract: Contract) {
+  if (!contract.closeEmailsSent || contract.closeEmailsSent === 0) return true
+  const { closedMultipleOfNDaysAgo, fullTimePeriodsSinceClose } =
+    marketClosedMultipleOfNDaysAgo(contract)
+  // Sends another notification if it's been a multiple of N days since the market closed AND
+  // the number of close notifications we've sent is equal to the number of time periods since the market closed
+  return (
+    contract.closeEmailsSent > 0 &&
+    closedMultipleOfNDaysAgo &&
+    contract.closeEmailsSent === fullTimePeriodsSinceClose
+  )
+}
+
+function marketClosedMultipleOfNDaysAgo(contract: Contract) {
+  const now = Date.now()
+  const closeTime = contract.closeTime
+  if (!closeTime)
+    return { closedMultipleOfNDaysAgo: false, fullTimePeriodsSinceClose: 0 }
+  const daysSinceClose = Math.floor((now - closeTime) / DAY_MS)
+  return {
+    closedMultipleOfNDaysAgo:
+      daysSinceClose % SEND_NOTIFICATIONS_EVERY_DAYS == 0,
+    fullTimePeriodsSinceClose: Math.floor(
+      daysSinceClose / SEND_NOTIFICATIONS_EVERY_DAYS
+    ),
+  }
+}
diff --git a/functions/src/on-create-liquidity-provision.ts b/functions/src/on-create-liquidity-provision.ts
index 54da7fd9..53f61eaa 100644
--- a/functions/src/on-create-liquidity-provision.ts
+++ b/functions/src/on-create-liquidity-provision.ts
@@ -1,6 +1,6 @@
 import * as functions from 'firebase-functions'
 import { getContract, getUser, log } from './utils'
-import { createNotification } from './create-notification'
+import { createFollowOrMarketSubsidizedNotification } from './create-notification'
 import { LiquidityProvision } from '../../common/liquidity-provision'
 import { addUserToContractFollowers } from './follow-market'
 import { FIXED_ANTE } from '../../common/economy'
@@ -36,7 +36,7 @@ export const onCreateLiquidityProvision = functions.firestore
     if (!liquidityProvider) throw new Error('Could not find liquidity provider')
     await addUserToContractFollowers(contract.id, liquidityProvider.id)
 
-    await createNotification(
+    await createFollowOrMarketSubsidizedNotification(
       contract.id,
       'liquidity',
       'created',
diff --git a/functions/src/on-follow-user.ts b/functions/src/on-follow-user.ts
index 52042345..2f601f6d 100644
--- a/functions/src/on-follow-user.ts
+++ b/functions/src/on-follow-user.ts
@@ -2,7 +2,7 @@ import * as functions from 'firebase-functions'
 import * as admin from 'firebase-admin'
 
 import { getUser } from './utils'
-import { createNotification } from './create-notification'
+import { createFollowOrMarketSubsidizedNotification } from './create-notification'
 import { FieldValue } from 'firebase-admin/firestore'
 
 export const onFollowUser = functions.firestore
@@ -23,7 +23,7 @@ export const onFollowUser = functions.firestore
       followerCountCached: FieldValue.increment(1),
     })
 
-    await createNotification(
+    await createFollowOrMarketSubsidizedNotification(
       followingUser.id,
       'follow',
       'created',
diff --git a/functions/src/scripts/backfill-badges.ts b/functions/src/scripts/backfill-badges.ts
index 145f064c..a3776eb0 100644
--- a/functions/src/scripts/backfill-badges.ts
+++ b/functions/src/scripts/backfill-badges.ts
@@ -17,6 +17,7 @@ const firestore = admin.firestore()
 async function main() {
   const users = await getAllUsers()
   // const users = filterDefined([await getUser('6hHpzvRG0pMq8PNJs7RZj2qlZGn2')]) // dev ian
+  // const users = filterDefined([await getUser('uglwf3YKOZNGjjEXKc5HampOFRE2')]) // prod David
   // const users = filterDefined([await getUser('AJwLWoo3xue32XIiAVrL5SyR1WB2')]) // prod ian
   await Promise.all(
     users.map(async (user) => {
@@ -38,6 +39,32 @@ async function main() {
 
 if (require.main === module) main().then(() => process.exit())
 
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+async function removeErrorBadges(user: User) {
+  if (
+    user.achievements.streaker?.badges.some(
+      (b) => b.data.totalBettingStreak > 1
+    )
+  ) {
+    console.log(
+      `User ${
+        user.id
+      } has a streaker badge with streaks ${user.achievements.streaker?.badges.map(
+        (b) => b.data.totalBettingStreak
+      )}`
+    )
+    // delete non 1,50 streaks
+    user.achievements.streaker.badges =
+      user.achievements.streaker.badges.filter((b) =>
+        streakerBadgeRarityThresholds.includes(b.data.totalBettingStreak)
+      )
+    // update user
+    await firestore.collection('users').doc(user.id).update({
+      achievements: user.achievements,
+    })
+  }
+}
+
 async function awardMarketCreatorBadges(user: User) {
   // Award market maker badges
   const contracts = await getValues<Contract>(
diff --git a/functions/src/test-scheduled-function.ts b/functions/src/test-scheduled-function.ts
index c4465703..ed51e5e9 100644
--- a/functions/src/test-scheduled-function.ts
+++ b/functions/src/test-scheduled-function.ts
@@ -1,6 +1,6 @@
 import { APIError, newEndpoint } from './api'
 import { isProd } from './utils'
-import { sendTrendingMarketsEmailsToAllUsers } from 'functions/src/weekly-markets-emails'
+import { sendMarketCloseEmails } from 'functions/src/market-close-notifications'
 
 // Function for testing scheduled functions locally
 export const testscheduledfunction = newEndpoint(
@@ -10,7 +10,7 @@ export const testscheduledfunction = newEndpoint(
       throw new APIError(400, 'This function is only available in dev mode')
 
     // Replace your function here
-    await sendTrendingMarketsEmailsToAllUsers()
+    await sendMarketCloseEmails()
 
     return { success: true }
   }
diff --git a/web/pages/notifications.tsx b/web/pages/notifications.tsx
index dd622a72..7388986a 100644
--- a/web/pages/notifications.tsx
+++ b/web/pages/notifications.tsx
@@ -1002,6 +1002,7 @@ function MarketClosedNotification(props: {
       isChildOfGroup={isChildOfGroup}
       highlighted={highlighted}
       subtitle={'Please resolve'}
+      hideUserName={true}
     >
       <Row>
         <span>