diff --git a/services/backup/src/constants.rs b/services/backup/src/constants.rs
--- a/services/backup/src/constants.rs
+++ b/services/backup/src/constants.rs
@@ -18,8 +18,8 @@
 pub const BACKUP_TABLE_FIELD_USER_ID: &str = "userID";
 pub const BACKUP_TABLE_FIELD_BACKUP_ID: &str = "backupID";
 pub const BACKUP_TABLE_FIELD_CREATED: &str = "created";
-pub const BACKUP_TABLE_FIELD_RECOVERY_DATA: &str = "recoveryData";
-pub const BACKUP_TABLE_FIELD_COMPACTION_HOLDER: &str = "compactionHolder";
+pub const BACKUP_TABLE_FIELD_USER_DATA: &str = "userData";
+pub const BACKUP_TABLE_FIELD_USER_KEYS: &str = "userKeys";
 pub const BACKUP_TABLE_FIELD_ATTACHMENT_HOLDERS: &str = "attachmentHolders";
 pub const BACKUP_TABLE_INDEX_USERID_CREATED: &str = "userID-created-index";
 
diff --git a/services/backup/src/database/backup_item.rs b/services/backup/src/database/backup_item.rs
--- a/services/backup/src/database/backup_item.rs
+++ b/services/backup/src/database/backup_item.rs
@@ -1,12 +1,15 @@
 use aws_sdk_dynamodb::types::AttributeValue;
 use chrono::{DateTime, Utc};
-use comm_services_lib::database::{DBItemError, TryFromAttribute};
-use std::collections::HashMap;
+use comm_services_lib::{
+  blob::types::BlobInfo,
+  database::{DBItemError, TryFromAttribute},
+};
+use std::collections::{HashMap, HashSet};
 
 use crate::constants::{
   BACKUP_TABLE_FIELD_ATTACHMENT_HOLDERS, BACKUP_TABLE_FIELD_BACKUP_ID,
-  BACKUP_TABLE_FIELD_COMPACTION_HOLDER, BACKUP_TABLE_FIELD_CREATED,
-  BACKUP_TABLE_FIELD_RECOVERY_DATA, BACKUP_TABLE_FIELD_USER_ID,
+  BACKUP_TABLE_FIELD_CREATED, BACKUP_TABLE_FIELD_USER_DATA,
+  BACKUP_TABLE_FIELD_USER_ID, BACKUP_TABLE_FIELD_USER_KEYS,
 };
 
 #[derive(Clone, Debug)]
@@ -14,65 +17,111 @@
   pub user_id: String,
   pub backup_id: String,
   pub created: DateTime<Utc>,
