diff --git a/src/config.rs b/src/config.rs
index ddb5344..6721f57 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,5 +1,6 @@
 use crate::bindings;
 
+#[derive(Copy, Clone)]
 pub struct Config {
     pub config: bindings::ndb_config,
 }
diff --git a/src/ndb.rs b/src/ndb.rs
index 8294af8..0e6e8fe 100644
--- a/src/ndb.rs
+++ b/src/ndb.rs
@@ -10,6 +10,7 @@ use std::os::raw::c_int;
 use std::path::Path;
 use std::sync::Arc;
 use tokio::task; // Make sure to import the task module
+use tracing::debug;
 
 #[derive(Debug)]
 struct NdbRef {
@@ -51,7 +52,28 @@ impl Ndb {
             let _ = fs::create_dir_all(path);
         }
 
-        let result = unsafe { bindings::ndb_init(&mut ndb, db_dir_cstr.as_ptr(), config.as_ptr()) };
+        let min_mapsize = 1024 * 1024 * 512;
+        let mut mapsize = config.config.mapsize;
+        let mut config = *config;
+
+        let result = loop {
+            let result =
+                unsafe { bindings::ndb_init(&mut ndb, db_dir_cstr.as_ptr(), config.as_ptr()) };
+
+            if result == 0 {
+                mapsize /= 2;
+                config = config.set_mapsize(mapsize);
+                debug!("ndb init failed, reducing mapsize to {}", mapsize);
+
+                if mapsize > min_mapsize {
+                    continue;
+                } else {
+                    break 0;
+                }
+            } else {
+                break result;
+            }
+        };
 
         if result == 0 {
             return Err(Error::DbOpenFailed);
@@ -448,4 +470,43 @@ mod tests {
             assert_eq!(note.kind(), 1);
         }
     }
+
+    #[test]
+    #[cfg(target_os = "windows")]
+    fn test_windows_large_mapsize() {
+        use std::{fs, path::Path};
+
+        let db = "target/testdbs/windows_large_mapsize";
+        test_util::cleanup_db(&db);
+
+        {
+            // 32 TiB should be way too big for CI
+            let config =
+                Config::new().set_mapsize(1024usize * 1024usize * 1024usize * 1024usize * 32usize);
+
+            // in this case, nostrdb should try to keep resizing to
+            // smaller mapsizes until success
+
+            let ndb = Ndb::new(db, &config);
+
+            assert!(ndb.is_ok());
+        }
+
+        let file_len = fs::metadata(Path::new(db).join("data.mdb"))
+            .expect("metadata")
+            .len();
+
+        assert!(file_len > 0);
+
+        if cfg!(target_os = "windows") {
+            // on windows the default mapsize will be 1MB when we fail
+            // to open it
+            assert_ne!(file_len, 1048576);
+        } else {
+            assert!(file_len < 1024u64 * 1024u64);
+        }
+
+        // we should definitely clean this up... especially on windows
+        test_util::cleanup_db(&db);
+    }
 }