diff --git a/client/beefy/src/aux_schema.rs b/client/beefy/src/aux_schema.rs
new file mode 100644
index 0000000000000..e9a2e9b9e6126
--- /dev/null
+++ b/client/beefy/src/aux_schema.rs
@@ -0,0 +1,105 @@
+// This file is part of Substrate.
+
+// Copyright (C) 2019-2022 Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+//! Schema for BEEFY state persisted in the aux-db.
+
+use crate::worker::PersistedState;
+use codec::{Decode, Encode};
+use log::{info, trace};
+use sc_client_api::{backend::AuxStore, Backend};
+use sp_blockchain::{Error as ClientError, Result as ClientResult};
+use sp_runtime::traits::Block as BlockT;
+
+const VERSION_KEY: &[u8] = b"beefy_auxschema_version";
+const WORKER_STATE: &[u8] = b"beefy_voter_state";
+
+const CURRENT_VERSION: u32 = 1;
+
+pub(crate) fn write_current_version(backend: &B) -> ClientResult<()> {
+ info!(target: "beefy", "🥩 write aux schema version {:?}", CURRENT_VERSION);
+ AuxStore::insert_aux(backend, &[(VERSION_KEY, CURRENT_VERSION.encode().as_slice())], &[])
+}
+
+/// Write voter state.
+pub(crate) fn write_voter_state(
+ backend: &B,
+ state: &PersistedState,
+) -> ClientResult<()> {
+ trace!(target: "beefy", "🥩 persisting {:?}", state);
+ backend.insert_aux(&[(WORKER_STATE, state.encode().as_slice())], &[])
+}
+
+fn load_decode(backend: &B, key: &[u8]) -> ClientResult