diff --git a/src/shared/scheduler/TaskScheduler.cpp b/src/shared/scheduler/TaskScheduler.cpp
index a071374d1aa8ba12b98881314fd6a76c1d3c339a..cb9d4107f71cabaa976c5cfcc04b89a7122b2933 100644
--- a/src/shared/scheduler/TaskScheduler.cpp
+++ b/src/shared/scheduler/TaskScheduler.cpp
@@ -35,40 +35,36 @@ namespace Boardcore
 TaskScheduler::TaskScheduler()
     : ActiveObject(STACK_MIN_FOR_SKYWARD, miosix::PRIORITY_MAX - 1)
 {
-    stopFlag       = false;
-    running        = false;
-    possibleFreeID = 1;
+    stopFlag = false;
+    running  = false;
 }
 
-uint8_t TaskScheduler::addTask(function_t function, uint32_t period,
-                               Policy policy, int64_t startTick)
+size_t TaskScheduler::addTask(function_t function, uint32_t period,
+                              Policy policy, int64_t startTick)
 {
 
     Lock<FastMutex> lock(mutex);
-    uint8_t id = possibleFreeID;
+    size_t id = 1;
 
     // Find a suitable id for the new task
-    for (; id < 255 && tasks[id] != nullptr; ++id)
+    for (; id < TASKS_SIZE && tasks[id].valid == false; id++)
         ;
 
-    possibleFreeID = id + 1;
     // Check if in the corresponding id there's already a task
-    if (tasks[id] != nullptr)
+    if (tasks[id].valid)
     {
-        LOG_ERR(logger, "Full task scheduler, id = 255");
+        LOG_ERR(logger, "Full task scheduler, id = {:zu}", id);
         return 0;
     }
 
     // Register the task into the map
-    Task* task =
-        new Task{function, period, id, true, policy, -1, {}, {}, {}, 0, 0};
-    tasks[id] = task;
+    tasks[id] = makeTask(function, period, id, true, policy);
 
     if (policy == Policy::ONE_SHOT)
         startTick += period;
 
     // Add the task first event in the agenda
-    Event event = {task, startTick};
+    Event event = {&(tasks[id]), startTick};
     agenda.push(event);
     condvar.broadcast();  // Signals the run thread
 
@@ -80,21 +76,14 @@ bool TaskScheduler::removeTask(uint8_t id)
     Lock<FastMutex> lock(mutex);
 
     // Check if the task is actually present
-    if (tasks[id] == nullptr)
+    if (tasks[id].valid == false)
     {
         LOG_ERR(logger, "Attempting to remove a task not registered");
         return false;
     }
 
     // Set the validity of the task to false
-    tasks[id]->valid = false;
-
-    // Remove the task from the tasks array
-    // We do not deallocate the task here because of future deallocation when
-    // popped from queue
-    tasks[id] = nullptr;
-    if (id < possibleFreeID)
-        possibleFreeID = id;
+    tasks[id].valid = false;
 
     return true;
 }
@@ -128,7 +117,7 @@ vector<TaskStatsResult> TaskScheduler::getTaskStats()
 
     for (auto& task : tasks)
     {
-        if (task != nullptr)
+        if (task.valid)
             result.push_back(fromTaskIdPairToStatsResult(task));
     }
 
@@ -206,7 +195,6 @@ void TaskScheduler::run()
         {
             if (!nextEvent.task->valid)
             {
-                delete nextEvent.task;
                 agenda.pop();
             }
 
@@ -248,9 +236,7 @@ void TaskScheduler::enqueue(Event& event, int64_t startTick)
         case Policy::ONE_SHOT:
             // If the task is one shot we won't push it to the agenda and we'll
             // remove it from the tasks map.
-            tasks[event.task->id] = nullptr;
-            if (event.task->id < possibleFreeID)
-                possibleFreeID = event.task->id;
+            tasks[event.task->id].valid = false;
             delete event.task;
 
             return;
@@ -280,4 +266,11 @@ void TaskScheduler::enqueue(Event& event, int64_t startTick)
     condvar.broadcast();
 }
 
+TaskScheduler::Task TaskScheduler::makeTask(function_t function,
+                                            uint32_t period, size_t id,
+                                            bool validity, Policy policy)
+{
+    return Task{function, period, id, validity, policy, -1, {}, {}, {}, 0, 0};
+}
+
 }  // namespace Boardcore
