diff --git a/.gitignore b/.gitignore
index 33b68146aa9a024e14107b02d40c194a884ca0f2..0d24f636be7a5c33097e616fa54150cd03d386df 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,4 @@ venv
 .venv
 .vscode
 docs/build
+bom.json
\ No newline at end of file
diff --git a/Changelog.md b/Changelog.md
index db9c93808bcda05ecc040fd654f472d50222144a..7cfc715db7fa499b500362c27301f52211daaa43 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -2,7 +2,10 @@
 
 All notable changes to this project will be documented in this file.
 
-## [0.145] - 2025-05-27
+## [0.147] - 2025-06-05
+- DBOARD3-1247: use threads for redis lookup of router interface services
+
+## [0.146] - 2025-05-27
 - NGM-15/19/20: added /map/pops & /map/equipment
 
 ## [0.145] - 2025-05-20
@@ -13,7 +16,6 @@ All notable changes to this project will be documented in this file.
 - DBOARD3-1152: Added full OIDs for active state checking
 - DBOARD3-1142: Added token based authentication
 
-
 ## [0.143] - 2025-03-06
 - POL1-886: Fix: Skip snmp info for nokia services
 
diff --git a/MANIFEST.in b/MANIFEST.in
deleted file mode 100644
index 15e9c71c38764b7528b3f1c2b118546cb49e8773..0000000000000000000000000000000000000000
--- a/MANIFEST.in
+++ /dev/null
@@ -1,3 +0,0 @@
-recursive-include inventory_provider/static *
-include inventory_provider/logging_default_config.json
-recursive-exclude test *
diff --git a/inventory_provider/routes/classifier.py b/inventory_provider/routes/classifier.py
index e22c923f4df871f9264136fe8eed3af2a4be140f..5b85c47510b89c0411fc017879610187a7e72127 100644
--- a/inventory_provider/routes/classifier.py
+++ b/inventory_provider/routes/classifier.py
@@ -61,7 +61,7 @@ import re
 from functools import lru_cache
 from typing import Iterable, List, Optional
 
-from flask import Blueprint, Response, request
+from flask import Blueprint, Response, request, current_app
 from redis import Redis
 
 from inventory_provider.routes import common
@@ -1273,12 +1273,15 @@ def _get_router_info(ims_source_equipment, redis):
             vendor = _r['vendor']
             break
 
-    for key in redis.scan_iter(f"ims:interface_services:{ims_source_equipment}:*"):
-        raw_services = redis.get(key.decode())
-        if not raw_services:
+    for result in common.load_json_docs(
+        config_params=current_app.config["INVENTORY_PROVIDER_CONFIG"],
+        key_pattern=f"ims:interface_services:{ims_source_equipment}:*",
+        num_threads=20,
+    ):
+        services = result["value"]
+        if not services:
             continue
 
-        services = json.loads(raw_services)
         for service in services:
             related_services.update({r["id"]: r for r in service["related-services"]})
             contacts.update(service.get("contacts", []))
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000000000000000000000000000000000000..5888ffbfd412f35a665931d34ea7c7125a932d5b
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,57 @@
+[build-system]
+build-backend = "setuptools.build_meta"
+requires = ["setuptools>=77", "setuptools-scm>=8.0", "wheel"]
+
+[project]
+name = "inventory-provider"
+version = "0.147"
+description = "Dashboard inventory provider"
+authors = [{ name = "GÉANT", email = "swd@geant.org" }]
+readme = "README.md"
+requires-python = ">=3.9"
+license = "MIT"
+license-files = ["LICENSE.txt"]
+classifiers = [
+    "Programming Language :: Python :: 3",
+    "Programming Language :: Python :: 3.9",
+    "Programming Language :: Python :: 3.10",
+    "Programming Language :: Python :: 3.11",
+    "Programming Language :: Python :: 3.12",
+    "Operating System :: OS Independent",
+    "Development Status :: 5 - Production/Stable",
+]
+dependencies = [
+    "click",
+    "mysql-connector",
+    "pyasn1==0.4.8",
+    "pysnmp==4.4.12",
+    "jsonschema",
+    "paramiko",
+    "flask",
+    "flask-cors",
+    "redis",
+    "kombu",
+    "vine",
+    "celery",
+    "junos-eznc",
+    "ncclient",
+    "lxml==4.9.4",
+    "requests",
+    "netifaces",
+    "tree-format",
+    "sentry-sdk[flask,celery]",
+]
+
+
+[project.optional-dependencies]
+health = ["flask", "arrow", "apscheduler<4"]
+web = ["flask", "flask-sqlalchemy"]
+
+[project.urls]
+Homepage = "https://gitlab.software.geant.org/geant-swd/dashboardv3/inventory-provider/"
+
+[project.scripts]
+monitor-tasks = "inventory_provider.tasks.monitor:run"
+
+[tool.setuptools.packages.find]
+include = ["inventory_provider*"]
diff --git a/setup.py b/setup.py
deleted file mode 100644
index d99f1e76be04064f12c3888f48cf5e8fdb25a9ac..0000000000000000000000000000000000000000
--- a/setup.py
+++ /dev/null
@@ -1,53 +0,0 @@
-from setuptools import setup, find_packages
-
-setup(
-    name='inventory-provider',
-    version="0.146",
-    author='GEANT',
-    author_email='swd@geant.org',
-    description='Dashboard inventory provider',
-    url=('https://gitlab.geant.net/live-projects'
-         '/dashboardv3/inventory-provider'),
-    packages=find_packages(),
-    install_requires=[
-        'click',
-        'mysql-connector',
-        'pyasn1==0.4.8',
-        'pysnmp==4.4.12',
-        'jsonschema',
-        'paramiko',
-        'flask',
-        'flask-cors',
-        'redis',
-        'kombu',
-        'vine',
-        'celery',
-        'junos-eznc',
-        'ncclient',
-        'lxml==4.9.4',
-        'requests',
-        'netifaces',
-        'tree-format',
-        'sentry-sdk[flask,celery]',
-        'Flask-HTTPAuth'
-    ],
-    entry_points={
-        'console_scripts': [
-            'monitor-tasks=inventory_provider.tasks.monitor:run'
-        ]
-    },
-    include_package_data=True,
-    license='MIT',
-    license_files=('LICENSE.txt',),
-    classifiers=[
-        'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.6',
-        'Programming Language :: Python :: 3.7',
-        'Programming Language :: Python :: 3.8',
-        'Programming Language :: Python :: 3.9',
-        'License :: OSI Approved :: MIT License',
-        'Operating System :: OS Independent',
-        'Development Status :: 5 - Production/Stable'
-    ],
-    python_requires='>=3.6'
-)