-  pub recovery_data: String,
-  pub compaction_holder: String,
-  pub attachment_holders: String,
+  pub user_keys: BlobInfo,
+  pub user_data: BlobInfo,
+  pub attachment_holders: HashSet<String>,
 }
 
 impl BackupItem {
   pub fn new(
     user_id: String,
     backup_id: String,
-    compaction_holder: String,
+    user_keys: BlobInfo,
+    user_data: BlobInfo,
+    attachment_holders: HashSet<String>,
   ) -> Self {
     BackupItem {
       user_id,
       backup_id,
-      compaction_holder,
       created: chrono::Utc::now(),
-      // TODO: Recovery data is mocked with random string
-      recovery_data: crate::utils::generate_random_string(
-        20,
-        &mut rand::thread_rng(),
+      user_keys,
+      user_data,
+      attachment_holders,
+    }
+  }
+}
+
+impl From<BackupItem> for HashMap<String, AttributeValue> {
+  fn from(value: BackupItem) -> Self {
+    let mut attrs = HashMap::from([
+      (
+        BACKUP_TABLE_FIELD_USER_ID.to_string(),
+        AttributeValue::S(value.user_id),
+      ),
+      (
+        BACKUP_TABLE_FIELD_BACKUP_ID.to_string(),
+        AttributeValue::S(value.backup_id),
+      ),
+      (
+        BACKUP_TABLE_FIELD_CREATED.to_string(),
+        AttributeValue::S(value.created.to_rfc3339()),
+      ),
+      (
+        BACKUP_TABLE_FIELD_USER_KEYS.to_string(),
+        value.user_keys.into(),
+      ),
+      (
+        BACKUP_TABLE_FIELD_USER_DATA.to_string(),
+        value.user_data.into(),
       ),
-      attachment_holders: String::new(),
+    ]);
+
+    if !value.attachment_holders.is_empty() {
+      attrs.insert(
+        BACKUP_TABLE_FIELD_ATTACHMENT_HOLDERS.to_string(),
+        AttributeValue::Ss(value.attachment_holders.into_iter().collect()),
+      );
     }
+
+    attrs
   }
 }
 
-pub fn parse_backup_item(
-  mut item: HashMap<String, AttributeValue>,
-) -> Result<BackupItem, DBItemError> {
-  let user_id = String::try_from_attr(
-    BACKUP_TABLE_FIELD_USER_ID,
-    item.remove(BACKUP_TABLE_FIELD_USER_ID),
-  )?;
-  let backup_id = String::try_from_attr(
-    BACKUP_TABLE_FIELD_BACKUP_ID,
-    item.remove(BACKUP_TABLE_FIELD_BACKUP_ID),
-  )?;
-  let created = DateTime::<Utc>::try_from_attr(
-    BACKUP_TABLE_FIELD_CREATED,
-    item.remove(BACKUP_TABLE_FIELD_CREATED),
-  )?;
-  let recovery_data = String::try_from_attr(
-    BACKUP_TABLE_FIELD_RECOVERY_DATA,
-    item.remove(BACKUP_TABLE_FIELD_RECOVERY_DATA),
-  )?;
-  let compaction_holder = String::try_from_attr(
-    BACKUP_TABLE_FIELD_COMPACTION_HOLDER,
-    item.remove(BACKUP_TABLE_FIELD_COMPACTION_HOLDER),
-  )?;
-  let attachment_holders = String::try_from_attr(
-    BACKUP_TABLE_FIELD_ATTACHMENT_HOLDERS,
-    item.remove(BACKUP_TABLE_FIELD_ATTACHMENT_HOLDERS),
-  )?;
-  Ok(BackupItem {
-    user_id,
-    backup_id,
-    created,
-    recovery_data,
-    compaction_holder,
-    attachment_holders,
-  })
+impl TryFrom<HashMap<String, AttributeValue>> for BackupItem {
+  type Error = DBItemError;
+
+  fn try_from(
+    mut value: HashMap<String, AttributeValue>,
+  ) -> Result<Self, Self::Error> {
+    let user_id = String::try_from_attr(
+      BACKUP_TABLE_FIELD_USER_ID,
+      value.remove(BACKUP_TABLE_FIELD_USER_ID),
+    )?;
+    let backup_id = String::try_from_attr(
+      BACKUP_TABLE_FIELD_BACKUP_ID,
+      value.remove(BACKUP_TABLE_FIELD_BACKUP_ID),
+    )?;
+    let created = DateTime::<Utc>::try_from_attr(
+      BACKUP_TABLE_FIELD_CREATED,
+      value.remove(BACKUP_TABLE_FIELD_CREATED),
+    )?;
+
+    let user_keys = BlobInfo::try_from_attr(
+      BACKUP_TABLE_FIELD_USER_KEYS,
+      value.remove(BACKUP_TABLE_FIELD_USER_KEYS),
+    )?;
+    let user_data = BlobInfo::try_from_attr(
+      BACKUP_TABLE_FIELD_USER_DATA,
+      value.remove(BACKUP_TABLE_FIELD_USER_DATA),
+    )?;
+
+    let attachments = value.remove(BACKUP_TABLE_FIELD_ATTACHMENT_HOLDERS);
+    let attachment_holders = if attachments.is_some() {
+      HashSet::<String>::try_from_attr(
+        BACKUP_TABLE_FIELD_ATTACHMENT_HOLDERS,
+        attachments,
+      )?
+    } else {
+      HashSet::new()
+    };
+
+    Ok(BackupItem {
+      user_id,
+      backup_id,
+      created,
+      user_keys,
+      user_data,
+      attachment_holders,
+    })
+  }
 }
diff --git a/services/backup/src/database/mod.rs b/services/backup/src/database/mod.rs
--- a/services/backup/src/database/mod.rs
+++ b/services/backup/src/database/mod.rs
@@ -10,9 +10,7 @@
 use tracing::error;
 
 use crate::constants::{
-  BACKUP_TABLE_FIELD_ATTACHMENT_HOLDERS, BACKUP_TABLE_FIELD_BACKUP_ID,
-  BACKUP_TABLE_FIELD_COMPACTION_HOLDER, BACKUP_TABLE_FIELD_CREATED,
-  BACKUP_TABLE_FIELD_RECOVERY_DATA, BACKUP_TABLE_FIELD_USER_ID,
+  BACKUP_TABLE_FIELD_BACKUP_ID, BACKUP_TABLE_FIELD_USER_ID,
   BACKUP_TABLE_INDEX_USERID_CREATED, BACKUP_TABLE_NAME,
   LOG_TABLE_FIELD_ATTACHMENT_HOLDERS, LOG_TABLE_FIELD_BACKUP_ID,
   LOG_TABLE_FIELD_DATA_HASH, LOG_TABLE_FIELD_LOG_ID,
@@ -20,7 +18,7 @@
 };
 
 use self::{
-  backup_item::{parse_backup_item, BackupItem},
+  backup_item::BackupItem,
   log_item::{parse_log_item, LogItem},
 };
 
@@ -41,32 +39,7 @@
     &self,
     backup_item: BackupItem,
   ) -> Result<(), Error> {
-    let item = HashMap::from([
-      (
-        BACKUP_TABLE_FIELD_USER_ID.to_string(),
-        AttributeValue::S(backup_item.user_id),
-      ),
-      (
-        BACKUP_TABLE_FIELD_CREATED.to_string(),
-        AttributeValue::S(backup_item.created.to_rfc3339()),
-      ),
-      (
-        BACKUP_TABLE_FIELD_BACKUP_ID.to_string(),
-        AttributeValue::S(backup_item.backup_id),
-      ),
-      (
-        BACKUP_TABLE_FIELD_RECOVERY_DATA.to_string(),
-        AttributeValue::S(backup_item.recovery_data),
-      ),
-      (
-        BACKUP_TABLE_FIELD_COMPACTION_HOLDER.to_string(),
-        AttributeValue::S(backup_item.compaction_holder),
-      ),
-      (
-        BACKUP_TABLE_FIELD_ATTACHMENT_HOLDERS.to_string(),
-        AttributeValue::S(backup_item.attachment_holders),
-      ),
-    ]);
+    let item = backup_item.into();
 
     self
       .client
@@ -113,7 +86,7 @@
       GetItemOutput {
         item: Some(item), ..
       } => {
-        let backup_item = parse_backup_item(item)?;
+        let backup_item = item.try_into()?;
         Ok(Some(backup_item))
       }
       _ => Ok(None),
@@ -146,7 +119,7 @@
 
     match response.items.unwrap_or_default().pop() {
       Some(item) => {
-        let backup_item = parse_backup_item(item)?;
+        let backup_item = item.try_into()?;
         Ok(Some(backup_item))
       }
       None => Ok(None),
diff --git a/services/comm-services-lib/src/database.rs b/services/comm-services-lib/src/database.rs
--- a/services/comm-services-lib/src/database.rs
+++ b/services/comm-services-lib/src/database.rs
@@ -1,6 +1,7 @@
 use aws_sdk_dynamodb::types::AttributeValue;
 use aws_sdk_dynamodb::Error as DynamoDBError;
 use chrono::{DateTime, Utc};
+use std::collections::HashSet;
 use std::fmt::{Display, Formatter};
 use std::num::ParseIntError;
 use std::str::FromStr;
@@ -260,6 +261,27 @@
   }
 }
 
+impl TryFromAttribute for HashSet<String> {
+  fn try_from_attr(
+    attribute_name: impl Into<String>,
+    attribute_value: Option<AttributeValue>,
+  ) -> Result<Self, DBItemError> {
+    match attribute_value {
+      Some(AttributeValue::Ss(set)) => Ok(set.into_iter().collect()),
+      Some(_) => Err(DBItemError::new(
+        attribute_name.into(),
+        Value::AttributeValue(attribute_value),
+        DBItemAttributeError::IncorrectType,
+      )),
+      None => Err(DBItemError::new(
+        attribute_name.into(),
+        Value::AttributeValue(attribute_value),
+        DBItemAttributeError::Missing,
+      )),
+    }
+  }
+}
+
 #[deprecated = "Use `String::try_from_attr()` instead"]
 pub fn parse_string_attribute(
   attribute_name: impl Into<String>,