diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,9 @@
 # Revision history for ip2location
 
+## 8.7.0  -- 2026-01-12
+
+* Added doInitBS and doQueryBS to allow opening of the BIN file once and querying multiple times.
+
 ## 8.6.0  -- 2025-09-04
 
 * Added support for AS domain, AS usage type and AS CIDR.
diff --git a/IP2Location.hs b/IP2Location.hs
--- a/IP2Location.hs
+++ b/IP2Location.hs
@@ -1,7 +1,7 @@
 {-|
 Module      : IP2Location
 Description : IP2Location Haskell package
-Copyright   : (c) IP2Location, 2023 - 2025
+Copyright   : (c) IP2Location, 2023 - 2026
 License     : MIT
 Maintainer  : sales@ip2location.com
 Stability   : experimental
@@ -15,7 +15,7 @@
 
 IP2Location LITE BIN databases are available for free at http://lite.ip2location.com/
 -}
-module IP2Location (Meta, IP2LocationRecord(..), getAPIVersion, doInit, doQuery) where
+module IP2Location (Meta, IP2LocationRecord(..), getAPIVersion, doInit, doInitBS, doQuery, doQueryBS) where
 
 import qualified Data.ByteString.Lazy as BS
 import qualified Data.ByteString.Lazy.Char8 as BS8
@@ -149,7 +149,7 @@
     The 'getAPIVersion' function returns a string containing the API version.
 -}
 getAPIVersion :: String
-getAPIVersion = "8.6.0"
+getAPIVersion = "8.7.0"
 
 ipToOcts :: IP -> [Int]
 ipToOcts (IPv4 ip) = fromIPv4 ip
@@ -176,6 +176,20 @@
         else do
             return $ stuff
 
+{-|
+    The 'doInitBS' function returns the Meta record containing metadata from the content.
+    It takes one argument, of type 'BS.ByteString', which is the content of the BIN database file.
+-}
+doInitBS :: BS.ByteString -> IO Meta
+doInitBS contents = do
+    let stuff = runGet getMeta contents
+    let iswrong = (show (wrongbin stuff))
+    if iswrong == "1"
+        then do
+            die(show "Incorrect IP2Location BIN file format. Please make sure that you are using the latest IP2Location BIN file.")
+        else do
+            return $ stuff
+
 readuint8 :: BS.ByteString -> Int -> Int
 readuint8 contents startpos = fromIntegral (runGet getWord8 (BS.drop (fromIntegral startpos - 1) contents))
 
@@ -409,6 +423,47 @@
 doQuery :: String -> Meta -> String -> IO IP2LocationRecord
 doQuery myfile meta myip = do
     contents <- BS.readFile myfile
+    let fromV4Mapped = 281470681743360
+    let toV4Mapped = 281474976710655
+    let fromV4Compatible = 0
+    let toV4Compatible = 4294967295
+    let from6To4 = 42545680458834377588178886921629466624
+    let to6To4 = 42550872755692912415807417417958686719
+    let fromTeredo = 42540488161975842760550356425300246528
+    let toTeredo = 42540488241204005274814694018844196863
+    let last32Bits = 4294967295
+    
+    ipnum <- tryfirst myip
+    if ipnum == -1
+        then do
+            let x = "Invalid IP address."
+            return $ IP2LocationRecord x x x x x 0.0 0.0 x x x x x x x x x x x 0.0 x x x x x x x x x
+        else if ipnum >= fromV4Mapped && ipnum <= toV4Mapped
+            then do
+                return $ search4 contents (ipnum - (toInteger fromV4Mapped)) (databasetype meta) 0 (ipv4databasecount meta) (ipv4databaseaddr meta) (ipv4indexbaseaddr meta) (ipv4columnsize meta)
+            else if ipnum >= from6To4 && ipnum <= to6To4
+                then do
+                    return $ search4 contents ((ipnum `rotateR` 80) .&. last32Bits) (databasetype meta) 0 (ipv4databasecount meta) (ipv4databaseaddr meta) (ipv4indexbaseaddr meta) (ipv4columnsize meta)
+                else if ipnum >= fromTeredo && ipnum <= toTeredo
+                    then do
+                        return $ search4 contents ((complement ipnum) .&. last32Bits) (databasetype meta) 0 (ipv4databasecount meta) (ipv4databaseaddr meta) (ipv4indexbaseaddr meta) (ipv4columnsize meta)
+                    else if ipnum >= fromV4Compatible && ipnum <= toV4Compatible
+                        then do
+                            return $ search4 contents ipnum (databasetype meta) 0 (ipv4databasecount meta) (ipv4databaseaddr meta) (ipv4indexbaseaddr meta) (ipv4columnsize meta)
+                        else if (ipv6databasecount meta) == 0
+                            then do
+                                let x = "IPv6 address missing in IPv4 BIN."
+                                return $ IP2LocationRecord x x x x x 0.0 0.0 x x x x x x x x x x x 0.0 x x x x x x x x x
+                            else do
+                                return $ search6 contents ipnum (databasetype meta) 0 (ipv6databasecount meta) (ipv6databaseaddr meta) (ipv6indexbaseaddr meta) (ipv6columnsize meta)
+
+
+{-|
+    The 'doQueryBS' function returns an IP2LocationRecord containing geolocation data for an IP address.
+    It takes 3 arguments; the content of the BIN database file (BS.ByteString), the metadata from 'doInitBS' function (Meta record) & either IPv4 or IPv6 address (String).
+-}
+doQueryBS :: BS.ByteString -> Meta -> String -> IO IP2LocationRecord
+doQueryBS contents meta myip = do
     let fromV4Mapped = 281470681743360
     let toV4Mapped = 281474976710655
     let fromV4Compatible = 0
diff --git a/IP2LocationWebService.hs b/IP2LocationWebService.hs
--- a/IP2LocationWebService.hs
+++ b/IP2LocationWebService.hs
@@ -2,7 +2,7 @@
 {-|
 Module      : IP2LocationWebService
 Description : IP2Location Haskell package
-Copyright   : (c) IP2Location, 2023 - 2025
+Copyright   : (c) IP2Location, 2023 - 2026
 License     : MIT
 Maintainer  : sales@ip2location.com
 Stability   : experimental
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 MIT License
 
-Copyright (c) 2023 - 2025 IP2Location.com
+Copyright (c) 2023 - 2026 IP2Location.com
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/ip2location.cabal b/ip2location.cabal
--- a/ip2location.cabal
+++ b/ip2location.cabal
@@ -10,7 +10,7 @@
 -- PVP summary:      +-+------- breaking API changes
 --                   | | +----- non-breaking API additions
 --                   | | | +--- code changes with no API change
-version:             8.6.0
+version:             8.7.0
 
 -- A short (one-line) description of the package.
 synopsis:            IP2Location Haskell package for IP geolocation.