diff --git a/src/shared/scheduler/TaskScheduler.h b/src/shared/scheduler/TaskScheduler.h
index daa18abdd1f52b0d6644b7f6287b5f792e5c5ad1..0efe40985e90d90fff586aadbb15f6fd85821f1b 100644
--- a/src/shared/scheduler/TaskScheduler.h
+++ b/src/shared/scheduler/TaskScheduler.h
@@ -61,6 +61,11 @@ class TaskScheduler : public ActiveObject
 public:
     typedef std::function<void()> function_t;
 
+    /**
+     * @brief It defines the tasks array maximum size
+     */
+    static constexpr size_t TASKS_SIZE = 256;
+
     /**
      * @brief Task behavior policy.
      *
@@ -107,9 +112,9 @@ public:
      * @param startTick First activation time, useful for synchronizing tasks.
      * @return true if the task was added successfully.
      */
-    uint8_t addTask(function_t function, uint32_t period,
-                    Policy policy     = Policy::SKIP,
-                    int64_t startTick = miosix::getTick());
+    size_t addTask(function_t function, uint32_t period,
+                   Policy policy     = Policy::SKIP,
+                   int64_t startTick = miosix::getTick());
 
     /**
      * @brief Removes the task identified by the given id if it exists.
@@ -136,7 +141,7 @@ private:
     {
         function_t function;
         uint32_t period;
-        uint8_t id;
+        size_t id;
         bool valid;
         Policy policy;
         int64_t lastCall;  ///< Last activation tick for statistics computation.
@@ -186,23 +191,35 @@ private:
      */
     void enqueue(Event& event, int64_t startTick);
 
-    static TaskStatsResult fromTaskIdPairToStatsResult(Task* task)
+    /**
+     * @brief Creates a task with the passed values
+     *
+     * @param function The std::function to be called
+     * @param period The Period in [ms]
+     * @param id The task intrinsic id
+     * @param validity The validity of the task (false if not initialized or if
+     * removed)
+     * @param policy The task policy in case of a miss
+     */
+    Task makeTask(function_t function, uint32_t period, size_t id,
+                  bool validity, Policy policy);
+
+    static TaskStatsResult fromTaskIdPairToStatsResult(Task task)
     {
 
-        return TaskStatsResult{task->id,
-                               task->period,
-                               task->activationStats.getStats(),
-                               task->periodStats.getStats(),
-                               task->workloadStats.getStats(),
-                               task->missedEvents,
-                               task->failedEvents};
+        return TaskStatsResult{task.id,
+                               task.period,
+                               task.activationStats.getStats(),
+                               task.periodStats.getStats(),
+                               task.workloadStats.getStats(),
+                               task.missedEvents,
+                               task.failedEvents};
     }
 
-    miosix::FastMutex mutex;            ///< Mutex to protect tasks and agenda.
-    std::array<Task*, 256> tasks{};     ///< Holds all tasks to be scheduled.
-    miosix::ConditionVariable condvar;  ///< Used when agenda is empty.
-    std::priority_queue<Event> agenda;  ///< Ordered list of functions.
-    uint8_t possibleFreeID;
+    miosix::FastMutex mutex;  ///< Mutex to protect tasks and agenda.
+    std::array<Task, TASKS_SIZE> tasks{};  ///< Holds all tasks to be scheduled.
+    miosix::ConditionVariable condvar;     ///< Used when agenda is empty.
+    std::priority_queue<Event> agenda;     ///< Ordered list of functions.
 
     PrintLogger logger = Logging::getLogger("taskscheduler");
 };
diff --git a/src/shared/scheduler/TaskSchedulerData.h b/src/shared/scheduler/TaskSchedulerData.h
index f1c43d31f10ff54c1b2a6d26bf9932647a3a4769..8b612714a0f1bda9de9a29914a9f7d71560248c3 100644
--- a/src/shared/scheduler/TaskSchedulerData.h
+++ b/src/shared/scheduler/TaskSchedulerData.h
@@ -43,7 +43,7 @@ namespace Boardcore
  */
 struct TaskStatsResult
 {
-    uint8_t id;
+    size_t id;
     uint32_t period;
     StatsResult activationStats;
     StatsResult periodStats;