diff --git a/release/src/linked-issues.ts b/release/src/linked-issues.ts
index c76892720eb41a026df5ac59ed603daab00d28ae..4662c1923f7e4549cdb9a256922f1f9fcbd9150f 100644
--- a/release/src/linked-issues.ts
+++ b/release/src/linked-issues.ts
@@ -22,3 +22,9 @@ export function getPRsFromCommitMessage(message: string) {
 
   return result.map(r => Number(r[1]));
 }
+
+// backport PRs just have a pr number in the body without a keyword
+export function getBackportSourcePRNumber(body: string) {
+  const matches = body.match(/#(\d+)/);
+  return matches ? Number(matches[1]) : null;
+}
diff --git a/release/src/linked-issues.unit.spec.ts b/release/src/linked-issues.unit.spec.ts
index b832b4522d1a98b90d76b06bb4e2c6550cc1a540..9efa996af2c48e83bae1bc343fb985635e418eeb 100644
--- a/release/src/linked-issues.unit.spec.ts
+++ b/release/src/linked-issues.unit.spec.ts
@@ -1,4 +1,4 @@
-import { getLinkedIssues, getPRsFromCommitMessage } from "./linked-issues";
+import { getLinkedIssues, getPRsFromCommitMessage, getBackportSourcePRNumber } from "./linked-issues";
 
 const closingKeywords = [
   "Close",
@@ -131,3 +131,18 @@ describe("getPRsFromCommitMessage", () => {
     expect(getPRsFromCommitMessage("Backport (#1234) and (#4567)")).toEqual([1234, 4567]);
   });
 });
+
+describe("getBackportSourcePRNumber", () => {
+  it("should return `null` when no PR is found", () => {
+    expect(getBackportSourcePRNumber("")).toBeNull();
+    expect(getBackportSourcePRNumber("Lorem ipsum dolor sit amet.")).toBeNull();
+    expect(getBackportSourcePRNumber("#yolo")).toBeNull();
+
+  });
+
+  it("should return the pr number when it is found", () => {
+    expect(getBackportSourcePRNumber("#4567")).toBe(4567);
+    expect(getBackportSourcePRNumber(" #4567 ")).toBe(4567);
+    expect(getBackportSourcePRNumber("backports #4567 and #6789")).toBe(4567);
+  });
+});
diff --git a/release/src/milestones.ts b/release/src/milestones.ts
index 12c810ac87d1e39d6e5b2dbfc76da1980d90a4ee..1d1c9f230047463b15b80581d2651623f4fb8bcb 100644
--- a/release/src/milestones.ts
+++ b/release/src/milestones.ts
@@ -1,7 +1,7 @@
 import _ from "underscore";
 
 import { getMilestones } from "./github";
-import { getLinkedIssues, getPRsFromCommitMessage } from "./linked-issues";
+import { getLinkedIssues, getPRsFromCommitMessage, getBackportSourcePRNumber } from "./linked-issues";
 import type { Issue, GithubProps, Milestone } from "./types";
 import {
   getMajorVersion,
@@ -54,13 +54,17 @@ async function getOriginalPR({
     pull_number: pullRequestNumber,
   });
 
-  if (pull?.data && isBackport(pull.data)) {
-    return getOriginalPR({
-      github,
-      repo,
-      owner,
-      pullRequestNumber: pull.data.number
-    });
+  if (pull?.data && isBackport(pull.data) && pull.data.body) {
+    const sourcePRNumber = getBackportSourcePRNumber(pull.data.body);
+    if (sourcePRNumber && sourcePRNumber !== pullRequestNumber) {
+      console.log('found backport PR', pull.data.number, 'source PR', sourcePRNumber);
+      return getOriginalPR({
+        github,
+        repo,
+        owner,
+        pullRequestNumber: sourcePRNumber,
+      });
+    }
   }
 
   const linkedIssues = await getLinkedIssues(pull.data.body ?? '');
@@ -182,9 +186,11 @@ export async function setMilestoneForCommits({
     })));
   }
 
-  console.log(`Tagging ${issuesToTag.length} issues with milestone ${nextMilestone.title}`)
+  const uniqueIssuesToTag = _.uniq(issuesToTag);
+
+  console.log(`Tagging ${uniqueIssuesToTag.length} issues with milestone ${nextMilestone.title}`)
 
-  for (const issueNumber of issuesToTag) { // for loop to avoid rate limiting
+  for (const issueNumber of uniqueIssuesToTag) { // for loop to avoid rate limiting
     await setMilestone({ github, owner, repo, issueNumber, milestone: nextMilestone });
   }
 }