Need help with with hitbox system

So I’m trying to make a hitbox system that does the following:

Client fires RemoteEvent to the server, giving the server the current time according to the client.

The server every HeartBeat records the time, and the CFrame of the HumanoidRootPart, according to the server.

When the server receives the RemoteEvent, it finds the the time closest to the Time given by client. And creates a Hitbox at the point.

This is the code:

local Players = game:GetService("Players")

local Shared = require(script.Shared)

Players.PlayerAdded:Connect(function(Player)
    Player.CharacterAdded:Wait()
    
    Player.Character.Archivable = true
    
    for _,v in pairs(Player.Character:GetDescendants()) do
        Player.Character:WaitForChild("HumanoidRootPart")
        if v:IsA("BasePart") then
            v.CollisionGroup = "Players"
        end
    end
end)

Players.PlayerRemoving:Connect(function(Player)
    if Shared.Past[Player] then
        Shared.Past[Player] = nil
    end
end)

game.ReplicatedStorage.Hitbox.OnServerEvent:Connect(function(Player, timestamp)
    
    local Character = Player.Character

    local HitPart = Instance.new("Part")
    HitPart.Size = Vector3.new(1,1,1)
    HitPart.Anchored = true
    HitPart.CFrame = Character.HumanoidRootPart.CFrame
    HitPart.Color = Color3.fromRGB(255,255,0)
    HitPart.Transparency = 0
    HitPart.CanCollide = false
    HitPart.Material = Enum.Material.Neon
    HitPart.Parent = workspace
        
    if not Shared.Past[Player] then return end

    local CurrentTimestamp = nil

    for t, CF in Shared.Past[Player] do
        if not CurrentTimestamp then
            CurrentTimestamp = t
        else

            if math.abs(t - timestamp) < math.abs(CurrentTimestamp - timestamp) then
                CurrentTimestamp = t                
            end
        end
    end

    warn(math.abs(workspace:GetServerTimeNow() - timestamp))
    warn(math.abs(CurrentTimestamp - timestamp))

    local CF = Shared.Past[Player][CurrentTimestamp]
    
    local HitPart = Instance.new("Part")
    HitPart.Size = Vector3.new(1,1,1)
    HitPart.Anchored = true
    HitPart.CFrame = CF
    HitPart.Color = Color3.fromRGB(255,0,0)
    HitPart.Transparency = 0
    HitPart.CanCollide = false
    HitPart.Material = Enum.Material.Neon
    HitPart.Parent = workspace
    
end)

game:GetService("RunService").Heartbeat:Connect(function()
    for _,Player : Player in Players:GetChildren() do
        local Character = Player.Character

        if not Character then continue end --//-- passes to next iteration if character is nil

        local HumanoidRootPart = Character:FindFirstChild("HumanoidRootPart")

        if not HumanoidRootPart then continue end --//-- passes to next iteration if HumanoidRootPart is nil

        local t = workspace:GetServerTimeNow()

        if Shared.Past[Player] then
            Shared.Past[Player][t] = HumanoidRootPart.CFrame
        else
            Shared.Past[Player] = {}
            Shared.Past[Player][t] = HumanoidRootPart.CFrame
        end

        for t, CF in Shared.Past[Player] do
            if workspace:GetServerTimeNow() - t > 0.15 then
                Shared.Past[Player][t] = nil
            end
        end
    end  
end)

Client:

local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Character = script.Parent

UserInputService.InputBegan:Connect(function(Input, GPE)
    if GPE then return end
    
    if Input.UserInputType == Enum.UserInputType.MouseButton1 then
        
        local HitPart = Instance.new("Part")
        HitPart.Size = Vector3.new(1,1,1)
        HitPart.Anchored = true
        HitPart.CFrame = Character.HumanoidRootPart.CFrame
        HitPart.Color = Color3.fromRGB(0,255,0)
        HitPart.CanCollide = false
        HitPart.Transparency = 0
        HitPart.Material = Enum.Material.Neon
        HitPart.Parent = workspace
        
        ReplicatedStorage.Hitbox:FireServer(workspace:GetServerTimeNow())
        
    end
end)

Problem is the hitbox is being created way too late, much after the client.

Here’s a representation of what I mean:

The Green is the client, yellow is the server, and the little red behind the yellow is where he hitbox will be created with the system.

As you can clearly see the Hitbox according to this will be created even later than the server.

If you have knowledge in this field, please do help me out. Espeically on how I could improve or change this system to make it work or make a good reliable hitbox system.

The official docs mentions that the workspace:GetServerTimeNow() is only an approximation, thus it’s not fully accurate.

Not to mention, sending the request also takes some time.