In the long run, I found that the look ups were cheaper than the memory consumption. Overlapping borders buys more problems than it solves and costs a lot (calculate the memory costs yourself… and then the costs of retrieving up to 8 blocks to edit one conjoined corner [if you do it in 3D]). If it’s really an issue, perhaps you can cache some bits in with your cell data to show which sides are solid and avoid a lookup during mesh creation. 6 bits per cell is enough if you have them to spare.
Well, it my case I don’t have problems editing conjoined corners - for how often that happens, which isn’t very often, because I’m not performing mass edits of blocks except during terraforming, in which case the leading edge is not yet terraformed and doesn’t need to be touched, and the trailing edge is already terraformed so doesn’t need to be touched again - so there are no lookups during terraforming at all - but voxels that preclude others being beside them are enforced.
Determining how voxels are rendered requires the amount of data I use in overlaps - for example, when a voxel faces a liquid water voxel it’s tinted blue - or when a voxel faces a transparent voxel (or even an air voxel of type 0) which is at a high temperature, it’s a little more yellow to indicate it’s hot. When a liquid voxel is beside another liquid voxel with a different compression, they average the height of the top side they share to produce a smooth surface.
The overlaps do contain less data than the actual block containing the voxel - but the absence of the need for lookups, in my case, allows for lots of nice interactions between neighbouring voxels during coloring, meshing, liquid simulations, etc, without lookups.
Perhaps your cache is more performant though, which would change things - mind if I ask what you’re using? : )