<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Blosc Home Page  (Posts about bytedelta)</title><link>https://blosc.org/</link><description></description><atom:link href="https://blosc.org/categories/bytedelta.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2026 &lt;a href="mailto:blosc@blosc.org"&gt;The Blosc Developers&lt;/a&gt; </copyright><lastBuildDate>Sun, 19 Jul 2026 11:09:13 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Bytedelta: Enhance Your Compression Toolset</title><link>https://blosc.org/posts/bytedelta-enhance-compression-toolset/</link><dc:creator>Francesc Alted</dc:creator><description>&lt;p&gt;&lt;cite&gt;Bytedelta&lt;/cite&gt; is a new filter that calculates the difference between bytes
in a data stream.  Combined with the shuffle filter, it can improve compression
for some datasets.  Bytedelta is based on &lt;a class="reference external" href="https://aras-p.info/blog/2023/03/01/Float-Compression-7-More-Filtering-Optimization/"&gt;initial work by Aras Pranckevičius&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: We have a brief introduction to bytedelta in the 3rd section of
&lt;a class="reference external" href="https://www.blosc.org/docs/Blosc2-WP7-LEAPS-Innov-2023.pdf"&gt;this presentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The basic concept is simple: after applying the shuffle filter,&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/shuffle-filter.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/shuffle-filter.png" style="width: 75%;"&gt;
&lt;p&gt;then compute the difference for each byte in the byte streams (also called splits in Blosc terminology):&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/bytedelta-filter.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/bytedelta-filter.png" style="width: 75%;"&gt;
&lt;p&gt;The key insight enabling the bytedelta algorithm lies in its implementation, especially the use of SIMD on Intel/AMD and ARM NEON CPUs, making the filter overhead minimal.&lt;/p&gt;
&lt;p&gt;Although Aras's original code implemented shuffle and bytedelta together, it was limited to a specific item size (4 bytes). Making it more general would require significant effort.  Instead, for Blosc2 we built on the existing shuffle filter and created a new one that just does bytedelta. When we insert both in the &lt;a class="reference external" href="https://www.blosc.org/docs/Blosc2-Intro-PyData-Global-2021.pdf"&gt;Blosc2 filter pipeline&lt;/a&gt; (it supports up to 6 chained filters), it leads to a completely general filter that works for any type size supported by existing shuffle filter.&lt;/p&gt;
&lt;p&gt;With that said, the &lt;a class="reference external" href="https://github.com/Blosc/c-blosc2/pull/456"&gt;implementation of the bytedelta filter&lt;/a&gt; has been a breeze thanks to the &lt;a class="reference external" href="https://www.blosc.org/posts/registering-plugins/"&gt;plugin support in C-Blosc2&lt;/a&gt;. You can also implement your own filters and codecs on your own, or if you are too busy, &lt;a class="reference external" href="mailto:contact@blosc.org"&gt;we will be happy to assist you&lt;/a&gt;.&lt;/p&gt;
&lt;section id="compressing-era5-datasets"&gt;
&lt;h2&gt;Compressing ERA5 datasets&lt;/h2&gt;
&lt;p&gt;The best approach to evaluate a new filter is to apply it to real data. For this, we will use some of the &lt;a class="reference external" href="https://www.ecmwf.int/en/forecasts/datasets/reanalysis-datasets/era5"&gt;ERA5 datasets&lt;/a&gt;, representing different measurements and labeled as "wind", "snow", "flux", "pressure" and "precip". They all contain floating point data (float32) and we will use a full month of each one, accounting for 2.8 GB for each dataset.&lt;/p&gt;
&lt;p&gt;The diverse datasets exhibit rather dissimilar complexity, which proves advantageous for testing diverse compression scenarios. For instance, the wind dataset appears as follows:&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/wind-colormap.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/wind-colormap.png" style="width: 100%;"&gt;
&lt;p&gt;The image shows the intricate network of winds across the globe on October 1, 1987. The South American continent is visible on the right side of the map.&lt;/p&gt;
&lt;p&gt;Another example is the snow dataset:&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/snow-colormap.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/snow-colormap.png" style="width: 100%;"&gt;
&lt;p&gt;This time the image is quite flat. Here one can spot Antarctica, Greenland, North America and of course, Siberia, which was pretty full of snow by 1987-10-01 23:00:00 already.&lt;/p&gt;
&lt;p&gt;Let's see how the new bytedelta filter performs when compressing these datasets.  All the plots below have been made using a box with an Intel i13900k processor, 32 GB of RAM and using Clear Linux.&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/cratio-vs-filter.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/cratio-vs-filter.png" style="width: 100%;"&gt;
&lt;p&gt;In the box plot above, we summarized the compression ratios for all datasets using different codecs (BLOSCLZ, LZ4, LZ4HC and ZSTD). The main takeaway is that using bytedelta yields the best median compression ratio: bytedelta achieves a median of 5.86x, compared to 5.62x for bitshuffle, 5.1x for shuffle, and 3.86x for codecs without filters.  Overall, bytedelta seems to improve compression ratios here, which is good news.&lt;/p&gt;
&lt;p&gt;While the compression ratio is a useful metric for evaluating the new bytedelta filter, there is more to consider. For instance, does the filter work better on some data sets than others? How does it impact the performance of different codecs? If you're interested in learning more, read on.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="effects-on-various-datasets"&gt;
&lt;h2&gt;Effects on various datasets&lt;/h2&gt;
&lt;p&gt;Let's see how different filters behave on various datasets:&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/cratio-vs-dset.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/cratio-vs-dset.png" style="width: 100%;"&gt;
&lt;p&gt;Here we see that, for datasets that compress easily (precip, snow), the behavior is quite different from those that are less compressible. For precip, bytedelta actually worsens results, whereas for snow, it slightly improves them. For less compressible datasets, the trend is more apparent, as can be seen in this zoomed in image:&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/cratio-vs-dset-zoom.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/cratio-vs-dset-zoom.png" style="width: 100%;"&gt;
&lt;p&gt;In these cases, bytedelta clearly provides a better compression ratio, most specifically with the pressure dataset, where compression ratio by using bytedelta has increased by 25% compared to the second best, bitshuffle (5.0x vs 4.0x, using ZSTD clevel 9). Overall, only one dataset (precip) shows an actual decrease. This is good news for bytedelta indeed.&lt;/p&gt;
&lt;p&gt;Furthermore, Blosc2 supports another compression parameter for splitting the compressed streams into bytes with the same significance. Normally, this leads to better speed but less compression ratio, so this is automatically activated for faster codecs, whereas it is disabled for slower ones. However, it turns out that, when we activate splitting for all the codecs, we find a welcome surprise: bytedelta enables ZSTD to find significantly better compression paths, resulting in higher compression ratios.&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/cratio-vs-dset-always-split-zoom.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/cratio-vs-dset-always-split-zoom.png" style="width: 100%;"&gt;
&lt;p&gt;As can be seen, in general ZSTD + bytedelta can compress these datasets better. For the pressure dataset in particular, it goes up to 5.7x, 37% more than the second best, bitshuffle (5.7x vs 4.1x, using ZSTD clevel 9).  Note also that this new highest is 14% more than without splitting (the default).&lt;/p&gt;
&lt;p&gt;This shows that when compressing, you cannot just trust your intuition for setting compression parameters - there is no substitute for experimentation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="effects-on-different-codecs"&gt;
&lt;h2&gt;Effects on different codecs&lt;/h2&gt;
&lt;p&gt;Now, let's see how bytedelta affects performance for different codecs and compression levels.&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/cratio-vs-codec.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/cratio-vs-codec.png" style="width: 100%;"&gt;
&lt;p&gt;Interestingly, on average bytedelta proves most useful for ZSTD and higher compression levels of ZLIB (Blosc2 comes with &lt;a class="reference external" href="https://github.com/zlib-ng/zlib-ng"&gt;ZLIB-NG&lt;/a&gt;). On the other hand, the fastest codecs (LZ4, BLOSCLZ) seem to benefit more from bitshuffle instead.&lt;/p&gt;
&lt;p&gt;Regarding compression speed, in general we can see that bytedelta has little effect on performance:&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/cspeed-vs-codec.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/cspeed-vs-codec.png" style="width: 100%;"&gt;
&lt;p&gt;As we can see, compression algorithms like BLOSCLZ, LZ4 and ZSTD can achieve extremely high speeds. LZ4 reaches and surpasses speeds of 30 GB/s, even when using bytedelta. BLOSCLZ and ZSTD can also exceed 20 GB/s, which is quite impressive.&lt;/p&gt;
&lt;p&gt;Let’s see the compression speed grouped by compression levels:&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/cspeed-vs-codec-clevel.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/cspeed-vs-codec-clevel.png" style="width: 100%;"&gt;
&lt;p&gt;Here one can see that, to achieve the highest compression rates when combined with shuffle and bytedelta, the codecs require significant CPU resources; this is especially noticeable in the zoomed-in view:&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/cspeed-vs-codec-clevel-zoom.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/cspeed-vs-codec-clevel-zoom.png" style="width: 100%;"&gt;
&lt;p&gt;where capable compressors like ZSTD do require up to 2x more time to compress when using bytedelta, especially for high compression levels (6 and 9).&lt;/p&gt;
&lt;p&gt;Now, let us examine decompression speeds:&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/dspeed-vs-codec.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/dspeed-vs-codec.png" style="width: 100%;"&gt;
&lt;p&gt;In general, decompression is faster than compression. BLOSCLZ, LZ4 and LZ4HC can achieve over 100 GB/s. BLOSCLZ reaches nearly 180 GB/s using no filters on the snow dataset (lowest complexity).&lt;/p&gt;
&lt;p&gt;Let’s see the decompression speed grouped by compression levels:&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/dspeed-vs-codec-clevel.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/dspeed-vs-codec-clevel.png" style="width: 100%;"&gt;
&lt;p&gt;The bytedelta filter noticeably reduces speed for most codecs, up to 20% or more.  ZSTD performance is less impacted.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="achieving-a-balance-between-compression-ratio-and-speed"&gt;
&lt;h2&gt;Achieving a balance between compression ratio and speed&lt;/h2&gt;
&lt;p&gt;Often, you want to achieve a good balance of compression and speed, rather than extreme values of either. We will conclude by showing plots depicting a combination of both metrics and how bytedelta influences them.&lt;/p&gt;
&lt;p&gt;Let's first represent the compression ratio versus compression speed:&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/cratio-vs-cspeed.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/cratio-vs-cspeed.png" style="width: 100%;"&gt;
&lt;p&gt;As we can see, the shuffle filter is typically found on the &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Pareto_front"&gt;Pareto frontier&lt;/a&gt; (in this case, the point furthest to the right and top). Bytedelta comes next.  In contrast, not using a filter at all is on the opposite side.  This is typically the case for most real-world numerical datasets.&lt;/p&gt;
&lt;p&gt;Let's now group filters and datasets and calculate the mean values of combining
(in this case, multiplying) the compression ratio and compression speed for all codecs.&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/cspeed-vs-filter.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/cspeed-vs-filter.png" style="width: 100%;"&gt;
&lt;p&gt;As can be seen, bytedelta works best with the wind dataset (which is quite complex), while bitshuffle does a good job in general for the others. The shuffle filter wins on the snow dataset (low complexity).&lt;/p&gt;
&lt;p&gt;If we group by compression level:&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/cratio_x_cspeed-vs-codec-clevel.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/cratio_x_cspeed-vs-codec-clevel.png" style="width: 100%;"&gt;
&lt;p&gt;We see that bytedelta works well with LZ4 here, and also with ZSTD at the lowest compression level (1).&lt;/p&gt;
&lt;p&gt;Let's revise the compression ratio versus decompression speed comparison:&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/cratio-vs-dspeed.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/cratio-vs-dspeed.png" style="width: 100%;"&gt;
&lt;p&gt;Let's group together the datasets and calculate the mean for all codecs:&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/cratio_x_dspeed-vs-filter-dset.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/cratio_x_dspeed-vs-filter-dset.png" style="width: 100%;"&gt;
&lt;p&gt;In this case, shuffle generally prevails, with bitshuffle also doing reasonably well, winning on precip and pressure datasets.&lt;/p&gt;
&lt;p&gt;Also, let’s group the data by compression level:&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/cratio_x_dspeed-vs-codec-clevel.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/cratio_x_dspeed-vs-codec-clevel.png" style="width: 100%;"&gt;
&lt;p&gt;We find that bytedelta compression does not outperform shuffle compression in any scenario. This is unsurprising since decompression is typically fast, and bytedelta's extra processing can decrease performance more easily. We also see that LZ4HC (clevel 6 and 9) + shuffle strikes the best balance in this scenario.&lt;/p&gt;
&lt;p&gt;Finally, let's consider the balance between compression ratio, compression speed, and decompression speed:&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/cratio_x_cspeed_dspeed-vs-dset.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/cratio_x_cspeed_dspeed-vs-dset.png" style="width: 100%;"&gt;
&lt;p&gt;Here the winners are shuffle and bitshuffle, depending on the data set, but bytedelta never wins.&lt;/p&gt;
&lt;p&gt;If we group by compression levels:&lt;/p&gt;
&lt;img alt="/images/bytedelta-enhance-compression-toolset/cratio_x_cspeed_dspeed-vs-codec-clevel.png" class="align-center" src="https://blosc.org/images/bytedelta-enhance-compression-toolset/cratio_x_cspeed_dspeed-vs-codec-clevel.png" style="width: 100%;"&gt;
&lt;p&gt;Overall, we see LZ4 as the clear winner at any level, especially when combined with shuffle. On the other hand, bytedelta did not win in any scenario here.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="benchmarks-for-other-computers"&gt;
&lt;h2&gt;Benchmarks for other computers&lt;/h2&gt;
&lt;p&gt;We have run the benchmarks presented here in an assortment of different boxes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://www.blosc.org/docs/era5-pds/plot_transcode_data-m1.html"&gt;MacBook Air with M1 processor and 8 GB RAM. MacOSX 13.1.&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://www.blosc.org/docs/era5-pds/plot_transcode_data-m1.html"&gt;AMD Ryzen 9 5950X processor and 32 GB RAM. Debian 22.04.&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://www.blosc.org/docs/era5-pds/plot_transcode_data-i10k.html"&gt;Intel i9-10940X processor and 64 GB RAM. Debian 22.04.&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://www.blosc.org/docs/era5-pds/plot_transcode_data-i13k.html"&gt;Intel i9-13900K processor and 32 GB RAM. Clear Linux.&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also, find here a couple of runs using the i9-13900K box above, but with the always split and never split settings:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://www.blosc.org/docs/era5-pds/plot_transcode_data-i13k-always-split.html"&gt;Intel i9-13900K. Always Split.&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://www.blosc.org/docs/era5-pds/plot_transcode_data-i13k-never-split.html"&gt;Intel i9-13900K. Never Split.&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Reproducing the benchmarks is straightforward. First, &lt;a class="reference external" href="https://github.com/Blosc/python-blosc2/blob/main/bench/ndarray/download_data.py"&gt;download the data&lt;/a&gt;; the downloaded files will be in the new &lt;cite&gt;era5_pds/&lt;/cite&gt; directory.  Then perform &lt;a class="reference external" href="https://github.com/Blosc/python-blosc2/blob/main/bench/ndarray/transcode_data.py"&gt;the series of benchmarks&lt;/a&gt;; this is takes time, so grab coffee and wait 30 min (fast workstations) to 6 hours (slow laptops).  Finally, run the &lt;a class="reference external" href="https://github.com/Blosc/python-blosc2/blob/main/bench/ndarray/plot_transcode_data.ipynb"&gt;plotting Jupyter notebook&lt;/a&gt; to explore your results.  If you wish to share your results with the &lt;a class="reference external" href="mailto:contact@blosc.org"&gt;Blosc development team&lt;/a&gt;, we will appreciate hearing from you!&lt;/p&gt;
&lt;/section&gt;
&lt;section id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Bytedelta can achieve higher compression ratios in most datasets, specially in combination with capable codecs like ZSTD, with a maximum gain of 37% (pressure) over other codecs; only in one case (precip) compression ratio decreases. By compressing data more efficiently, bytedelta can reduce file sizes even more, accelerating transfer and storage.&lt;/p&gt;
&lt;p&gt;On the other hand, while bytedelta excels at achieving high compression ratios, this requires more computing power. We have found that for striking a good balance between high compression and fast compression/decompression, other filters, particularly shuffle, are superior overall.&lt;/p&gt;
&lt;p&gt;We've learned that no single codec/filter combination is best for all datasets:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;ZSTD (clevel 9) + bytedelta can get better absolute compression ratio for most of the datasets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LZ4 + shuffle is well-balanced for all metrics (compression ratio, speed, decompression speed).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LZ4 (clevel 6) and ZSTD (clevel 1) + shuffle strike a good balance of compression ratio and speed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LZ4HC (clevel 6 and 9) + shuffle balances well compression ratio and decompression speed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;BLOSCLZ without filters achieves best decompression speed (at least in one instance).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In summary, the optimal choice depends on your priorities.&lt;/p&gt;
&lt;p&gt;As a final note, the Blosc development team is working on BTune, a new deep learning tuner for Blosc2. BTune can be trained to automatically recognize different kinds of datasets and choose the optimal codec and filters to achieve the best balance, based on the user's needs. This would create a much more intelligent compressor that can adapt itself to your data faster, without requiring time-consuming manual tuning. If interested, &lt;a class="reference external" href="mailto:contact@blosc.org"&gt;contact us&lt;/a&gt;; we are looking for beta testers!&lt;/p&gt;
&lt;/section&gt;</description><category>Blosc2</category><category>bytedelta</category><category>filter</category><guid>https://blosc.org/posts/bytedelta-enhance-compression-toolset/</guid><pubDate>Fri, 24 Mar 2023 11:32:20 GMT</pubDate></item></channel></rss>