diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp
index 405628b3087df40c2d99f3fcb802de165183cd1e..5674cb48e34bc59499c7813d53b3b5f1b3965bb5 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp
@@ -34,7 +34,7 @@ void DynamicPatriciaTrieNodeReader::fetchNodeInfoFromBufferAndProcessMovedNode(c
     mFlags = PatriciaTrieReadingUtils::getFlagsAndAdvancePosition(dictBuf, &pos);
     const int parentPos =
             DynamicPatriciaTrieReadingUtils::getParentPosAndAdvancePosition(dictBuf, &pos);
-    mParentPos = (parentPos != 0) ? mNodePos + parentPos : NOT_A_DICT_POS;
+    mParentPos = (parentPos != 0) ? nodePos + parentPos : NOT_A_DICT_POS;
     if (outCodePoints != 0) {
         mCodePointCount = PatriciaTrieReadingUtils::getCharsAndAdvancePosition(
                 dictBuf, mFlags, maxCodePointCount, outCodePoints, &pos);
diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.cpp b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.cpp
index e244212193c93d15bbb0d46137bfc2e6abaff925..356a853c9cad454e2fe2491d28ad887d3d59a45b 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.cpp
@@ -136,9 +136,10 @@ bool DynamicPatriciaTrieWritingHelper::markNodeAsMovedAndSetPosition(
             &writingPos)) {
         return false;
     }
-    // Update moved position, which is stored in the parent position field.
-    if (!DynamicPatriciaTrieWritingUtils::writeParentPositionAndAdvancePosition(
-            mBuffer, movedPos, &writingPos)) {
+    // Update moved position, which is stored in the parent offset field.
+    const int movedPosOffset = movedPos - originalNode->getNodePos();
+    if (!DynamicPatriciaTrieWritingUtils::writeParentOffsetAndAdvancePosition(
+            mBuffer, movedPosOffset, &writingPos)) {
         return false;
     }
     return true;
@@ -150,6 +151,7 @@ bool DynamicPatriciaTrieWritingHelper::writeNodeToBuffer(const bool isBlackliste
         const int codePointCount, const int probability, const int childrenPos,
         const int originalBigramListPos, const int originalShortcutListPos,
         int *const writingPos) {
+    const int nodePos = *writingPos;
     // Create node flags and write them.
     const PatriciaTrieReadingUtils::NodeFlags nodeFlags =
             PatriciaTrieReadingUtils::createAndGetFlags(isBlacklisted, isNotAWord,
@@ -160,9 +162,10 @@ bool DynamicPatriciaTrieWritingHelper::writeNodeToBuffer(const bool isBlackliste
             writingPos)) {
         return false;
     }
-    // Write parent position
-    if (!DynamicPatriciaTrieWritingUtils::writeParentPositionAndAdvancePosition(mBuffer, parentPos,
-            writingPos)) {
+    // Calculate a parent offset and write the offset.
+    const int parentOffset = (parentPos != NOT_A_DICT_POS) ? parentPos - nodePos : NOT_A_DICT_POS;
+    if (!DynamicPatriciaTrieWritingUtils::writeParentOffsetAndAdvancePosition(mBuffer,
+            parentOffset, writingPos)) {
         return false;
     }
     // Write code points
diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_utils.cpp b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_utils.cpp
index 4187504b4d7e326193812222df0eeea969c150af..b261e594d188cacf000f9f70767aa2ed417512d9 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_utils.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_utils.cpp
@@ -68,11 +68,11 @@ const int DynamicPatriciaTrieWritingUtils::NODE_FLAG_FIELD_SIZE = 1;
     return buffer->writeUintAndAdvancePosition(nodeFlags, NODE_FLAG_FIELD_SIZE, nodeFlagsFieldPos);
 }
 
-/* static */ bool DynamicPatriciaTrieWritingUtils::writeParentPositionAndAdvancePosition(
-        BufferWithExtendableBuffer *const buffer, const int parentPosition,
+// Note that parentOffset is offset from node's head position.
+/* static */ bool DynamicPatriciaTrieWritingUtils::writeParentOffsetAndAdvancePosition(
+        BufferWithExtendableBuffer *const buffer, const int parentOffset,
         int *const parentPosFieldPos) {
-    // Note that parentPosition is offset from node's head position.
-    int offset = (parentPosition != NOT_A_DICT_POS) ? parentPosition : 0;
+    int offset = (parentOffset != NOT_A_DICT_POS) ? parentOffset : 0;
     return writeDictOffset(buffer, offset, parentPosFieldPos);
 }
 
diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_utils.h b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_utils.h
index 801042ddf2f340a7dc36441579d3b1acd5221bfa..183ede4447154b26b222d6009cc205df33a79729 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_utils.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_utils.h
@@ -39,7 +39,7 @@ class DynamicPatriciaTrieWritingUtils {
             const DynamicPatriciaTrieReadingUtils::NodeFlags nodeFlags,
             int *const nodeFlagsFieldPos);
 
-    static bool writeParentPositionAndAdvancePosition(BufferWithExtendableBuffer *const buffer,
+    static bool writeParentOffsetAndAdvancePosition(BufferWithExtendableBuffer *const buffer,
             const int parentPosition, int *const parentPosFieldPos);
 
     static bool writeCodePointsAndAdvancePosition(BufferWithExtendableBuffer *const buffer,