diff --git a/src/include/daos/object.h b/src/include/daos/object.h
index ff58c0af2ea..95aa926e7e4 100644
--- a/src/include/daos/object.h
+++ b/src/include/daos/object.h
@@ -206,6 +206,7 @@ struct daos_obj_layout {
 struct daos_shard_tgt {
 	uint32_t		st_rank;	/* rank of the shard */
 	uint32_t		st_shard;	/* shard index */
+	uint32_t		st_shard_id;	/* shard id */
 	uint32_t		st_tgt_id;	/* target id */
 	uint16_t		st_tgt_idx;	/* target xstream index */
 	/* target idx for EC obj, only used for client */
diff --git a/src/object/cli_obj.c b/src/object/cli_obj.c
index 7c2da71e7ba..60c7fd7d583 100644
--- a/src/object/cli_obj.c
+++ b/src/object/cli_obj.c
@@ -24,7 +24,7 @@
 #define CLI_OBJ_IO_PARMS	8
 #define NIL_BITMAP		(NULL)
 
-#define OBJ_TGT_INLINE_NR	(16)
+#define OBJ_TGT_INLINE_NR	(12)
 struct obj_req_tgts {
 	/* to save memory allocation if #targets <= OBJ_TGT_INLINE_NR */
 	struct daos_shard_tgt	 ort_tgts_inline[OBJ_TGT_INLINE_NR];
@@ -942,6 +942,7 @@ obj_shard_tgts_query(struct dc_object *obj, uint32_t map_ver, uint32_t shard,
 
 	shard_tgt->st_rank	= obj_shard->do_target_rank;
 	shard_tgt->st_shard	= shard;
+	shard_tgt->st_shard_id	= obj_shard->do_id.id_shard;
 	shard_tgt->st_tgt_idx	= obj_shard->do_target_idx;
 	rc = obj_shard2tgtid(obj, shard, map_ver, &shard_tgt->st_tgt_id);
 	obj_shard_close(obj_shard);
diff --git a/src/object/obj_rpc.c b/src/object/obj_rpc.c
index f65539a11d8..442da199787 100644
--- a/src/object/obj_rpc.c
+++ b/src/object/obj_rpc.c
@@ -705,7 +705,7 @@ crt_proc_struct_daos_cpd_sub_req(crt_proc_t proc,
 		 * be used as part of the vos object cache index.
 		 *
 		 * It is not important what the id_shard is, that
-		 * is packed via daos_cpd_req_idx::dcri_shard_idx.
+		 * is packed via daos_cpd_req_idx::dcri_shard_id.
 		 */
 		rc = crt_proc_daos_unit_oid_t(proc, &oid);
 	}
diff --git a/src/object/obj_rpc.h b/src/object/obj_rpc.h
index 6aed005fd32..4a26c0b88e1 100644
--- a/src/object/obj_rpc.h
+++ b/src/object/obj_rpc.h
@@ -40,7 +40,7 @@
  * These are for daos_rpc::dr_opc and DAOS_RPC_OPCODE(opc, ...) rather than
  * crt_req_create(..., opc, ...). See daos_rpc.h.
  */
-#define DAOS_OBJ_VERSION 2
+#define DAOS_OBJ_VERSION 3
 /* LIST of internal RPCS in form of:
  * OPCODE, flags, FMT, handler, corpc_hdlr and name
  */
@@ -467,13 +467,17 @@ struct daos_cpd_sub_req {
  */
 struct daos_cpd_req_idx {
 	/* Shard index of the object for the sub request on this DAOS target. */
-	uint32_t			 dcri_shard_idx;
+	uint32_t			 dcri_shard_off;
+	/* Shard identifier of the object for the sub request. */
+	uint32_t			 dcri_shard_id;
 	/* The index (relative to the first sub request for its transaction)
 	 * of sub-request in the 'oci_sub_reqs' array. For parsing convenience,
 	 * DCSO_READ requests firstly, then modification ones. The update and
 	 * punch are sorted as their original executed order.
 	 */
 	uint32_t			 dcri_req_idx;
+	/* 64-bits alignment. */
+	uint32_t			 dcri_padding;
 };
 
 /**
diff --git a/src/object/obj_tx.c b/src/object/obj_tx.c
index 011c842c5df..51029af1685 100644
--- a/src/object/obj_tx.c
+++ b/src/object/obj_tx.c
@@ -1246,8 +1246,10 @@ dc_tx_classify_common(struct dc_tx *tx, struct daos_cpd_sub_req *dcsr,
 
 		dcri = &dtrg->dtrg_req_idx[dtrg->dtrg_read_cnt +
 					   dtrg->dtrg_write_cnt];
-		dcri->dcri_shard_idx = shard->do_shard;
+		dcri->dcri_shard_off = idx;
+		dcri->dcri_shard_id = shard->do_shard;
 		dcri->dcri_req_idx = req_idx;
+		dcri->dcri_padding = 0;
 
 		if (read)
 			dtrg->dtrg_read_cnt++;
diff --git a/src/object/srv_obj.c b/src/object/srv_obj.c
index ce9b1855456..c830b594811 100644
--- a/src/object/srv_obj.c
+++ b/src/object/srv_obj.c
@@ -3567,7 +3567,7 @@ ds_obj_dtx_handle_one(crt_rpc_t *rpc, struct daos_cpd_sub_head *dcsh,
 			D_GOTO(out, rc = -DER_PROTO);
 		}
 
-		dcsr->dcsr_oid.id_shard = dcri[i].dcri_shard_idx;
+		dcsr->dcsr_oid.id_shard = dcri[i].dcri_shard_id;
 		rc = vos_fetch_begin(ioc->ioc_vos_coh, dcsr->dcsr_oid,
 				     dcsh->dcsh_epoch.oe_value,
 				     &dcsr->dcsr_dkey, dcsr->dcsr_nr,
@@ -3591,7 +3591,7 @@ ds_obj_dtx_handle_one(crt_rpc_t *rpc, struct daos_cpd_sub_head *dcsh,
 	/* P2: vos_update_begin. */
 	for (i = 0; i < dcde->dcde_write_cnt; i++) {
 		dcsr = &dcsrs[dcri[i].dcri_req_idx];
-		dcsr->dcsr_oid.id_shard = dcri[i].dcri_shard_idx;
+		dcsr->dcsr_oid.id_shard = dcri[i].dcri_shard_id;
 
 		if (dcsr->dcsr_opc != DCSO_UPDATE)
 			continue;
diff --git a/src/object/srv_obj_remote.c b/src/object/srv_obj_remote.c
index 473052b42ad..ae374479766 100644
--- a/src/object/srv_obj_remote.c
+++ b/src/object/srv_obj_remote.c
@@ -133,7 +133,7 @@ ds_obj_remote_update(struct dtx_leader_handle *dlh, void *data, int idx,
 		orw->orw_iod_array.oia_oiod_nr = orw->orw_iod_array.oia_iod_nr;
 		orw->orw_iod_array.oia_offs = tgt_oiod->oto_offs;
 	}
-	orw->orw_oid.id_shard = shard_tgt->st_shard;
+	orw->orw_oid.id_shard = shard_tgt->st_shard_id;
 	uuid_copy(orw->orw_co_hdl, orw_parent->orw_co_hdl);
 	uuid_copy(orw->orw_co_uuid, orw_parent->orw_co_uuid);
 	orw->orw_shard_tgts.ca_count	= orw_parent->orw_shard_tgts.ca_count;
@@ -351,7 +351,7 @@ ds_obj_cpd_clone_reqs(struct dtx_leader_handle *dlh, struct daos_shard_tgt *tgt,
 
 				oiod = obj_ec_tgt_oiod_get(split->osr_tgt_oiods,
 						dcsr_parent[idx].dcsr_ec_tgt_nr,
-						dcri_parent->dcri_shard_idx -
+						dcri_parent->dcri_shard_off -
 						dcu_parent->dcu_start_shard);
 				D_ASSERT(oiod != NULL);
 
@@ -362,8 +362,10 @@ ds_obj_cpd_clone_reqs(struct dtx_leader_handle *dlh, struct daos_shard_tgt *tgt,
 			}
 		}
 
-		dcde->dcde_reqs[i].dcri_shard_idx = dcri_parent->dcri_shard_idx;
+		dcde->dcde_reqs[i].dcri_shard_off = dcri_parent->dcri_shard_off;
+		dcde->dcde_reqs[i].dcri_shard_id = dcri_parent->dcri_shard_id;
 		dcde->dcde_reqs[i].dcri_req_idx = i;
+		dcde->dcde_reqs[i].dcri_padding = dcri_parent->dcri_padding;
 	}
 
 out: