diff --git a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp
--- a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp
+++ b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp
@@ -1912,8 +1912,9 @@
 void SQLiteQueryExecutor::storeOlmPersistSession(
     const OlmPersistSession &session) const {
   static std::string replaceOlmPersistSessionSQL =
-      "REPLACE INTO olm_persist_sessions (target_user_id, session_data) "
-      "VALUES (?, ?);";
+      "REPLACE INTO olm_persist_sessions "
+      "(target_device_id, session_data, version) "
+      "VALUES (?, ?, ?);";
 
   replaceEntity<OlmPersistSession>(
       SQLiteQueryExecutor::getConnection(),
diff --git a/native/cpp/CommonCpp/DatabaseManagers/entities/OlmPersistSession.h b/native/cpp/CommonCpp/DatabaseManagers/entities/OlmPersistSession.h
--- a/native/cpp/CommonCpp/DatabaseManagers/entities/OlmPersistSession.h
+++ b/native/cpp/CommonCpp/DatabaseManagers/entities/OlmPersistSession.h
@@ -7,17 +7,21 @@
 namespace comm {
 
 struct OlmPersistSession {
-  std::string target_user_id;
+  std::string target_device_id;
   std::string session_data;
+  int version;
 
   static OlmPersistSession fromSQLResult(sqlite3_stmt *sqlRow, int idx) {
     return OlmPersistSession{
-        getStringFromSQLRow(sqlRow, idx), getStringFromSQLRow(sqlRow, idx + 1)};
+        getStringFromSQLRow(sqlRow, idx),
+        getStringFromSQLRow(sqlRow, idx + 1),
+        getIntFromSQLRow(sqlRow, idx + 2)};
   }
 
   int bindToSQL(sqlite3_stmt *sql, int idx) const {
-    bindStringToSQL(target_user_id, sql, idx);
-    return bindStringToSQL(session_data, sql, idx + 1);
+    bindStringToSQL(target_device_id, sql, idx);
+    bindStringToSQL(session_data, sql, idx + 1);
+    return bindIntToSQL(version, sql, idx + 2);
   }
 };
 
diff --git a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp
--- a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp
+++ b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp
@@ -470,7 +470,7 @@
                     sessionsDataItem.session_data.begin(),
                     sessionsDataItem.session_data.end());
                 contentPersist.sessions.insert(std::make_pair(
-                    sessionsDataItem.target_user_id, sessionDataBuffer));
+                    sessionsDataItem.target_device_id, sessionDataBuffer));
               }
             }
 
diff --git a/web/cpp/SQLiteQueryExecutorBindings.cpp b/web/cpp/SQLiteQueryExecutorBindings.cpp
--- a/web/cpp/SQLiteQueryExecutorBindings.cpp
+++ b/web/cpp/SQLiteQueryExecutorBindings.cpp
@@ -104,8 +104,9 @@
       .field("medias", &MessageWithMedias::medias);
 
   value_object<OlmPersistSession>("OlmPersistSession")
-      .field("targetUserID", &OlmPersistSession::target_user_id)
-      .field("sessionData", &OlmPersistSession::session_data);
+      .field("targetDeviceID", &OlmPersistSession::target_device_id)
+      .field("sessionData", &OlmPersistSession::session_data)
+      .field("version", &OlmPersistSession::version);
 
   value_object<ClientMessageToDevice>("ClientMessageToDevice")
       .field("messageID", &ClientMessageToDevice::message_id)
diff --git a/web/shared-worker/_generated/comm-query-executor.js b/web/shared-worker/_generated/comm-query-executor.js
--- a/web/shared-worker/_generated/comm-query-executor.js
+++ b/web/shared-worker/_generated/comm-query-executor.js
@@ -131,14 +131,14 @@
 arguments.length+") - expected ("+Object.keys(H.tb).toString()+") parameters instead!");return I.apply(this,arguments)});var K=Object.create(C,{constructor:{value:u}});u.prototype=K;var H=new Nb(p,u,K,x,w,g,h,q);w=new V(p,H,!0,!1);C=new V(p+"*",H,!1,!1);var Ga=new V(p+" const*",H,!1,!0);Db[a]={pointerType:C,jd:Ga};Ub(l,u);return[w,C,Ga]})},ja:function(a,b,c,d,f,g){0<b||v();var k=$b(b,c);f=W(d,f);ub([],[a],function(h){h=h[0];var n="constructor "+h.name;void 0===h.Ta.tb&&(h.Ta.tb=[]);if(void 0!==h.Ta.tb[b-
 1])throw new xb("Cannot register multiple constructors with identical number of parameters ("+(b-1)+") for class '"+h.name+"'! Overload resolution is currently only performed using the parameter count, not actual type info!");h.Ta.tb[b-1]=()=>{Zb("Cannot construct "+h.name+" due to unbound types",k)};ub([],k,function(q){q.splice(1,0,null);h.Ta.tb[b-1]=bc(n,q,null,f,g);return[]});return[]})},a:function(a,b,c,d,f,g,k,h){var n=$b(c,d);b=S(b);g=W(f,g);ub([],[a],function(q){function p(){Zb("Cannot call "+
 t+" due to unbound types",n)}q=q[0];var t=q.name+"."+b;b.startsWith("@@")&&(b=Symbol[b.substring(2)]);h&&q.Ta.Nd.push(b);var x=q.Ta.Eb,l=x[b];void 0===l||void 0===l.$a&&l.className!==q.name&&l.Qb===c-2?(p.Qb=c-2,p.className=q.name,x[b]=p):(Lb(x,b,t),x[b].$a[c-2]=p);ub([],n,function(u){u=bc(t,u,q,g,k);void 0===x[b].$a?(u.Qb=c-2,x[b]=u):x[b].$a[c-2]=u;return[]});return[]})},ea:function(a,b){b=S(b);R(a,{name:b,fromWireType:function(c){var d=ec(c);dc(c);return d},toWireType:function(c,d){return Sb(d)},
-argPackAdvance:8,readValueFromPointer:lb,ib:null})},x:function(a,b,c){c=vb(c);b=S(b);R(a,{name:b,fromWireType:function(d){return d},toWireType:function(d,f){return f},argPackAdvance:8,readValueFromPointer:fc(b,c),ib:null})},ha:function(a,b,c,d,f,g){var k=$b(b,c);a=S(a);f=W(d,f);Mb(a,function(){Zb("Cannot call "+a+" due to unbound types",k)},b-1);ub([],k,function(h){h=[h[0],null].concat(h.slice(1));Ub(a,bc(a,h,null,f,g),b-1);return[]})},i:function(a,b,c,d,f){b=S(b);-1===f&&(f=4294967295);f=vb(c);var g=
+argPackAdvance:8,readValueFromPointer:lb,ib:null})},x:function(a,b,c){c=vb(c);b=S(b);R(a,{name:b,fromWireType:function(d){return d},toWireType:function(d,f){return f},argPackAdvance:8,readValueFromPointer:fc(b,c),ib:null})},ha:function(a,b,c,d,f,g){var k=$b(b,c);a=S(a);f=W(d,f);Mb(a,function(){Zb("Cannot call "+a+" due to unbound types",k)},b-1);ub([],k,function(h){h=[h[0],null].concat(h.slice(1));Ub(a,bc(a,h,null,f,g),b-1);return[]})},j:function(a,b,c,d,f){b=S(b);-1===f&&(f=4294967295);f=vb(c);var g=
 h=>h;if(0===d){var k=32-8*c;g=h=>h<<k>>>k}c=b.includes("unsigned")?function(h,n){return n>>>0}:function(h,n){return n};R(a,{name:b,fromWireType:g,toWireType:c,argPackAdvance:8,readValueFromPointer:gc(b,f,0!==d),ib:null})},g:function(a,b,c){function d(g){g>>=2;var k=F;return new f(ua,k[g+1],k[g])}var f=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array][b];c=S(c);R(a,{name:c,fromWireType:d,argPackAdvance:8,readValueFromPointer:d},{Ad:!0})},y:function(a,b){b=
 S(b);var c="std::string"===b;R(a,{name:b,fromWireType:function(d){var f=F[d>>2],g=d+4;if(c)for(var k=g,h=0;h<=f;++h){var n=g+h;if(h==f||0==z[n]){k=y(k,n-k);if(void 0===q)var q=k;else q+=String.fromCharCode(0),q+=k;k=n+1}}else{q=Array(f);for(h=0;h<f;++h)q[h]=String.fromCharCode(z[g+h]);q=q.join("")}X(d);return q},toWireType:function(d,f){f instanceof ArrayBuffer&&(f=new Uint8Array(f));var g="string"==typeof f;g||f instanceof Uint8Array||f instanceof Uint8ClampedArray||f instanceof Int8Array||T("Cannot pass non-string to std::string");
 var k=c&&g?ta(f):f.length;var h=wc(4+k+1),n=h+4;F[h>>2]=k;if(c&&g)A(f,z,n,k+1);else if(g)for(g=0;g<k;++g){var q=f.charCodeAt(g);255<q&&(X(n),T("String has UTF-16 code units that do not fit in 8 bits"));z[n+g]=q}else for(g=0;g<k;++g)z[n+g]=f[g];null!==d&&d.push(X,h);return h},argPackAdvance:8,readValueFromPointer:lb,ib:function(d){X(d)}})},p:function(a,b,c){c=S(c);if(2===b){var d=ic;var f=jc;var g=kc;var k=()=>va;var h=1}else 4===b&&(d=lc,f=mc,g=nc,k=()=>F,h=2);R(a,{name:c,fromWireType:function(n){for(var q=
 F[n>>2],p=k(),t,x=n+4,l=0;l<=q;++l){var u=n+4+l*b;if(l==q||0==p[u>>h])x=d(x,u-x),void 0===t?t=x:(t+=String.fromCharCode(0),t+=x),x=u+b}X(n);return t},toWireType:function(n,q){"string"!=typeof q&&T("Cannot pass non-string to C++ string type "+c);var p=g(q),t=wc(4+p+b);F[t>>2]=p>>h;f(q,t+4,p+b);null!==n&&n.push(X,t);return t},argPackAdvance:8,readValueFromPointer:lb,ib:function(n){X(n)}})},f:function(a,b,c,d,f,g){jb[a]={name:S(b),rc:W(c,d),pb:W(f,g),Lc:[]}},d:function(a,b,c,d,f,g,k,h,n,q){jb[a].Lc.push({rd:S(b),
 zd:c,Sb:W(d,f),yd:g,Sd:k,Rd:W(h,n),Td:q})},ga:function(a,b){b=S(b);R(a,{Dd:!0,name:b,argPackAdvance:0,fromWireType:function(){},toWireType:function(){}})},o:function(){return Date.now()},aa:function(){return!0},k:function(a,b,c){a=ec(a);b=oc(b,"emval::as");var d=[],f=Sb(d);F[c>>2]=f;return b.toWireType(d,a)},A:function(a,b,c,d){a=rc[a];b=ec(b);c=qc(c);a(b,c,null,d)},na:dc,oa:function(a,b){var c=tc(a,b),d=c[0];b=d.name+"_$"+c.slice(1).map(function(p){return p.name}).join("_")+"$";var f=uc[b];if(void 0!==
 f)return f;f=["retType"];for(var g=[d],k="",h=0;h<a-1;++h)k+=(0!==h?", ":"")+"arg"+h,f.push("argType"+h),g.push(c[1+h]);var n="return function "+pb("methodCaller_"+b)+"(handle, name, destructors, args) {\n",q=0;for(h=0;h<a-1;++h)n+="    var arg"+h+" = argType"+h+".readValueFromPointer(args"+(q?"+"+q:"")+");\n",q+=c[h+1].argPackAdvance;n+="    var rv = handle[name]("+k+");\n";for(h=0;h<a-1;++h)c[h+1].deleteObject&&(n+="    argType"+h+".deleteObject(arg"+h+");\n");d.Dd||(n+="    return retType.toWireType(destructors, rv);\n");
-f.push(n+"};\n");a=ac(f).apply(null,g);f=sc(a);return uc[b]=f},z:function(a,b){a=ec(a);b=ec(b);return Sb(a[b])},C:function(a){4<a&&(Y[a].uc+=1)},B:function(){return Sb([])},ma:function(a){return Sb(qc(a))},la:function(a){var b=ec(a);kb(b);dc(a)},j:function(a,b){a=oc(a,"_emval_take_value");a=a.readValueFromPointer(b);return Sb(a)},ba:function(a,b){a=new Date(1E3*ib(a));E[b>>2]=a.getSeconds();E[b+4>>2]=a.getMinutes();E[b+8>>2]=a.getHours();E[b+12>>2]=a.getDate();E[b+16>>2]=a.getMonth();E[b+20>>2]=a.getFullYear()-
+f.push(n+"};\n");a=ac(f).apply(null,g);f=sc(a);return uc[b]=f},z:function(a,b){a=ec(a);b=ec(b);return Sb(a[b])},C:function(a){4<a&&(Y[a].uc+=1)},B:function(){return Sb([])},ma:function(a){return Sb(qc(a))},la:function(a){var b=ec(a);kb(b);dc(a)},i:function(a,b){a=oc(a,"_emval_take_value");a=a.readValueFromPointer(b);return Sb(a)},ba:function(a,b){a=new Date(1E3*ib(a));E[b>>2]=a.getSeconds();E[b+4>>2]=a.getMinutes();E[b+8>>2]=a.getHours();E[b+12>>2]=a.getDate();E[b+16>>2]=a.getMonth();E[b+20>>2]=a.getFullYear()-
 1900;E[b+24>>2]=a.getDay();var c=new Date(a.getFullYear(),0,1);E[b+28>>2]=(a.getTime()-c.getTime())/864E5|0;E[b+36>>2]=-(60*a.getTimezoneOffset());var d=(new Date(a.getFullYear(),6,1)).getTimezoneOffset();c=c.getTimezoneOffset();E[b+32>>2]=(d!=c&&a.getTimezoneOffset()==Math.min(c,d))|0},N:function(a,b,c,d,f,g){try{var k=N.rb(d);if(!k)return-8;var h=N.yb(k,a,f,b,c),n=h.Sa;E[g>>2]=h.zc;return n}catch(q){if("undefined"==typeof N||!(q instanceof N.Ma))throw q;return-q.Ra}},O:function(a,b,c,d,f,g){try{var k=
 N.rb(f);if(k&&c&2){var h=z.slice(a,a+b);N.Fb(k,h,g,b,d)}}catch(n){if("undefined"==typeof N||!(n instanceof N.Ma))throw n;return-n.Ra}},ca:yc,m:function(){v("")},J:function(){return 2147483648},w:zc,n:function(a){var b=z.length;a>>>=0;if(2147483648<a)return!1;for(var c=1;4>=c;c*=2){var d=b*(1+.2/c);d=Math.min(d,a+100663296);var f=Math;d=Math.max(a,d);f=f.min.call(f,2147483648,d+(65536-d%65536)%65536);a:{try{pa.grow(f-ua.byteLength+65535>>>16);ya();var g=1;break a}catch(k){}g=void 0}if(g)return!0}return!1},
 Q:function(a,b){var c=0;Bc().forEach(function(d,f){var g=b+c;f=F[a+4*f>>2]=g;for(g=0;g<d.length;++g)B[f++>>0]=d.charCodeAt(g);B[f>>0]=0;c+=d.length+1});return 0},R:function(a,b){var c=Bc();F[a>>2]=c.length;var d=0;c.forEach(function(f){d+=f.length+1});F[b>>2]=d;return 0},l:function(a){try{var b=Q(a);N.close(b);return 0}catch(c){if("undefined"==typeof N||!(c instanceof N.Ma))throw c;return c.Ra}},H:function(a,b){try{var c=Q(a);B[b>>0]=c.tty?2:N.Ya(c.mode)?3:N.vb(c.mode)?7:4;return 0}catch(d){if("undefined"==
diff --git a/web/shared-worker/_generated/comm_query_executor.wasm b/web/shared-worker/_generated/comm_query_executor.wasm
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001

literal 0
Hc$@<O00001

diff --git a/web/shared-worker/queries/olm-persist-data-queries.test.js b/web/shared-worker/queries/olm-persist-data-queries.test.js
--- a/web/shared-worker/queries/olm-persist-data-queries.test.js
+++ b/web/shared-worker/queries/olm-persist-data-queries.test.js
@@ -1,10 +1,29 @@
 // @flow
 
 import { getDatabaseModule } from '../db-module.js';
+import type { OlmPersistSession } from '../types/sqlite-query-executor.js';
 import { clearSensitiveData } from '../utils/db-utils.js';
 
 const FILE_PATH = 'test.sqlite';
 
+const TEST_SESSION_DATA: OlmPersistSession[] = [
+  {
+    targetDeviceID: '1',
+    sessionData: '1',
+    version: 1,
+  },
+  {
+    targetDeviceID: '2',
+    sessionData: '2',
+    version: 2,
+  },
+  {
+    targetDeviceID: '3',
+    sessionData: '3',
+    version: 2,
+  },
+];
+
 describe('Olm Tables queries', () => {
   let queryExecutor;
   let dbModule;
@@ -30,18 +49,9 @@
       'notifsAccountData',
     );
 
-    queryExecutor.storeOlmPersistSession({
-      targetUserID: '1',
-      sessionData: '1',
-    });
-    queryExecutor.storeOlmPersistSession({
-      targetUserID: '2',
-      sessionData: '2',
-    });
-    queryExecutor.storeOlmPersistSession({
-      targetUserID: '3',
-      sessionData: '3',
-    });
+    queryExecutor.storeOlmPersistSession(TEST_SESSION_DATA[0]);
+    queryExecutor.storeOlmPersistSession(TEST_SESSION_DATA[1]);
+    queryExecutor.storeOlmPersistSession(TEST_SESSION_DATA[2]);
   });
 
   afterEach(() => {
@@ -63,5 +73,6 @@
   it('should return all olm sessions', () => {
     const olmSessions = queryExecutor.getOlmPersistSessionsData();
     expect(olmSessions.length).toBe(3);
+    expect(olmSessions).toStrictEqual(TEST_SESSION_DATA);
   });
 });
diff --git a/web/shared-worker/types/sqlite-query-executor.js b/web/shared-worker/types/sqlite-query-executor.js
--- a/web/shared-worker/types/sqlite-query-executor.js
+++ b/web/shared-worker/types/sqlite-query-executor.js
@@ -36,8 +36,9 @@
 };
 
 export type OlmPersistSession = {
-  +targetUserID: string,
+  +targetDeviceID: string,
   +sessionData: string,
+  +version: number,
 };
 
 export type ClientMessageToDevice = {
diff --git a/web/shared-worker/worker/worker-crypto.js b/web/shared-worker/worker/worker-crypto.js
--- a/web/shared-worker/worker/worker-crypto.js
+++ b/web/shared-worker/worker/worker-crypto.js
@@ -99,9 +99,10 @@
 
   const pickledContentSessions: OlmPersistSession[] = entries(
     contentSessions,
-  ).map(([deviceID, session]) => ({
-    targetUserID: deviceID,
+  ).map(([targetDeviceID, session]) => ({
+    targetDeviceID,
     sessionData: session.pickle(contentAccountPickleKey),
+    version: 1,
   }));
 
   const pickledNotificationAccount: PickledOLMAccount = {
@@ -181,7 +182,7 @@
   for (const sessionData of sessionsData) {
     const session = new olm.Session();
     session.unpickle(picklingKey, sessionData.sessionData);
-    sessions[sessionData.targetUserID] = session;
+    sessions[sessionData.targetDeviceID] = session;
   }
 
   return sessions;