I suggest exploiting the space from 0x80 for the data type byte. This can help save space in that for values from 0 to 127 you can use the value 0x80 + num. That is, the two-byte value [i][2] (69 02) will be expressed in only one byte: [i-2] (82).
It can be done not only with the numbers, but also with one-char value names: "d" > [i][1][d] (69 02 64) > [c-d] (E4). In this case, the ASCII char value will be also added to 0x80. Numeric value, as in the previous paragraph, will be used until 31 (9F) (0 <= x <= 31).
Example:
| Before |
After |
[{] [i][4][name][S][i][4][John] [i][6][salary][I][12000] [i][9][seniority][i][7] [i][1][v][i][24] [}] |
[{] [i-4][name][S][i-4][John] [i-6][salary][I][12000] [i-9][seniority][i-7] [c-v][i-24] [}] |
| 44 bytes |
36 bytes (18% less) |