What is it?
Building automatic storage systems in Minecraft has been a challenge that has motivated players since as early as 2012. Progress has been made in part by new additions to the game, but also mainly by advances in the theoretical method of organizing random items sent by the player.
Storage Tech grew from a small community of about 100 players (2019) to now over 32,000 (2024), each racing to design the best automatic sorting systems possible. This article outlines my contributions to storage tech from about 2019-2023.

Kreb's Storage System 2023
Outline of the challenge
A player in Minecraft will likely accumulate a large amount of items during his/her journey, where items come in a variety of types. One type could be "wood" or "red concrete". Players can also obtain boxes that hold other items, where each box is constrained by both the number of items and number of types of items it can hold. A box cannot be placed in another box. Ideally, we would like to be able to dump all of these items, or boxes of items, into some kind system that automatically sorts, stores, and presents the items to the player such that they can be retrieved on a later occasion.
​
We would also like to do this in a way that satisfies a number of conditions. Some of the more important ones are listed here:
- Speed
- Lag (Should not slow the game down, client-side or server-side, whilst running or idle - there are several ways to achieve this)
- Moveable Block Compatibility (Some blocks cannot moved like chests. If one day this is changed such that chests can be moved, the system should not try to push a non-moveable block which would otherwise break the system for future-compatibility's sake).
- Backwards compatible to a reasonably far back version of Minecraft
- No togglestates (The system should not depend on states that can be toggled on or off. If the system is loaded or unloaded during runtime, these can can get stuck in the wrong state, and are bad design practice).
- User friendly
- Should be able to sort every item, and account for every edge case
​
This article focuses mainly on the theoretical techniques to improve the speed of the system, and less on the specific engineering mechanics of minecraft redstone. However, it should be noted that minecraft wiring is an entirely separate field that is intimately involved with the improvement and optimisation of all the designs mentioned in this article.
How to do it?
Items in Minecraft stack together if they are of the same type. Most items stack to 64, but some stack to a maximum of 16, or do not stack at all. A chest, or box, holds 27 slots. Each slot can hold only one type, and up to 64/16 etc of that type. An example of a non-stackable item is a box.
We want to sort items based on their type. The simple filter circuit is capable of separating one type of items from the rest. The filter uses a hopper, which is a container block that has 5 slots, and takes in items that are dropped above it. The hopper has 1 item of the sorted type in slot 1, and then 4 other extremely rare stackable items* in the 4 other slots. This means only items of the sorted type can enter (or the rare items), since they are the only items that can stack with the sorted type. The circuit detects the incoming item, and releases exactly one of them into the output chest, such that it returns to its original state. We can place many of these 1-wide circuits side by side, each one taking a different item, and can pass the items over using a water channel.
​
*Rare items are used to ensure its very unlikely it fails and sorts an unintended item. In fact, due to the order in which hoppers extract items, if this case happens, the filter permenantly breaks. We can make items astronomically rare by renaming them to a random string (although this is still considered problematic). Unstackable items cannot be used as it would overflow the signal such that it spills over to adjacent slices. There is a solution to this problem we employ later on.
We can do much, much better
Hoppers operate at a fixed speed of 1 item every 8 game ticks (0.4 seconds if the game isn't lagging, this is called 1x speed). An alternative 1-wide design approach is also available that sorts at 2x speed which exploits the fact that a hopper can take and send two different items at the same time. However, this requires us to batch our input items to avoid overflow. I made a design in 2020 that does exactly this.
​
We can also improve our circuit by attaching a box loader underneath each filter. This simple circuit is also one wide, and simply fills an empty box with incoming items. When the box fills, it breaks the full box of one item type and leaves it for the player. This conveniently boxes up our sorted items. The details of this class of circuit are beyond the scope of this article.
​

A simple filter

1x filter array
My very outdated item batcher from 2020

A modern 1x box loader

mixed box

partial box

Boxes
The top image shows a mixed box. Its contents are completely randomised, and we should expect it to contain absolutely anything. The technique so far has been to unload boxes of this kind, filter each item out, and load them to eventually reach full boxes.
​
One brilliant circuit that was devised in 2018 is called a splitter. A splitter takes a mixed box, and is able to separate the items such that it outputs partial boxes as shown in the diagram. It does this by receiving one random item from the box, then doing nothing, and then it behaves like a normal filter of whatever item it received. It sends these items into a box until the mixed box runs out of that type (if no item is sorted after 8gt, the initial item is released), and then repeats this for each item. The result is a number of partial boxes, of only one type, as shown on the left for each type.
​
This approach is great because each splitter works at ~1x speed (minus the short delay when switching item type), and so we can parallelise the operation. We just need to stack say 8 splitters side by side, and we can convert mixed boxes to partials in parallel. The speed is constrained now by the number of splitters we build, and not the constant speed of the hopper.
​
This however raises a challenge. How do we convert partials to full boxes?​
full box
​One technique is to "merge" partials of the same type together. We simply take the 2 partials, check which one is larger, and unload the smaller into the larger. The main problem is that it is hard to store the final odd box out. Previously, we had each partial trapped in a box loader, but now they are all randomly collected together.
We would need to have some kind of "temp" storage that could hold one partial for each possible item that exists in Minecraft. Given that there are over 2000 items in Minecraft, this becomes extremely tedious and spatially big. We would also need to retrieve particular boxes that match new pairs that come in with a new batch. In other words, this would mean sampling an item from each partial, and then sorting that item to find the partial in temp that corresponds with it. This means we are back to the bottleneck of filter based sorting, and has added a lot of complexity. We can solve this however, by using a completely different paradigm called "encoding" (this is popularly known as "binary storage") which when done correctly is ultimately the best method. But we will discuss this later.

A modern splitter (2-wide) This particular design uses non-stackables as filter items.
The first splitter by pallapalla
Parallel Unloading
To avoid the complexity of encoding, we can still make use of the efficiency of splitters by using parallel unloading. This involves sorting partials by type, and then unloading partials of different type at the same time. The output runs over normal filter-boxloader circuits as before. For example, if we had partials of wood, partials of concrete, and partials of dirt, we would unload wood, concrete and dirt, each at 1x speed, at the same time. That way, although the total volume of our unloading is 3x speed, we know our 1x filters will not overflow because the items will all go to different filters, each at 1x. This wasn't possible before, because if we tried unloading 3 mixed boxes in parallel, then if both started unloading wood, for instance, this would result in an overflow. This causes a backlog that could potentially grow to infinity.
​
We first need to sort the partial boxes. We do this by, as mentioned earlier, sampling one item from a box, and then running the remaining box and the item in two separate channels at once. They reach a set of "variable box sorters" (svars). Like the splitters, these first accept one pair (item and box), and use this item to configure the hopper. This hopper now only accepts items of this type. The box is lodged in the svar. Now, should a new pair of that type come through, it gets filtered, and then reunited with its box, and then that box gets unloaded. We can stack these next to each other as before to retain parallelism.
​
A cyclical method is used where svars are unmapped from their item once the entire batch has gone through, or only overflow remains. Overflow occurs when we have more types than svars.

Optic's set-based unloading array
My double pass array
Double Pass
This approach can be significantly sped up using a technique I developed called "double pass" (above). In double pass, we do not need to batch our items, and instead we use a continuous input of partials. In the approach I used, we sent one box from cycle A, and then another from B, then A, then B and so on. We lock the input of each svar, even if the items match, in A, then unlock them for B. If an svar gets mapped, it that svar only becomes unlocked for B and A. The result of this is that we can safely unmap slices at any point we like, because we can guarantee that any box from B that has a chance of mapping has already passed over once in A. This means it wont map a slice to an item that is already mapped further down the line (which was the prior bottleneck). I made a more detailed video of this that can be found above.
​
This approach sparked immense development, from something called "parvar", to eventually "FIT" (first item type). I am not knowledgeable enough about these techniques to write about them and they are beyond the scope of this article, but it is generally accepted that using either cyclical (set-based) or double pass is good enough for most people's needs. Nonetheless, I found it fun to push the limits of sorting in this way, and I developed two large-scale sorting systems using this method (2021). They involve lots of other interesting things like a working 7-segment display and counter that records the fill level of the storage, and were themselves huge collaborative undertakings.