by voxels, do you mean actual parts? point data? terrain?, I got a working optimization system that combines similar parts to make them big, and cutting parts destruction.
You could try greedy meshing for the parts, and for destruction, calculate the destruction manually on the original voxel array, then recalculate that regions voxels (remove any necessary) and greedy mesh the results.
While greedy mesh will reduce your part count I would not recommend it as you have to recalculate the hole chunk every time you change 1 voxel on the chunk even Minecraft does not use greedy mesh
I think simple culling should be enough that is where you simple check the surrounding 6 voxels and if none of them are Air then you don’t generate the voxel
another thing you can do is chunks that are far away from the character can be generated at a lower resolution so instead of loading the chunk as 16 * 16 * 256 you can load them as larger cubes maybe something like 8 * 8 * 128 and 4 * 4 * 64 for chunks that are really far away that’s how Roblox’s built in terrain works
each client should be generating there own voxels around there character the server should not be generating the world the server only sends the voxel data to the clients and then the client decides if it should generate or not generate the terrain according to how close they are standing to the chunk
and if you want to save your voxel data into the datastore you will need to try and save as much data into a single datastore key as possible so you don’t hit the datastore limits when trying to save and load the chunks
so when loading the chunk you loop all voxels and each voxel checks its neighbouring voxels and if none of the neighbours are air then the voxel should not be loaded
when you destroy a voxel you check all neighbouring voxels and if any has not loaded you load them
and when you place a voxel you check all neighbouring voxels and check if they have any air touching them and if they have no air then you can unload that voxel