diff --git a/src/slice/requirements.in b/src/slice/requirements.in
index daef740da4729659fb3117eadff31994acdf5746..42a96f5a576338b82aff2e246c3d187d252302b3 100644
--- a/src/slice/requirements.in
+++ b/src/slice/requirements.in
@@ -12,5 +12,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-
 #deepdiff==5.8.*
+numpy==1.23.*
+scikit-learn==1.1.*
diff --git a/src/slice/service/README.md b/src/slice/service/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..696b4a6e099cfc8463db6f93e5940cbc1d9c32e1
--- /dev/null
+++ b/src/slice/service/README.md
@@ -0,0 +1,38 @@
+# SLICE GROUPING details
+
+## Description
+- Similar slice requests can share underlying services.
+- Clustering algorithm for slice grouping.
+- Consider both paths and SLA constraints.
+- SLA monitored by slice group.
+
+## TFS Target Objective
+- Objective 3.2: Provisioning of multi-tenant transport network slices.
+- Improve network resource usage by 30% by adopting multi-tenancy resource allocation algorithms.
+- Optimal slice grouping: trade-offs between economies of scale and limitations as to which SLAs can be grouped together need to be considered.
+- Optimal grouping of slices is required to maximise KPIs, such as resource utilisation, utility of the connectivity, and energy efficiency.
+- In this context, trade-offs between the resulting control plane complexity and differential treatment of SLA classes should be considered.
+
+## New Requirements
+- User can select if slice grouping is performed per-slice request.
+- Slice grouping introduces a clustering algorithm for finding service optimisation while preserving slice SLA.
+- Service (re-)optimisation is provided.
+
+## TFS Architecture Update
+- Update Slice service RPC to include Slice Grouping.
+- Use novel Slice model with SLA constraints.
+- Use Policy Component with action to update services to apply slice grouping.
+- Describe Slice service operation modes: per-request or user-triggered.
+
+    OSS/BSS --> Slice   : Create Slice with SLA (slice)
+    Slice   --> Slice   : Slice Grouping (slice)
+alt [slice can be grouped to other slice services]
+    // do nothing and return existing slice
+else [slice needs new services]
+    Slice   --> ... : normal logic
+end alt
+    Slice   --> OSS/BSS : slice
+
+slice.proto:
+  rpc OrderSliceWithSLA(context.Slice) returns (context.SliceId) {} // If slice with SLA already exists, returns slice. If not, it creates it.
+  rpc RunSliceGrouping (context.Empty) returns (context.Empty) {} // Optimizes the underlying services and re-maps them to the requested slices.
diff --git a/src/slice/service/SliceGrouper.py b/src/slice/service/SliceGrouper.py
new file mode 100644
index 0000000000000000000000000000000000000000..e5363de1b30f0dd876b276d226d65e083f7901a4
--- /dev/null
+++ b/src/slice/service/SliceGrouper.py
@@ -0,0 +1,61 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#import numpy as np
+#import pandas as pd
+from matplotlib import pyplot as plt
+from sklearn.datasets import make_blobs
+from sklearn.cluster import KMeans
+from common.proto.context_pb2 import ContextId
+from context.client.ContextClient import ContextClient
+
+class SliceGrouper:
+    def __init__(self) -> None:
+        pass
+
+    def load_slices(self, context_uuid : str) -> None:
+        context_client = ContextClient()
+
+        
+        context_client.ListSlices(ContextId)
+
+X, y = make_blobs(n_samples=300, n_features=2, cluster_std=[(10,.1),(100,.01)],centers= [(10,.9), (100,.99)])
+
+plt.scatter(X[:,0], X[:,1])
+plt.show()
+
+
+wcss = []
+for i in range(1, 11):
+    kmeans = KMeans(n_clusters=i, init='k-means++', max_iter=300, n_init=10, random_state=0)
+    kmeans.fit(X)
+    wcss.append(kmeans.inertia_)
+plt.plot(range(1, 11), wcss)
+plt.title('Elbow Method')
+plt.xlabel('Number of clusters')
+plt.ylabel('WCSS')
+plt.show()
+
+
+kmeans = KMeans(n_clusters=2, init='k-means++', max_iter=300, n_init=10, random_state=0)
+pred_y = kmeans.fit_predict(X)
+plt.scatter(X[:,0], X[:,1])
+plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s=300, c='red')
+plt.ylabel('service-slo-availability')
+plt.xlabel('service-slo-one-way-bandwidth')
+ax = plt.subplot(1, 1, 1)
+
+ax.set_ylim(bottom=0., top=1.)
+ax.set_xlim(left=0.)
+plt.show()