diff --git a/book/db/README.md b/book/db/README.md
new file mode 100644
index 000000000..65b25d449
--- /dev/null
+++ b/book/db/README.md
@@ -0,0 +1,333 @@
+# db
+
+The database is a central component to Reth, enabling persistent storage for data like block headers, block bodies, transactions and more. The Reth database is comprised of key-value storage written to the disk and organized in tables. This chapter might feel a little dense at first, but shortly, you will feel very comfortable understanding and navigating the `db` crate. This chapter will go through the structure of the database, its tables and the mechanics of the `Database` trait.
+
+
+
+## Tables
+
+Within Reth, the database is organized via "tables". A table is any struct that implements the `Table` trait.
+
+[File: crates/storage/db/src/abstraction/table.rs](https://github.com/paradigmxyz/reth/blob/main/crates/storage/db/src/abstraction/table.rs#L56-L65)
+```rust ignore
+pub trait Table: Send + Sync + Debug + 'static {
+ /// Return table name as it is present inside the MDBX.
+ const NAME: &'static str;
+ /// Key element of `Table`.
+ ///
+ /// Sorting should be taken into account when encoding this.
+ type Key: Key;
+ /// Value element of `Table`.
+ type Value: Value;
+}
+
+//--snip--
+pub trait Key: Encode + Decode {}
+
+//--snip--
+pub trait Value: Compress + Decompress {}
+
+```
+
+The `Table` trait has two generic values, `Key` and `Value`, which need to implement the `Key` and `Value` traits, respectively. The `Encode` trait is responsible for transforming data into bytes so it can be stored in the database, while the `Decode` trait transforms the bytes back into its original form. Similarly, the `Compress` and `Decompress` traits transform the data to and from a compressed format when storing or reading data from the database.
+
+There are many tables within the node, all used to store different types of data from `Headers` to `Transactions` and more. Below is a list of all of the tables. You can follow [this link](https://github.com/paradigmxyz/reth/blob/main/crates/storage/db/src/tables/mod.rs#L36) if you would like to see the table definitions for any of the tables below.
+
+- CanonicalHeaders
+- HeaderTD
+- HeaderNumbers
+- Headers
+- BlockBodies
+- BlockOmmers
+- NonCanonicalTransactions
+- Transactions
+- TxHashNumber
+- Receipts
+- Logs
+- PlainAccountState
+- PlainStorageState
+- Bytecodes
+- BlockTransitionIndex
+- TxTransitionIndex
+- AccountHistory
+- StorageHistory
+- AccountChangeSet
+- StorageChangeSet
+- TxSenders
+- Config
+- SyncStage
+
+
+
+## Database
+
+Reth's database design revolves around it's main [Database trait](https://github.com/paradigmxyz/reth/blob/0d9b9a392d4196793736522f3fc2ac804991b45d/crates/interfaces/src/db/mod.rs#L33), which takes advantage of [generic associated types](https://blog.rust-lang.org/2022/10/28/gats-stabilization.html) and [a few design tricks](https://sabrinajewson.org/blog/the-better-alternative-to-lifetime-gats#the-better-gats) to implement the database's functionality across many types. Let's take a quick look at the `Database` trait and how it works.
+
+[File: crates/storage/db/src/abstraction/database.rs](https://github.com/paradigmxyz/reth/blob/main/crates/storage/db/src/abstraction/database.rs#L19)
+```rust ignore
+/// Main Database trait that spawns transactions to be executed.
+pub trait Database: for<'a> DatabaseGAT<'a> {
+ /// Create read only transaction.
+ fn tx(&self) -> Result<>::TX, Error>;
+
+ /// Create read write transaction only possible if database is open with write access.
+ fn tx_mut(&self) -> Result<>::TXMut, Error>;
+
+ /// Takes a function and passes a read-only transaction into it, making sure it's closed in the
+ /// end of the execution.
+ fn view(&self, f: F) -> Result
+ where
+ F: Fn(&>::TX) -> T,
+ {
+ let tx = self.tx()?;
+
+ let res = f(&tx);
+ tx.commit()?;
+
+ Ok(res)
+ }
+
+ /// Takes a function and passes a write-read transaction into it, making sure it's committed in
+ /// the end of the execution.
+ fn update(&self, f: F) -> Result
+ where
+ F: Fn(&>::TXMut) -> T,
+ {
+ let tx = self.tx_mut()?;
+
+ let res = f(&tx);
+ tx.commit()?;
+
+ Ok(res)
+ }
+}
+```
+Any type that implements the `Database` trait can create a database transaction, as well as view or update existing transactions. As an example, lets revisit the `Transaction` struct from the `stages` crate. This struct contains a field named `db` which is a reference to a generic type `DB` that implements the `Database` trait. The `Transaction` struct can use the `db` field to store new headers, bodies and senders in the database. In the code snippet below, you can see the `Transaction::open()` method, which uses the `Database::tx_mut()` function to create a mutable transaction.
+
+
+[File: crates/stages/src/db.rs](https://github.com/paradigmxyz/reth/blob/main/crates/stages/src/db.rs#L95-L98)
+```rust ignore
+pub struct Transaction<'this, DB: Database> {
+ /// A handle to the DB.
+ pub(crate) db: &'this DB,
+ tx: Option<>::TXMut>,
+}
+
+//--snip--
+impl<'this, DB> Transaction<'this, DB>
+where
+ DB: Database,
+{
+ //--snip--
+
+ /// Open a new inner transaction.
+ pub fn open(&mut self) -> Result<(), Error> {
+ self.tx = Some(self.db.tx_mut()?);
+ Ok(())
+ }
+}
+```
+
+The `Database` trait also implements the `DatabaseGAT` trait which defines two associated types `TX` and `TXMut`.
+
+[File: crates/storage/db/src/abstraction/database.rs](https://github.com/paradigmxyz/reth/blob/main/crates/storage/db/src/abstraction/database.rs#L11)
+```rust ignore
+/// Implements the GAT method from:
+/// https://sabrinajewson.org/blog/the-better-alternative-to-lifetime-gats#the-better-gats.
+///
+/// Sealed trait which cannot be implemented by 3rd parties, exposed only for implementers
+pub trait DatabaseGAT<'a, __ImplicitBounds: Sealed = Bounds<&'a Self>>: Send + Sync {
+ /// RO database transaction
+ type TX: DbTx<'a> + Send + Sync;
+ /// RW database transaction
+ type TXMut: DbTxMut<'a> + DbTx<'a> + Send + Sync;
+}
+```
+
+In Rust, associated types are like generics in that they can be any type fitting the generic's definition, with the difference being that associated types are associated with a trait and can only be used in the context of that trait.
+
+In the code snippet above, the `DatabaseGAT` trait has two associated types, `TX` and `TXMut`.
+
+The `TX` type can be any type that implements the `DbTx` trait, which provides a set of functions to interact with read only transactions.
+
+[File: crates/storage/db/src/abstraction/transaction.rs](https://github.com/paradigmxyz/reth/blob/main/crates/storage/db/src/abstraction/transaction.rs#L36)
+```rust ignore
+/// Read only transaction
+pub trait DbTx<'tx>: for<'a> DbTxGAT<'a> {
+ /// Get value
+ fn get(&self, key: T::Key) -> Result