Am I using buffers correctly

I want to know if this is how you would use buffers:

local Buffer = buffer.create(15)

buffer.writestring(Buffer, 0, "value", 5)
buffer.writei16(Buffer, 5, 1500)
buffer.writef32(Buffer, 7, math.round(3624.124 * 1000))
buffer.writei32(Buffer, 11, 257757237)

print(string.format("Buffer: %s | Size: %i", buffer.tostring(Buffer), buffer.len(Buffer)))

print("---------------------------------------------")

print(buffer.readstring(Buffer, 0, 5))
print(buffer.readi16(Buffer, 5))
print(buffer.readf32(Buffer, 7) / 1000)
print(buffer.readi32(Buffer, 11))

Result:
image
Buffer: value��2]J5] | Size: 15

value
1500
3624.124
257757237

And if you can tell me how many bits it would take without buffers compared to how many bits with the buffer

yes, you are using buffers correctly

with the buffer you created a 15 bytes buffer so 15 bytes

without buffers

5 + 8 + 8 + 8 = 29 bytes-

though I have read in some devforum posts that values in luau have +1 extra byte overhead that stores the value (not sure if this is correct)

and if you will send that buffer across the network then it can get compressed

though idk why did you use round and multiply that number, f means float which can also store decimal numbers so you can do this instead
buffer.writef32(Buffer, 7, 3624.124)

wait so how did you get 8?

In the introducing buffers post, I saw them multiply the orientation by 100 and divide it by 100 after receiving it and they said that it could reduce it even more

-- each object takes 3*4 bytes for position and 3*2 bytes for orientation
local buf = buffer.create(#objects * (12 + 6))

for i, obj: Part in objects do
    local offset = (i - 1) * (12 + 6) -- note: buffer offsets are 0-based
    local pos, ori = obj.Position, obj.Orientation

    -- 12 bytes for position, 4 bytes per component
    buffer.writef32(buf, offset + 0, pos.X)
    buffer.writef32(buf, offset + 4, pos.Y)
    buffer.writef32(buf, offset + 8, pos.Z)

    -- 6 bytes for orientation, 2 bytes per component
    -- note: orientation components use degrees with -180..180 range
    -- we're a little sloppy here and use a subset of the full i16 range
    -- when reading this data, make sure to divide i16 by 100
    buffer.writei16(buf, offset + 12, math.round(ori.X * 100))
    buffer.writei16(buf, offset + 14, math.round(ori.Y * 100))
    buffer.writei16(buf, offset + 16, math.round(ori.Z * 100))
end

numbers in luau are 64-bit by default which is 8 bytes
and if you are typing asci in strings then each character is 1 byte

orientation got multiplied by 100 so that it can be stored as an integer (i16)

integers are unable to store decimals, but orientation contain decimals
example
orientation is 85.58
you multiply is by 100 and it becomes ( 8558 )
you send it to client
client divides it by 100 and it becomes ( 85.58 )

but in your topic, you used f32 which is able to store decimals directly, but it uses 4 bytes while i16 uses 2 bytes