Ostrovsky's hierarchical ORAM improves on Goldreich's "square root" ORAM by storing data in a hierarchy of buffers of different sizes and shuffling buffers with frequency inversely proportional to their size. This minimizes the amortized cost of random shuffling. To read or write, it scans buckets in each level using pseudorandom functions until finding the data, then writes it to the top level and shuffles data between levels using oblivious sorting and scanning to maintain an invariant of at most 1 slot per bucket on average in each level. This achieves poly-logarithmic overhead, constant client storage, and hides access patterns.